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

Selenium爬取英超黄牌统计数据时获取值与HTML实际值不符

问题根因
  • 页面异步渲染未完成就执行抓取:你访问的统计页是纯前端动态渲染的,driver.get()触发跳转后,页面会先加载全历史赛季的俱乐部累计黄牌默认数据,再通过异步接口拉取se=20参数对应赛季的真实数据替换表格内容。你没有等待数据替换完成就直接读取DOM文本,拿到的是默认的历史累计值,和目标赛季的数值自然差异极大。
  • 绝对Xpath容错性为0:你使用的从根节点开始逐层索引的绝对Xpath,只要页面插入运营广告、调整DOM层级、新增功能模块,就会出现定位偏移,很容易抓错列的内容。
  • 未处理页面前置弹窗:首次访问英超官网会弹出cookie授权弹窗,会阻塞页面JS执行、遮挡内容,进一步导致数据加载异常。
修复代码
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.webdriver.chrome.service import Service
import time

chrome_driver_path = "你的chromedriver本地路径"
driver = webdriver.Chrome(service=Service(chrome_driver_path))
wait = WebDriverWait(driver, 15)

driver.get("https://www.premierleague.com/stats/top/clubs/total_yel_card?se=20")

# 处理cookie授权弹窗
try:
    accept_cookie_btn = wait.until(EC.element_to_be_clickable(
        (By.XPATH, '//button[@id="onetrust-accept-btn-handler"]')
    ))
    accept_cookie_btn.click()
except:
    pass

# 等待目标赛季数据加载完成:单赛季俱乐部黄牌数不可能超过200,抓到小于200的数值说明默认历史数据已被替换
wait.until(EC.presence_of_element_located(
    (By.CSS_SELECTOR, 'tbody tr:first-child td.stats-table__main-stat')
))
while True:
    first_card_val = driver.find_element(By.CSS_SELECTOR, 'tbody tr:first-child td.stats-table__main-stat').text
    processed_val = int(first_card_val.replace(',', ''))
    if processed_val < 200:
        break
    time.sleep(0.5)

cards = {}
# 用相对定位遍历表格行,避免绝对路径索引失效
rows = driver.find_elements(By.CSS_SELECTOR, 'table.stats-table tbody tr')
for row in rows[:20]:
    club_name = row.find_element(By.CSS_SELECTOR, 'td a.stats-table__playerName').text
    # 直接定位带统计值专属class的单元格,避免列索引偏移
    card_count = row.find_element(By.CSS_SELECTOR, 'td.stats-table__main-stat').text
    cards[club_name] = card_count

print(cards)
driver.quit()
注意点
  • 不要使用绝对Xpath定位元素,优先使用元素的class、id等稳定属性做相对定位,避免页面结构微调就导致定位失效。
  • 爬取动态渲染页面必须加显式等待,不要页面刚跳转就立刻抓取内容,要等目标元素加载到符合预期的状态再读取数据。
  • 数值类内容抓取后可以先做合理性校验,比如单赛季俱乐部黄牌数不可能超过200,一旦抓到上千的数值就说明拿到的是错误的默认数据,等待重新加载即可。

内容的提问来源于stack exchange,提问作者Nuri Taş

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 04:45:38