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

Python爬虫翻页时StaleElementReferenceException错误修复方案

修复StaleElementReferenceException自动翻页问题

错误原因分析

  • 你遇到的StaleElementReferenceException核心原因是旧元素引用失效:pages是你在某个时刻获取的分页元素集合,当执行翻页操作后,页面DOM会重新渲染,原来的pages里的元素已经脱离当前页面的DOM树,此时访问这些元素的属性(比如page.text)就会触发报错。
  • 加time.sleep只是延迟了执行时间,但没有解决“引用失效”的本质问题——旧元素已经和新页面完全无关了。

具体修复方案

1. 每次翻页后重新获取分页元素集合

不要在函数外复用pages,而是在move_next函数内部,每次执行时都重新定位分页元素,确保拿到的是当前页面的有效元素。

2. 用显式等待替代固定sleep

显式等待(WebDriverWait)会等待元素满足条件后再执行,比固定时间的time.sleep更可靠,也能节省不必要的等待时间。

3. 优化元素定位方式

避免使用绝对XPATH(比如/html/body/div[3]/...),这种定位方式极易因为页面结构变化失效,改用相对定位或者基于元素文本、class的定位。

修改后的代码示例

from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium.common.exceptions import StaleElementReferenceException

def move_next(driver, page_now, last_page):
    # 每次进入函数都重新获取当前页面的分页元素,确保引用有效
    pages = WebDriverWait(driver, 10).until(
        EC.presence_of_all_elements_located((By.CSS_SELECTOR, "span.pagination a"))  # 替换为你实际的分页元素选择器
    )
    
    for page in pages:
        try:
            page_num = page.text.strip()
        except StaleElementReferenceException:
            # 中途元素失效时,重新获取分页集合后重试
            pages = WebDriverWait(driver, 10).until(
                EC.presence_of_all_elements_located((By.CSS_SELECTOR, "span.pagination a"))
            )
            continue
            
        if page_num == last_page:
            print('마지막 페이지')
            return True
        elif page_num == '다음':
            WebDriverWait(driver, 5).until(EC.element_to_be_clickable(page)).send_keys("\n")
            # 等待页面刷新完成
            WebDriverWait(driver, 10).until(EC.staleness_of(page))
            return False
        elif int(page_num) == int(page_now):
            # 用更稳定的定位方式替换绝对XPATH
            next_btn = WebDriverWait(driver, 5).until(
                EC.element_to_be_clickable((By.LINK_TEXT, '다음'))
            )
            next_btn.click()
            WebDriverWait(driver, 10).until(EC.staleness_of(next_btn))
            return False
        elif int(page_num) > int(page_now):
            WebDriverWait(driver, 5).until(EC.element_to_be_clickable(page)).send_keys("\n")
            WebDriverWait(driver, 10).until(EC.staleness_of(page))
            return False

is_done = False
page_now = 1  # 初始化当前页码
last_page = "10"  # 替换为实际最后一页页码

while not is_done:
    is_done = move_next(driver, page_now, last_page)
    page_now += 1  # 更新当前页码

关键改动说明

  • 每次调用move_next时都重新获取pages集合,确保元素引用是当前页面的有效元素。
  • 增加try-except捕获中途可能出现的元素失效问题,重新获取后重试。
  • 使用EC.staleness_of等待旧元素失效,确保页面已完成刷新再进行后续操作。
  • 替换绝对XPATH为更稳定的定位方式(比如By.LINK_TEXT),降低页面结构变化导致的定位失败概率。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 16:05:35