Python Selenium中presence_of_element_located始终返回对象的等待异常咨询
异常根因分析
WebDriverWait.until() 的核心运行规则
- 方法接收一个可回调对象,运行时会自动将当前driver实例作为参数传入回调
- 回调返回值判定逻辑:只要返回值为真值(非空对象、非零数字、非False、非空序列等),就立刻终止等待流程并返回该值;仅当回调连续到超时时间仍返回假值,或回调内部抛出可捕获的查找类异常时,才会抛出TimeoutException
代码的实际运行偏差
Selenium内置的EC.presence_of_element_located 本身是一个类,而非可直接执行的元素查找方法:
- 调用
EC.presence_of_element_located(定位器)这个动作本身,仅会在内存中实例化一个等待条件对象,不会立刻执行页面元素查找逻辑,真正的查找动作是在该实例对象被传入driver参数、执行其内部__call__方法时才会触发 - 你嵌套的lambda逻辑相当于:每次轮询时仅生成一个EC类的实例对象就返回,这个内存中的非空对象是标准真值
WebDriverWait.until()拿到这个真值后,会立刻判定等待成功,既不会等满超时时间,也根本不会执行实际的页面元素查找,自然不会因为元素不存在抛出错误
正确的实现方式
不需要额外嵌套lambda,直接将实例化后的EC条件对象传入until() 即可,框架会自动将driver传入该对象的查找逻辑,实现预期的等待效果:
WebDriverWait(driver, 100).until( EC.presence_of_element_located((By.XPATH, '//*[@title="ZZZZZZZZZZZZZZZZZ"]')) )
这种写法下,框架会按固定间隔轮询执行元素查找:元素不存在时会抛出NoSuchElementException,直到超时时间到达后抛出TimeoutException,完全符合设计预期。
补充说明:如果需要自定义等待逻辑,lambda内部必须实际执行元素查找动作(比如
lambda d: d.find_element(By.ID, "xxx")),不能仅生成EC实例就作为返回值,否则就会出现不查找元素直接等待通过的异常。
内容的提问来源于stack exchange,提问作者Edward Garemo
相关产品推荐
相关产品推荐

