Как найти и нажать на элемент кнопки, который содержит несколько классов - PullRequest
2 голосов
/ 04 мая 2019

Использование python + селеновый хромедривер. На экране входа в систему и при попытке нажать кнопку входа в систему, однако, я не могу определить элемент правильно.

Код пробной версии:

login = driver.find_element_by_css_selector('tv-button.tv-button--no-border-radius.tv-button--size_large.tv-button--primary_ghost.tv-button--loader')
click(login)

HTML:

<button type="submit" class="tv-button tv-button--no-border-radius tv-button--size_large tv-button--primary_ghost tv-button--loader">
<span class="tv-button__text">Log In</span>
<span class="tv-button__loader"><span class="tv-button__loader-item"></span><span class="tv-button__loader-item"></span><span class="tv-button__loader-item"></span></span></button>

Ответы [ 5 ]

1 голос
/ 04 мая 2019

Нет сомнений в том, что мы всегда должны выбирать css selector вместо xpath.

Но селектор CSS, который вы используете: .tv-button.tv-button--no-border-radius.tv-button--size_large.tv-button--primary_ghost.tv-button--loader выглядит очень нестабильно.

Для просто кнопки входа, вы можете использовать:

xpath: //span[contains(text(),'Log In')]/parent::button

Причина, по которой вам следует избегать css-селектора, заключается в том, что (в данном случае) этот css-селектор является комбинацией имени класса, поэтому в случае изменения имени класса вам придется изменить локатор.

Вероятность изменения имени класса в этом случае весьма вероятна. Потому что это сделано из 5 классов.

Надеюсь, это поможет.

1 голос
/ 04 мая 2019

Кажется, вы вначале пропускаете ., поэтому селектор Css будет искать тег tv-button вместо класса. Попробуйте это:

login = driver.find_element_by_css_selector('.tv-button.tv-button--no-border-radius.tv-button--size_large.tv-button--primary_ghost.tv-button--loader')
click(login)
0 голосов
/ 04 мая 2019

Элемент является динамическим элементом, поэтому для определения местоположения и щелчка по элементу, который необходимо вызвать WebDriverWait для element_to_be_clickable(), можно использовать любое из следующих решений:

  • Использование CSS_SELECTOR:

    WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "button.tv-button--no-border-radius.tv-button--loader>span.tv-button__text"))).click()
    
  • Использование XPATH:

    WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//button[@class='tv-button tv-button--no-border-radius tv-button--size_large tv-button--primary_ghost tv-button--loader']/span[@class='tv-button__text' and text()='Log In']"))).click()
    
  • Примечание : необходимо добавить следующий импорт:

    from selenium.webdriver.support.ui import WebDriverWait
    from selenium.webdriver.common.by import By
    from selenium.webdriver.support import expected_conditions as EC
    
0 голосов
/ 04 мая 2019

Попробуйте Induce WebDriverWait, чтобы определить элемент, а затем нажмите на него.

from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By

element=WebDriverWait(driver,30).until(EC.element_to_be_clickable((By.CSS_SELECTOR,'button.tv-button span')))
print(element.text)
element.click()
0 голосов
/ 04 мая 2019

Я бы попробовал более короткий селектор класса

driver.find_element_by_css_selector('.tv-button').click()
...