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

Selenium循环中StaleElementException问题及解决方法问询

解决StaleElementException并正常退出爬取循环

你的问题核心在于页面跳转后,之前获取的DOM元素引用已经失效——比如company_links_elements是上一页的元素集合,当点击下一页刷新页面后,这些元素已经不在当前文档中,继续遍历就会触发StaleElementReferenceException。另外,next_page元素也可能因为页面更新变成无效引用。

修复方案

我们需要调整逻辑,确保每次处理当前页时都重新获取最新的元素,同时捕获StaleElementReferenceException来处理元素失效的情况,并用显式等待替代固定的time.sleep来确保页面加载完成:

  1. 每次进入循环先获取当前页的公司链接元素,处理完再尝试获取下一页按钮
  2. 同时捕获NoSuchElementException和StaleElementReferenceException,覆盖下一页按钮不存在或失效的场景
  3. 使用显式等待确保元素加载完成,避免因页面未加载完全导致的元素获取失败

修改后的代码

from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import csv
import random
import time
from selenium.common.exceptions import NoSuchElementException, StaleElementReferenceException

with open(f"{provider}-{state}-{city}-links.csv", 'w', newline='') as file:
    writer = csv.writer(file)
    idx = 1
    while True:
        try:
            # 显式等待当前页的公司链接加载完成
            WebDriverWait(driver, 10).until(
                EC.presence_of_all_elements_located((By.XPATH, "//h3[@class='jss320 jss324 jss337 sc-gzOgki eucExu']/a"))
            )
            # 重新获取当前页的公司链接元素(每次循环都获取最新的)
            company_links_elements = driver.find_elements(By.XPATH, "//h3[@class='jss320 jss324 jss337 sc-gzOgki eucExu']/a")
            
            # 处理当前页的所有链接
            for company in company_links_elements:
                try:
                    company_url = company.get_attribute("href")
                    writer.writerow((idx, company_url, provider))
                    idx += 1
                    time.sleep(random.randint(2, 3))
                except StaleElementReferenceException:
                    # 单个公司链接元素失效,跳过该元素继续处理下一个
                    continue
            
            # 尝试获取并点击下一页按钮
            try:
                # 显式等待下一页按钮加载完成且可点击
                next_page = WebDriverWait(driver, 5).until(
                    EC.element_to_be_clickable((By.XPATH, "//a[@role='link'][contains(text(),'Next')]"))
                )
                next_page.click()
                # 等待页面跳转完成
                time.sleep(random.randint(2, 3))
            except (NoSuchElementException, StaleElementReferenceException):
                # 没有下一页按钮或按钮失效,退出循环
                print("没有下一页,退出爬取")
                break
        except Exception as e:
            print(f"出现异常: {str(e)}")
            break

driver.quit()

关键改进点说明

  • 每次循环重新获取元素:company_links_elements在每次循环开始时重新获取,确保是当前页的有效元素引用
  • 捕获单个元素的Stale异常:在遍历公司链接时,如果单个元素失效,直接跳过继续处理下一个,不会中断整个循环
  • 显式等待:用WebDriverWait确保元素加载完成,比固定time.sleep更可靠,减少因页面加载慢导致的问题
  • 双重异常捕获:获取下一页按钮时同时处理两种异常,覆盖下一页按钮不存在或失效的所有场景

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 07:20:00