Selenium - 等待元素出现、可见和可交互

123

我有一个使用Selenium (Python) 编写的脚本,可以点击回复按钮,使得class为anonemail 的元素出现。由于class为anonemail的元素出现的时间不确定,因此我不得不使用sleep方法来等待该元素出现。

我想要等到该元素出现后再执行后续操作,而不是使用sleep方法。我听说过wait命令,但我不知道如何使用它们。

这是我目前的代码:

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

任何答案是否涉及等待元素可交互?它可能存在且可点击,但仍未准备好让您向其发送键。 - Jeremy Kahan
请尝试:https://i.stack.imgur.com/XaPtT.png - Ann Zen
anonemail = 匿名 + 邮箱。类名没有命名约定吗? - Peter Mortensen
6个回答

165

根据最佳实践:

  • 如果您的使用情况是验证任何元素的存在,则需要使用WebDriverWait来诱导expected_conditions,并将presence_of_element_located()设置为期望检查页面DOM上是否存在元素。这并不一定意味着该元素可见。因此,有效的代码行将是:

    WebDriverWait(browser, 20).until(EC.presence_of_element_located((By.CSS_SELECTOR, ".reply-button"))).click()
    
  • 如果您的使用情况是提取任何元素的属性,则需要使用WebDriverWait来诱导expected_conditions,并将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来诱导expected_conditions,并将element_to_be_clickable()设置为期望检查元素是否可见且启用,以便您可以单击它。因此,在您的使用情况中,有效的代码行将是:

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

参考资料

您可以在以下链接中找到详细的讨论:


非常感谢!这不会显示元素未找到的错误。但是,即使存在显式等待,它也会立即关闭浏览器窗口。你知道为什么吗? - Esraa Abdelmaksoud

56

在点击回复按钮后,可以像下面这样使用.visibility_of_element_located

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)

以下是导入内容:

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

等待文档


1
感谢您提供了最容易复制粘贴的答案 ;-P - George Pligoropoulos

16

您可以使用等待。在Selenium 等待 中查找更多信息。

在下面的示例中,我们使用 visibility_of_element_located 函数等待 10 秒钟以使元素可见。

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()

9
  • WebDriverWait(driver, 5).until( EC.presence_of_element_located((By.CSS_SELECTOR, ".reply-button"))):

    • 嘿,司机,等待(0-5秒),当你看到.reply-button出现在DOM中时,把这个按钮给我!
      • presence意味着该元素已经存在于DOM中。隐藏的元素也可以。
  • WebDriverWait(driver, 5).until( EC.visibility_of_element_located((By.CSS_SELECTOR, ".reply-button”)))):

    • 嘿,司机,等待(0-5秒),当你看到.reply-button在DOM中是可见的时,把这个按钮给我!
      • visibility意味着该元素在DOM中存在且可见。 隐藏的元素不行
  • WebDriverWait(driver, 5).until( EC.element_to_be_clickable((By.CSS_SELECTOR, ".reply-button”)))):

    • 嘿,司机,等待(0-5秒),当你看到.reply-button在DOM中是可点击的时,把这个按钮给我!
      • clickable意味着该元素在DOM中可见且可点击。 隐藏的元素或不可点击的元素不行

其他可用条件


1
我非常喜欢在SO上找到这种答案:我认为它们可以帮助你学会钓鱼,而不仅仅是给你一条鱼。赞! - PavoDive

8

您可以使用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")

2

我也遇到了类似的问题。我尝试使用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)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接