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

Python中解决StaleElementReferenceException:Whoscored足球数据爬取

解决Selenium操作Whoscored时间轴时的StaleElementReferenceException问题

这个异常在处理动态DOM页面时真的很常见,尤其是像Whoscored这种拖放时间轴后会实时更新比赛统计的场景——拖动手柄后,页面的统计模块会重新渲染DOM,导致你之前获取的元素引用直接失效,就抛出这个错误了。结合你用的OSX 10+Chrome+Selenium环境,给你几个针对性的解决办法:

1. 每次操作前重新定位元素(最基础也最有效)

不要提前缓存timeline-handle或者统计元素的引用,每次需要操作(拖放、读取统计)的时候都重新通过选择器定位元素。因为拖放后DOM已经变了,之前存的元素对象早就“过期”了。

示例代码:

from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.by import By

# 封装拖放时间轴手柄的函数,每次都重新定位
def drag_timeline_handle(target_offset_x):
    # 每次调用都重新找手柄元素,避免引用失效
    timeline_handle = driver.find_element(By.CLASS_NAME, "timeline-handle")
    action = ActionChains(driver)
    # 根据目标时间计算x轴偏移量(你需要自己测试10/30分钟对应的具体偏移值)
    action.drag_and_drop_by_offset(timeline_handle, target_offset_x, 0).perform()

# 调用示例:拖放下限到10分钟对应的位置
drag_timeline_handle(120) # 这里的120是示例偏移量,需要你根据实际页面调整

2. 用显式等待等待DOM更新完成

拖放手柄后,页面不会立刻完成统计更新,需要等新的统计元素渲染出来再进行后续操作。用WebDriverWait设置等待条件,确保元素已经可见/可交互后再操作。

示例代码:

from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

# 拖放后等待统计区域加载完成
def wait_for_stats_ready():
    # 替换成你要获取的统计元素的实际选择器,比如某类统计项
    WebDriverWait(driver, 10).until(
        EC.visibility_of_element_located((By.CSS_SELECTOR, "#match-centre-timeline .stat-value"))
    )

# 流程示例:拖放 → 等待 → 读取数据
drag_timeline_handle(120)
wait_for_stats_ready()
# 现在再读取统计数据,就不会拿到过期元素了
stats = driver.find_elements(By.CSS_SELECTOR, "#match-centre-timeline .stat-value")

3. 捕获异常并重试操作

有时候即使做了等待,还是可能因为页面渲染的微小延迟触发异常,这时候可以捕获StaleElementReferenceException,重试几次操作。

示例代码:

from selenium.common.exceptions import StaleElementReferenceException
import time

def get_match_stats(retries=3):
    for attempt in range(retries):
        try:
            stats_elements = driver.find_elements(By.CSS_SELECTOR, "#match-centre-timeline .stat-value")
            return [elem.text for elem in stats_elements]
        except StaleElementReferenceException:
            if attempt < retries - 1:
                time.sleep(1) # 等待1秒后重试
                continue
            else:
                raise # 重试3次都失败,抛出原始异常

# 使用示例
drag_timeline_handle(120)
wait_for_stats_ready()
match_stats = get_match_stats()

4. 检查是否有意外的页面刷新

偶尔Whoscored可能会有自动刷新机制,或者你的代码里不小心触发了页面刷新。可以检查Chrome的设置(关闭自动刷新),同时确保你的操作流程中没有多余的driver.refresh()调用。


核心思路就是不缓存元素引用+等待DOM稳定+异常重试,这三个点结合起来,基本能解决你遇到的这个问题。

内容的提问来源于stack exchange,提问作者scottish.samba

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 06:30:32