Selenium find_elements 仅在 get() 之后经过时间时才有效

Posted

技术标签:

【中文标题】Selenium find_elements 仅在 get() 之后经过时间时才有效【英文标题】:Selenium find_elements only works if time passes since get() 【发布时间】:2022-01-19 17:08:28 【问题描述】:

在 Colab 中同时运行这两行代码会返回 []

wd.get("https://wetransfer.com/")
wd.find_elements(By.CSS_SELECTOR, 'input[type=file]')

但是,运行一个,然后运行另一个会返回预期的结果:

[<selenium.webdriver.remote.webelement.WebElement (session="3cdfb3afbb591862e909cd406b6ac523", element="19fd31e8-710a-4b6e-8284-9a7409f12718")>,
<selenium.webdriver.remote.webelement.WebElement (session="3cdfb3afbb591862e909cd406b6ac523", element="837097d1-5735-4b24-9cb2-9d3ded3a0311")>]

Get 应该是阻塞的,所以不确定这里发生了什么。

【问题讨论】:

导航到一个 url 后,javascript 可能需要一些时间来加载页面上的所有元素。 【参考方案1】:

这就是 Selenium 的基本工作原理。 它只有在完全加载后才能访问 Web 元素。 这就是我们在这里隐式和显式使用等待的原因。 更推荐显式等待。 所以不是

wd.get("https://wetransfer.com/")
wd.find_elements(By.CSS_SELECTOR, 'input[type=file]')

你应该使用这样的东西:

wd.get("https://wetransfer.com/")
wait = WebDriverWait(wd, 20)
wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, "input[type=file]")))
wd.find_elements(By.CSS_SELECTOR, 'input[type=file]')

要使用它,您必须导入这些导入:

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

【讨论】:

这真的很有帮助,谢谢!那么presence_of_element_locatedvisibility_of_all_elements_located 的行为是什么? presence_of 等待元素的存在,而 visibility_of 等待元素的可见性。建议使用visibility_of,因为在页面加载过程中,元素正在页面上构建。如果 Selenium 在它已经存在但仍未完成的情况下过早捕获其上的元素,则它可能不会被单击等。但如果元素已经可见,则在大多数情况下它是可点击的等。 input[type=file] 元素不可见,因此您不能对其使用visibility_of 条件 presence_of_element_located 正在寻找 single 元素的存在并返回单个元素,而 visibility_of_all_elements_located 正在寻找元素的可见性并返回 list 个匹配传递的定位器的元素。你可能认为这个方法总是会返回匹配传递的定位器的所有元素,但实际上它会在驱动程序找到至少一个匹配项时返回一个找到的元素列表。 谢谢,非常详细。那么我可以做些什么来获得最终出现在页面上的这些元素的实际总数吗?【参考方案2】:

您可以使用以下代码作为示例,等待您的网站完全加载并准备好进行操作。

myElem = WebDriverWait(driver, delay).until(EC.element_to_be_clickable((By.CLASS_NAME , 'bs_btn_buchen')))

【讨论】:

【参考方案3】:

在浏览器将'document.readyState' == "complete" 发送到驱动程序后立即调用get(),Colab 会执行下一行代码,因为DOM Tree 完全没有加载,所以找不到任何匹配项。因此,您会看到 Colab 返回 []

要定位 可见 元素,您需要为visibility_of_all_elements_located() 诱导WebDriverWait,您可以使用以下任一Locator Strategies:

使用CSS_SELECTOR

elements = WebDriverWait(driver, 20).until(EC.visibility_of_all_elements_located((By.CSS_SELECTOR, "input[type=file]")))

使用XPATH

elements = WebDriverWait(driver, 20).until(EC.visibility_of_all_elements_located((By.XPATH, "//input[@type=file]")))

注意:您必须添加以下导入:

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

【讨论】:

这真的很有帮助,谢谢!那么presence_of_element_locatedvisibility_of_all_elements_located 的行为是什么?

以上是关于Selenium find_elements 仅在 get() 之后经过时间时才有效的主要内容,如果未能解决你的问题,请参考以下文章

selenium 的 find_element()和find_elements()

Selenium2+python自动化44-元素定位参数化(find_element)

selenium BY定位

Selenium2学习-- 定位一组元素find_elements

即使元素存在,Selenium find_element 也会抛出异常

关于Python selenium,无法使用,find_element求大神指点