Селен - подождите, пока элемент появится, станет видимым и взаимодействующим

У меня есть сценарий селена (python), который нажимает кнопку ответа, чтобы отобразить класс anonemail. Время, необходимое для появления электронного письма класса, варьируется. Из-за этого мне приходится использовать сон, пока не появится элемент. Я хочу дождаться появления класса вместо использования сна. Я слышал о командах ожидания, но не знаю, как их использовать.

Вот что у меня есть на данный момент:

browser.find_element_by_css_selector(".reply-button").click()
sleep(5)
email=browser.find_element_by_css_selector(".anonemail").get_attribute("value")

7 ответов

Согласно передовой практике:

  • Если ваш вариант использования заключается в проверке наличия любого элемента, вам нужно побудить WebDriverWait установить ожидаемые_условия как presence_of_element_located() что является ожиданием проверки того, что элемент присутствует в DOM страницы. Это не обязательно означает, что элемент виден. Итак, эффективная строка кода будет такой:

    WebDriverWait(browser, 20).until(EC.presence_of_element_located((By.CSS_SELECTOR, ".reply-button"))).click()
    
  • Если вы используете для извлечения любого атрибута любого элемента, вам нужно побудить WebDriverWait установить ожидаемые_условия как visibility_of_element_located(locator) это ожидание для проверки того, что элемент присутствует в DOM страницы и виден. Видимость означает, что элемент не только отображается, но также имеет высоту и ширину больше 0. Таким образом, в вашем сценарии использования строка кода будет выглядеть так:

    email = WebDriverWait(driver, 20).until(EC.visibility_of_element_located((By.CSS_SELECTOR, "element_css"))).get_attribute("value")
    
  • Если ваш вариант использования - вызвать click() на любом элементе, который вам нужно, чтобы WebDriverWait установил ожидаемые_условия как element_to_be_clickable() что является ожиданием проверки того, что элемент виден и включен, чтобы вы могли щелкнуть по нему. Таким образом, в вашем сценарии использования строка кода будет выглядеть так:

    WebDriverWait(browser, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, ".reply-button"))).click()
    

Ссылки

Вы можете найти пару подробных обсуждений в:

После щелчка reply кнопка, используйте .visibility_of_element_located как ниже:

browser.find_element_by_css_selector(".reply-button").click()

#wait initialize, in seconds
wait = WebDriverWait(browser, 10)

email = wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, '.anonemail'))).get_attribute("value")
print(email)

После импорта:

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

Ожидает документы

Вы можете использовать ожидания. Проверьте дополнительную информацию по этой ссылке: selenium watis

В приведенном ниже примере мы ждем 10 секунд, пока элемент станет видимым, используя функцию visibility_of_element_located.

driver = webdriver.Firefox()
driver.get("http://somedomain/url_that_delays_loading")
try:
    element = WebDriverWait(driver, 10).until(
        EC.visibility_of_element_located((By.ID, "myDynamicElement"))
    )
finally:
    driver.quit()
  • WebDriverWait(driver, 5).until( EC.presence_of_element_located((By.CSS_SELECTOR, ".reply-button"))):

    • Эй, водитель, подожди (0-5 секунд), когда увидишь присутствие , верни мне эту кнопку!
      • присутствует в DOM. Скрытый элемент достаточно хорош.
  • WebDriverWait(driver, 5).until( EC.visibility_of_element_located((By.CSS_SELECTOR, ".reply-button”)))):

    • Эй, водитель, подожди (0-5 секунд), когда увидишь видимость , верни мне эту кнопку!
      • видимость присутствует и видна в DOM. Скрытый элемент недостаточно хорош!
  • WebDriverWait(driver, 5).until( EC.element_to_be_clickable((By.CSS_SELECTOR, ".reply-button”)))):

    • Эй, водитель, подожди (0-5 секунд), когда увидишь .reply-buttonкликабельно , верните мне эту кнопку!
      • clickable присутствует, виден и доступен для кликов в DOM. Скрытый элемент или некликабельный элемент недостаточно хорош!

Вы можете использовать implicitly_wait

from selenium import webdriver

driver = webdriver.Firefox()
driver.implicitly_wait(15)
driver.get("http://url")
driver.find_element_by_id("id_of_element").click()

Он ждет, пока элемент не загрузится.

В вашем случае реализация будет,

browser.implicitly_wait(10)
browser.find_element_by_css_selector(".reply-button").click()
email=browser.find_element_by_css_selector(".anonemail").get_attribute("value")

У меня также была проблема, похожая на вашу, я пытался использовать implicit_wait()а также WebDriverWaitно они не работали. Поэтому я решил установить implicit_wait(10)в web driverэкземпляр и используя этот фрагмент, чтобы нажать на кнопку:

      element = driver.find_elements_by_xpath("//button[contains(string(), 'Log In')]")[0]
driver.execute_script("arguments[0].click();", element)

Вот что мне понравилось:

      from selenium import webdriver, common

browser = webdriver.Chrome()
browser.get("www.yourwebpage.com")

while True:
    try:
        email = browser.find_element_by_css_selector(".anonemail").get_attribute("value")
        break
    except common.exceptions.NoSuchElementException:
        print("Fail.")

print(email)
Другие вопросы по тегам