为何已忽略StaleElementReferenceException仍报错?如何等待元素可点击避免异常?
明明在WebDriverWait里忽略了StaleElementReferenceException,为啥还会抛出?怎么彻底避免?
问题描述
我已经在代码里设置WebDriverWait忽略StaleElementReferenceException,但这个异常还是会被抛出。现在代码重试几次后能成功,但想知道怎么实现等待元素可点击后再执行操作,彻底避免这类异常?
原代码如下:
import sys from selenium.common.exceptions import StaleElementReferenceException while True: try: WebDriverWait(driver, 10, ignored_exceptions=[StaleElementReferenceException]).until(ec.element_to_be_clickable((By.XPATH,"//button[contains(text(), 'Performance Summary')]"))).click() break except Exception as e: exc_type, exc_obj, exc_tb = sys.exc_info() print(e, exc_type, exc_tb.tb_lineno) print('Retrying...')
问题原因
WebDriverWait的ignored_exceptions参数只负责忽略等待until条件满足过程中抛出的指定异常,但你代码里的click()操作是在等待结束后执行的——这时候如果元素已经因为页面刷新、DOM重构变成了陈旧引用,click()还是会触发StaleElementReferenceException,这个异常不在WebDriverWait的忽略范围内,所以会被外层的except捕获到。
彻底解决的方案
核心思路是:每次操作都确保元素是最新的DOM引用,并且把点击操作也纳入异常重试的覆盖范围。
方案1:把点击逻辑封装进等待条件
用lambda表达式把点击操作整合进等待逻辑,让WebDriverWait的异常忽略规则覆盖整个操作流程:
import sys from selenium.common.exceptions import StaleElementReferenceException from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.common.by import By import selenium.webdriver.support.expected_conditions as ec while True: try: WebDriverWait(driver, 10, ignored_exceptions=[StaleElementReferenceException]).until( lambda d: d.find_element(By.XPATH, "//button[contains(text(), 'Performance Summary')]").click() ) break except Exception as e: exc_type, exc_obj, exc_tb = sys.exc_info() print(e, exc_type, exc_tb.tb_lineno) print('Retrying...')
方案2:每次重试都重新定位元素
在循环内每次重新等待并获取元素,避免复用之前的陈旧引用,确保点击操作基于最新的DOM节点:
import sys from selenium.common.exceptions import StaleElementReferenceException from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.common.by import By import selenium.webdriver.support.expected_conditions as ec while True: try: # 每次循环都重新等待元素可点击,获取最新的元素引用 btn = WebDriverWait(driver, 10, ignored_exceptions=[StaleElementReferenceException]).until( ec.element_to_be_clickable((By.XPATH,"//button[contains(text(), 'Performance Summary')]")) ) btn.click() break except (StaleElementReferenceException, Exception) as e: exc_type, exc_obj, exc_tb = sys.exc_info() print(e, exc_type, exc_tb.tb_lineno) print('Retrying...')
额外说明
- 页面频繁刷新或DOM动态变化时,绝对不要复用之前获取的元素引用,每次操作前重新查找是最稳妥的方式。
- 如果页面加载延迟较高,可以适当调整WebDriverWait的超时时间,或者结合
ec.visibility_of_element_located等条件,先确保元素完全可见再执行操作。
内容的提问来源于stack exchange,提问作者jguy
相关产品推荐
相关产品推荐

