You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python Selenium循环遍历列表触发StaleElementReferenceException求助

Selenium StaleElementReferenceException 问题解决方案

错误根源:你提前一次性抓取了所有机构选项元素存入corporaties列表,但每次选中机构、执行下载操作后,页面DOM会发生重绘,之前抓取的元素引用已经和当前DOM节点脱节,所以二次调用时就会抛出该异常。同时你提前存储的下载按钮元素element_to_select也可能存在同样的失效风险。

修复思路

  • 不要提前缓存动态页面的元素对象,改为先缓存所有机构的名称文本,每次循环时重新打开下拉框,根据文本匹配选中对应机构
  • 所有元素查找操作放到每次循环内部执行,避免预存元素失效
  • 每次操作后添加适当的等待逻辑,确保页面元素加载完成后再执行后续操作

修改后的代码示例

from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.action_chains import ActionChains
...
# 初始化配置webdriver的代码保持不变

driver.get("https://opendata-dashboard.cijfersoverwonen.nl/dashboard/opendata-dashboard/beleidswaarde")
wait = WebDriverWait(driver, 30)
action = ActionChains(driver)

# 处理cookie提示(需要的话取消注释)
# wait.until(EC.element_to_be_clickable((By.CLASS_NAME, "cc-compliance"))).click()

# 第一步:先获取所有机构名称的列表,只存文本不存元素
wait.until(EC.element_to_be_clickable((By.ID, "baseGeo"))).click()
# 等待所有option加载完成
corporate_options = wait.until(EC.presence_of_all_elements_located((By.XPATH, "//button[@role='option']")))
# 只提取文本存入列表
corporate_names = [opt.text.strip() for opt in corporate_options if opt.text.strip()]
# 关闭下拉框,准备开始循环
driver.find_element(By.ID, "baseGeo").click()

# 遍历机构名称列表
for name in corporate_names:
    # 每次循环重新打开下拉框
    wait.until(EC.element_to_be_clickable((By.ID, "baseGeo"))).click()
    # 等待当前机构选项可点击,根据文本匹配
    target_opt = wait.until(EC.element_to_be_clickable((By.XPATH, f"//button[@role='option' and text()='{name}']")))
    target_opt.click()

    # 关闭弹窗
    wait.until(EC.element_to_be_clickable((By.CLASS_NAME, "close-button"))).click()

    # 操作下载按钮,每次重新查找避免失效
    download_btn = wait.until(EC.element_to_be_clickable((By.ID, "utilsmenu")))
    action.move_to_element(download_btn).perform()
    download_btn.click()

    # 导出excel
    wait.until(EC.element_to_be_clickable((By.ID, "utils-export-spreadsheet"))).click()

    # 等待导出触发完成,再准备下一次循环
    driver.implicitly_wait(2)

额外注意点

  • 尽量用WebDriverWait配合expected_conditions的显式等待替代固定等待,既稳定又节省时间
  • 如果部分机构名称包含特殊字符,需要对XPath的文本匹配逻辑做对应转义处理
  • 如果下载触发后页面有加载状态,可增加等待加载完成的逻辑,避免影响下一次循环的元素查找

内容的提问来源于stack exchange,提问作者Sukaldi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 08:12:03