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
相关产品推荐
相关产品推荐

