Selenium - 等到元素存在、可见且可交互

Selenium - wait until element is present, visible and interactable

提问人:Benjamin Arvola 提问时间:12/2/2019 最后编辑:Peter MortensenBenjamin Arvola 更新时间:6/1/2023 访问量:209909

问:

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

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

这是我到目前为止所拥有的:

browser.find_element_by_css_selector(".reply-button").click()
sleep(5)
email=browser.find_element_by_css_selector(".anonemail").get_attribute("value")
python selenium-webdriver webdriverwait 预期条件

评论

0赞 Jeremy Kahan 7/21/2021
是否有任何答案涉及等待元素可交互的问题?它可以存在并可单击,但仍然没有准备好向您发送密钥。
0赞 Red 3/23/2022
尝试:i.stack.imgur.com/XaPtT.png
0赞 Peter Mortensen 11/1/2022
匿名电子邮件 = 匿名 + 电子邮件。类名没有命名约定吗?

答:

16赞 daniboy000 12/2/2019 #1

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

在下面的示例中,我们等待 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()
8赞 Mert Köklü 12/2/2019 #2

您可以使用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")
165赞 undetected Selenium 12/2/2019 #3

根据最佳实践:

  • 如果你的用例是验证任何元素的存在,你需要诱导 WebDriverWaitexpected_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(定位器),这是检查元素是否存在于页面的 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()
    

引用

您可以在以下位置找到一些详细的讨论:

评论

0赞 Esraa Abdelmaksoud 3/12/2023
多谢!这不会显示“未找到元素”错误。但是,即使存在显式等待,它也会立即关闭浏览器窗口。你知道为什么吗?
56赞 frianH 12/2/2019 #4

单击“回复”按钮后,如下所示:.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

等待文档

2赞 badr 5/5/2022 #5

我也有和你类似的问题。我尝试使用 和 ,但它们不起作用。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)
9赞 HoangYell 7/23/2022 #6
  • WebDriverWait(driver, 5).until( EC.presence_of_element_located((By.CSS_SELECTOR, ".reply-button"))):

    • 嘿司机,等一下(0-5 秒),当您看到 .reply-button 存在时,将该按钮还给我!
      • 状态存在于 DOM 上。 隐藏元素就足够了。
  • WebDriverWait(driver, 5).until( EC.visibility_of_element_located((By.CSS_SELECTOR, ".reply-button”)))):

    • 嘿司机,等一下(0-5 秒),当您看到 .reply-button可见性时,将该按钮归还给我!
      • 可见性在 DOM 上存在且可见。 隐藏元素不够好!
  • WebDriverWait(driver, 5).until( EC.element_to_be_clickable((By.CSS_SELECTOR, ".reply-button”)))):

    • 嘿司机,等一下(0-5 秒),当您看到 .reply-button 可点击时,将该按钮返回给我!
      • clickable 在 DOM 上存在且可见且可点击。 隐藏元素或不可点击是不够的!

Other available conditions

评论

1赞 PavoDive 4/12/2023
我真的很喜欢在SO中找到这种答案:我认为它们可以帮助你学习钓鱼,而不仅仅是给你一条鱼。荣誉!