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

Python Selenium scrollIntoView触发StaleElementReferenceException问题

问题解决:NBA赛程爬取中页面重载导致的StaleElementReferenceException

问题场景

爬取NBA赛程页面中data-id='nba:schedule:main:team:link'的球队名称,通过scrollIntoView定位元素后提取内容到列表和文本文件。但页面中途重载后屏幕冻结,滚动操作停止,添加time.sleep(3)也无效,抛出StaleElementReferenceException错误。

错误原因

StaleElementReferenceException的本质是:你最初获取的元素引用,在页面DOM被重新渲染(比如页面重载、动态刷新)后,已经和当前页面的元素失去关联。你一开始一次性获取了所有elements_to_save,但页面中途重载后,这些元素对象已经失效,再操作就会报错。

解决方案

核心思路是避免复用失效的元素引用,每次操作前重新定位元素,同时处理页面动态加载的情况:

修改后的代码

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

driver = webdriver.Chrome(r"C:\Users\Admin\Downloads\chromedriver_win32 (1)\chromedriver.exe")
driver.get("https://www.nba.com/schedule?pd=false&region=1")
wait = WebDriverWait(driver, 10)

# 处理同意cookie弹窗
wait.until(EC.element_to_be_clickable((By.ID, "onetrust-accept-btn-handler"))).click()

# 初始化文件和列表
myList = []
with open('new_result_file00.txt', 'w', encoding='utf-8') as f:
    # 写入初始标题和时间
    header_element = wait.until(EC.presence_of_element_located((By.XPATH, "//div/div/div/div/h4")))
    f.write(header_element.text + "\n")
    f.write(str(datetime.today()) + "\n")
    myList.append(1)

    # 循环处理元素,每次重新获取避免stale引用
    processed_count = 0
    while True:
        try:
            # 每次循环重新获取所有当前页面的目标元素
            elements_to_save = wait.until(EC.presence_of_all_elements_located((By.XPATH, "//*[@data-id='nba:schedule:main:team:link']")))
            # 只处理未处理过的元素
            for element in elements_to_save[processed_count:]:
                try:
                    # 滚动到元素位置
                    driver.execute_script("arguments[0].scrollIntoView({behavior: 'smooth', block: 'center'});", element)
                    # 等待元素文本可获取
                    wait.until(EC.visibility_of(element))
                    team_name = element.text
                    # 写入文件和列表
                    f.write(team_name + "\n")
                    f.write(str(datetime.today()) + "\n")
                    myList.append(team_name)
                    processed_count += 1
                    # 短暂等待避免滚动过快触发页面重载
                    time.sleep(1)
                except StaleElementReferenceException:
                    # 遇到stale引用,跳过当前元素,下次循环重新获取
                    continue
            # 尝试滚动到底部加载更多内容
            driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
            time.sleep(2)
            # 检查是否还有新元素加载
            new_elements = wait.until(EC.presence_of_all_elements_located((By.XPATH, "//*[@data-id='nba:schedule:main:team:link']")))
            if len(new_elements) == processed_count:
                # 没有新元素,结束循环
                break
        except Exception as e:
            print(f"处理出错: {e}")
            break

driver.quit()

关键改动说明

  • 每次循环重新获取元素:不再一次性获取所有元素,而是每次循环重新定位,避免页面重载后引用失效
  • 使用显式等待:用WebDriverWait替代implicitly_wait,更精准地等待元素可交互/可见,提升稳定性
  • 处理动态加载:滚动到底部后等待新元素加载,直到没有新内容为止
  • 捕获StaleElementReferenceException:遇到失效引用时跳过当前元素,下次循环重新获取
  • 用with语句管理文件:自动处理文件关闭,避免资源泄漏
  • 优化滚动方式:使用平滑滚动并居中元素,减少页面重载触发概率

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 04:10:39