Selenium判定页面完成渲染可执行元素查找的规则是什么
Selenium页面加载与元素查找逻辑解析
1. browser.get() 默认的页面加载完成判定标准
browser.get(url) 方法默认会阻塞后续代码执行,直到浏览器触发 window.load 事件。这个事件的触发时机是:页面的初始HTML文档、所有同步引入的CSS、同步JS、图片、字体等静态资源全部加载完成。
注意:这个判定逻辑完全不关心页面内的异步操作,不管是XHR/fetch异步请求、setTimeout/setInterval 触发的延时任务,都不会被get方法等待。
2. 为什么异步渲染的元素有时候依然能被成功定位
你观察到的异步请求渲染的元素也能被找到,通常是两种原因:
- 代码执行到
find_element这一步的时间差,刚好大于异步请求的耗时:比如get方法在load事件触发后才继续执行,而异步请求在load触发前就已经发起、在执行find_element前就已经拿到数据并把元素插入DOM,自然能直接查到。 - 你开启了隐式等待:隐式等待是WebDriver的全局配置,开启后所有
find类方法在首次没找到元素时,会按照固定频率轮询DOM,直到元素出现或者到达超时时间才结束。如果你的隐式等待超时时间设置得比异步渲染的耗时更长,也能顺利找到元素。
3. 元素查找方法的执行规则
不管是find_element_by_css_selector还是find_elements_by_css_selector,本身的执行逻辑都非常直接:
- 未开启隐式等待(默认配置超时为0)时:调用方法时立刻查询当前DOM树,匹配到元素就返回结果,匹配不到时
find_element直接抛出NoSuchElementException,find_elements直接返回空列表。 - 开启隐式等待时:调用方法后会在超时时间内反复查询DOM,直到匹配到目标元素、到达超时时间、驱动连接断开才会返回。
如果你的页面是setTimeout2秒后才插入非核心数据,只要你没设置大于2秒的隐式等待,也没有加显式等待,调用find方法时元素还没插入DOM,就会直接匹配失败。
4. 异步页面的最佳实践
不要依赖默认加载逻辑或者隐式等待来处理异步渲染场景,稳定性极低,更推荐使用显式等待指定等待条件,示例代码如下:
from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.common.by import By # 初始化等待器,最长等待10秒 wait = WebDriverWait(browser, 10) # 等待id为some-data的元素出现在DOM中,超时就抛异常 result = wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, '#some-data')))
内容的提问来源于stack exchange,提问作者nonopolarity
相关产品推荐
相关产品推荐

