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

Python Selenium PS5库存监控脚本偶发StaleElementReferenceException报错求助

错误原因

StaleElementReferenceException属于Selenium的常见偶发异常,触发原因是你调用browser.get()后立即执行find_elements_by_tag_name("span")获取了元素引用,但此时页面仍在进行动态渲染或局部更新,等你遍历调用i.text时,部分之前获取的span元素已经被页面DOM移除替换,旧的引用失效就会抛出该错误。

可行解决方案

1. 新增显式等待逻辑

不要在页面刚打开时就直接操作元素,使用Selenium自带的WebDriverWait显式等待规则,确认页面元素加载完成后再执行后续操作,避免硬编码等待时间影响效率。

2. 增加异常重试机制

针对该偶发错误增加重试逻辑,遇到过时引用异常时自动重新获取元素,最多重试3~5次即可覆盖绝大多数偶发场景。

3. 优化元素定位规则(可选,推荐)

当前你遍历页面所有span元素的逻辑效率极低,你可以直接定位包含库存状态的目标元素,不需要扫描全页面的span,大幅降低元素操作的报错概率。

修改后的完整代码

from selenium import webdriver
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, TimeoutException
import csv 
from datetime import date

options = webdriver.ChromeOptions()
options.add_argument('--headless')
options.add_argument('--no-sandbox')
options.add_argument('--disable-dev-shm-usage')
options.add_argument('user-agent=Mozilla/5.0 (Macintosh; Intel Mac OS X 10.10; rv:39.0) Gecko/20100101 Firefox/39.0')

browser = webdriver.Chrome(options = options)
browser.set_page_load_timeout(60)

browser.get('https://www.wehkamp.nl/sony-playstation-5-16644186/')

max_retry = 3
all_span_text = []
# 元素获取重试逻辑
for retry in range(max_retry):
    try:
        # 等待页面span元素全部加载完成
        WebDriverWait(browser, 15).until(EC.presence_of_all_elements_located((By.TAG_NAME, 'span')))
        all_span = browser.find_elements_by_tag_name("span")
        all_span_text = [i.text for i in all_span]
        break
    except StaleElementReferenceException:
        all_span = []
        continue
    except TimeoutException:
        browser.close()
        raise Exception("页面加载超时")
else:
    browser.close()
    raise Exception("多次尝试获取页面元素失败")

today_date = date.today()
is_beschikbaar = False

if "uitverkocht" in all_span_text:
    print("Playstation 5 is niet op voorraad")
else: 
    print("Playstation 5 is weer op voorraad")
    is_beschikbaar = True
    
headers = ["date", "is de Playstation 5 Beschikbaar?"]

with open ("ps5_beschikbaarheid.csv", "a" ) as csvfile:
    write = csv.writer(csvfile)
    #write.writerow(headers)
    write.writerow([today_date, is_beschikbaar])
    
variables['text'] = is_beschikbaar 
    
browser.close()

额外优化建议

你可以直接判断库存相关的span是否存在,不需要遍历所有span,代码运行效率会更高,报错概率也更低:

# 替换原有元素获取和判断逻辑
try:
    # 等待10秒看是否存在售罄文本的span
    WebDriverWait(browser, 10).until(EC.presence_of_element_located((By.XPATH, "//span[contains(text(),'uitverkocht')]")))
    is_beschikbaar = False
    print("Playstation 5 is niet op voorraad")
except TimeoutException:
    is_beschikbaar = True
    print("Playstation 5 is weer op voorraad")

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 12:36:04