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

Selenium(Python)遍历动态表格遇StaleElementReferenceException问题求助

解决Selenium动态表格遍历的StaleElementReferenceException问题

问题描述

我有一个包含可点击行的动态表格,尝试遍历所有行时,仅能成功点击第一行,随后会触发如下错误:
StaleElementReferenceException: stale element reference: element is not attached to the page document

可运行代码(仅遍历1行)

# Retrieve table and rows
table_id = driver.find_element(By.CLASS_NAME, "ember-table-overflow")
rows = table_id.find_elements(By.TAG_NAME, "tr")
back_btn = driver.find_element(By.CLASS_NAME,"navigation__links")

# Total number of components
print(len(rows))

comp_list = []
for row in rows[1:2]:
    print(row)
    time.sleep(10)
    row.click()
    soup = BeautifulSoup(driver.page_source,'lxml')
    kind = soup.find_all("div", {"class": "component-view-spec__body"})[0].text
    print(kind)
    LV = soup.find_all("div", {"class": "component-view-spec__body"})[1].text
    comp_data = {
        'Kind': kind,
        'LV': LV,
        }
    comp_list.append(comp_data)
    back_btn.click()

报错代码(遍历2行)

# Total number of components
print(len(rows))

comp_list = []
for row in rows[1:3]:
    print(row)
    time.sleep(10)
    row.click()
    soup = BeautifulSoup(driver.page_source,'lxml')
    kind = soup.find_all("div", {"class": "component-view-spec__body"})[0].text
    print(kind)
    LV = soup.find_all("div", {"class": "component-view-spec__body"})[1].text
    comp_data = {
        'Kind': kind,
        'LV': LV,
        }
    comp_list.append(comp_data)
    back_btn.click()

原因分析

这不是超时问题,核心是DOM元素引用失效:

  • 你一开始获取的rows是当前页面DOM的元素引用集合
  • 点击行进入详情页,再点返回按钮回到列表页时,动态渲染的Ember表格会重新生成DOM结构
  • 之前缓存的rows里的元素引用已经和新DOM中的元素脱节,变成了"过时"的无效引用,再次调用row.click()就会触发异常

解决方案

每次回到列表页后,重新获取表格行的引用,不要复用之前的rows集合。修改后的代码示例:

import time
from selenium.webdriver.common.by import By
from bs4 import BeautifulSoup

comp_list = []
# 先获取总行数(第一次初始化)
table = driver.find_element(By.CLASS_NAME, "ember-table-overflow")
total_rows = len(table.find_elements(By.TAG_NAME, "tr"))

# 遍历第2到第3行(索引1到2)
for i in range(1, 3):
    # 每次循环重新获取表格和目标行,确保引用是最新的
    table = driver.find_element(By.CLASS_NAME, "ember-table-overflow")
    rows = table.find_elements(By.TAG_NAME, "tr")
    target_row = rows[i]
    
    print(target_row)
    target_row.click()
    
    # 解析详情页数据
    soup = BeautifulSoup(driver.page_source, 'lxml')
    spec_bodies = soup.find_all("div", {"class": "component-view-spec__body"})
    comp_data = {
        'Kind': spec_bodies[0].text,
        'LV': spec_bodies[1].text
    }
    comp_list.append(comp_data)
    print(comp_data)
    
    # 返回列表页,重新获取返回按钮避免引用失效
    back_btn = driver.find_element(By.CLASS_NAME, "navigation__links")
    back_btn.click()
    
    # 等待页面渲染完成(建议用显式等待替代time.sleep)
    time.sleep(1)

额外优化建议

  • 把time.sleep()替换为显式等待,比如等待表格元素重新可见,这样更稳定且高效,示例:
    from selenium.webdriver.support.ui import WebDriverWait
    from selenium.webdriver.support import expected_conditions as EC
    
    # 返回后等待表格重新加载完成
    WebDriverWait(driver, 10).until(
        EC.presence_of_element_located((By.CLASS_NAME, "ember-table-overflow"))
    )
    
  • 不要提前缓存back_btn,每次返回前重新获取,避免同样的过时引用问题

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.23 04:27:14