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

Selenium Python点击翻页报StaleElementReferenceException如何解决

问题根因

出现StaleElementReferenceException的核心原因是你提前定位好的DOM元素,在页面刷新/局部更新后,原引用已经被浏览器销毁,后续再调用该元素的属性/方法就会触发该报错。
你的代码存在两个明确的问题点:

  1. 提前捕获下一页按钮pag后,先遍历了当前页列表,这个过程如果页面触发异步渲染更新,会导致pag的引用失效,点击时直接报错
  2. 点击翻页后直接调用info(),但list_ed还是上一页的元素引用,哪怕设置了35秒等待,后续遍历也会触发同类报错
修复建议
  • 调整操作顺序:优先处理完当前页所有数据,再定位下一页按钮并点击,避免捕获按钮后等待过久导致元素失效
  • 不要复用跨页的元素引用:每次翻页后重新定位列表元素,不要沿用之前捕获的list_ed变量
  • 替换固定sleep为显式等待:通过判断页面元素是否更新来确认翻页完成,比固定时长等待兼容性更强
  • 增加重试机制:对下一页点击操作增加异常捕获重试逻辑,避免偶发的元素失效问题
修复后可运行代码
from selenium import webdriver
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.common.exceptions import StaleElementReferenceException, TimeoutException

def get_current_page_info(driver, wait):
    # 每次拉取数据前重新定位当前页的列表元素
    list_ed = wait.until(EC.presence_of_all_elements_located((By.XPATH, '//*[@id="jornal"]/li[@class="lista"]')))
    for idx, ed in enumerate(list_ed):
        # 遍历过程中增加异常重试,避免偶发元素失效
        for _ in range(3):
            try:
                el_text = ed.text 
                el = ed.find_element(By.XPATH, 'a').get_attribute('href')
                print(el_text)
                print(el)
                break
            except StaleElementReferenceException:
                list_ed = wait.until(EC.presence_of_all_elements_located((By.XPATH, '//*[@id="jornal"]/li[@class="lista"]')))
                ed = list_ed[idx]

def click_next_page(driver, wait) -> bool:
    # 点击前才定位下一页按钮,避免提前捕获失效
    try:
        next_btn = wait.until(EC.element_to_be_clickable((By.XPATH, '//*[@id="Pagination"]/a[@class="next"]')))
        # 记录当前页第一条数据的文本,用来校验翻页是否完成
        first_item_text = wait.until(EC.presence_of_element_located((By.XPATH, '//*[@id="jornal"]/li[@class="lista"][1]'))).text
        next_btn.click()
        # 等待页面更新:要么第一条数据变化,要么下一页按钮消失(到最后一页)
        wait.until(lambda d: d.find_element(By.XPATH, '//*[@id="jornal"]/li[@class="lista"][1]').text != first_item_text \
            or len(d.find_elements(By.XPATH, '//*[@id="Pagination"]/a[@class="next"]')) == 0)
        return True
    except TimeoutException:
        # 没有下一页,终止循环
        return False
    except StaleElementReferenceException:
        # 按钮偶发失效自动重试
        return click_next_page(driver, wait)

def main():
    driver = webdriver.Firefox()
    driver.implicitly_wait(10)
    wait = WebDriverWait(driver, 20)
    driver.get("https://www.imprensaoficialmunicipal.com.br/sao_joaquim_da_barra")
    
    while True:
        # 先拉取当前页所有数据
        get_current_page_info(driver, wait)
        # 再尝试翻页
        has_next = click_next_page(driver, wait)
        if not has_next:
            break
    driver.quit()

if __name__ == '__main__':
    main()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 18:06:03