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
相关产品推荐
相关产品推荐

