硒-等待,直到元素出现,可见和可交互

我有一个 Selenium 脚本(Python) ,它单击一个回复按钮以显示类 匿名邮件。课堂上出现一封电子邮件所需的时间各不相同。因此,我必须使用睡眠,直到元素出现。

我想等到类出现,而不是使用睡眠。我听说过等待命令,但我不知道如何使用它们。

这就是我目前所知道的:

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

You can use waits. Check for more information in Selenium waits.

In the example below we are waiting 10 seconds for the element to be visible, using the function 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()

You can use 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()

It waits until element is loaded.

In your case the implementation would be,

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

As per the best practices:

  • If your use case is to validate the presence of any element, you need to induce WebDriverWait setting the expected_conditions as presence_of_element_located() which is the expectation for checking that an element is present on the DOM of a page. This does not necessarily mean that the element is visible. So the effective line of code will be:

      WebDriverWait(browser, 20).until(EC.presence_of_element_located((By.CSS_SELECTOR, ".reply-button"))).click()
    
  • If your use case is to extract any attribute of any element you need to induce WebDriverWait setting the expected_conditions as visibility_of_element_located(locator) which is an expectation for checking that an element is present on the DOM of a page and visible. Visibility means that the element is not only displayed, but it also has a height and width that is greater than 0. So in your use case, effectively the line of code will be:

      email = WebDriverWait(driver, 20).until(EC.visibility_of_element_located((By.CSS_SELECTOR, "element_css"))).get_attribute("value")
    
  • If your use case is to invoke click() on any element you need to induce WebDriverWait setting the expected_conditions as element_to_be_clickable() which is an expectation for checking an element is visible and enabled such that you can click it. So in your use case, effectively the line of code will be:

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

References

You can find a couple of detailed discussion in:

After clicking the Reply button, use .visibility_of_element_located like below:

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


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


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

Following import:

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

Waits documentation

I also had a similar problem to yours. I tried using implicit_wait() and WebDriverWait, but they did not work.

So I solved setting the implicit_wait(10) in the web driver instance and using this snippet to click on the button:

element = driver.find_elements_by_xpath("//button[contains(string(), 'Log In')]")[0]
driver.execute_script("arguments[0].click();", element)
  • WebDriverWait(driver, 5).until( EC.presence_of_element_located((By.CSS_SELECTOR, ".reply-button"))):

    • Hey driver, wait (0-5 seconds), when you see .reply-button is presence, return that button to me!
      • presence is present on the DOM. Hidden element is good enough.
  • WebDriverWait(driver, 5).until( EC.visibility_of_element_located((By.CSS_SELECTOR, ".reply-button”)))):

    • Hey driver, wait (0-5 seconds), when you see .reply-button is visibility, return that button to me!
      • visibility is present and visible on the DOM. Hidden element is not good enough!
  • WebDriverWait(driver, 5).until( EC.element_to_be_clickable((By.CSS_SELECTOR, ".reply-button”)))):

    • Hey driver, wait (0-5 seconds), when you see .reply-button is clickable, return that button to me!
      • clickable is present and visible and clickable on the DOM. Hidden element or non-clickable is not good enough!

Other available conditions