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

解决Selenium循环点击商品返回后出现StaleElementReferenceException问题

解决Selenium遍历商品时的StaleElementReferenceException问题

问题根源

你碰到的StaleElementReferenceException是因为:第一次加载列表页时获取的box_product_elements是当时DOM的元素引用,当你点击商品进入详情页再返回列表页后,页面已经重新渲染,原来的元素引用已经失效,和当前页面的DOM元素不再对应,自然找不到了。time.sleep和隐式等待解决不了这个问题——它们只能等元素加载,但你用的还是旧的无效引用。

解决方案

核心是每次从详情页返回列表页后,重新获取商品元素列表,同时用显式等待替代硬编码的等待,提升稳定性。修改后的代码如下:

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

chrome_options = webdriver.ChromeOptions()

driver = webdriver.Chrome(options=chrome_options)
driver.maximize_window()
driver.get("https://foodkoreadubai.com/collections/beverages")

# 处理弹窗,用显式等待替代time.sleep
try:
    close_button = WebDriverWait(driver, 10).until(
        EC.element_to_be_clickable((By.CSS_SELECTOR, ".popup-close .icon-close"))
    )
    close_button.click()
    WebDriverWait(driver, 5).until(EC.invisibility_of_element_located((By.CLASS_NAME, "popup-close")))
except:
    print("弹窗未出现或关闭失败")

# 遍历所有商品:每次返回后重新获取元素
product_index = 0
while True:
    try:
        # 每次循环重新获取商品列表
        box_product_elements = WebDriverWait(driver, 10).until(
            EC.presence_of_all_elements_located((By.CSS_SELECTOR, ".box.product"))
        )
        # 超出索引就结束循环
        if product_index >= len(box_product_elements):
            break
        # 点击当前索引的商品
        box_product_elements[product_index].click()
        # 等待详情页加载(可选,根据实际页面调整)
        WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.CLASS_NAME, "product-single")))
        # 返回列表页
        driver.back()
        # 等待列表页重新加载完成
        WebDriverWait(driver, 10).until(EC.presence_of_all_elements_located((By.CSS_SELECTOR, ".box.product")))
        product_index += 1
    except StaleElementReferenceException:
        # 如果出现stale异常,重新获取元素继续循环
        continue

driver.quit()

关键改动说明

  • 重新获取元素:把获取商品列表的操作放到循环内部,每次返回列表页后都重新查询DOM,确保使用的是当前有效的元素引用
  • 显式等待替代time.sleep:用WebDriverWait等待元素可点击/出现,比固定时长等待更可靠,能根据页面实际加载情况调整等待时间
  • 循环逻辑优化:从0开始遍历所有商品,避免跳过第一个;通过索引递增控制遍历,直到索引超出商品数量结束循环
  • 异常处理:捕获StaleElementReferenceException后继续循环,进一步提升稳定性

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 23:25:20