新手求助:能否从Sofascore抓取实时赛事黄牌、红牌及进球数据?
解决Sofascore实时赛事数据(黄牌/红牌/进球)抓取问题
问题描述
我是web scrape新手,若问题较为基础还请见谅。我希望抓取Sofascore上正在进行的实时赛事数据,当平台新增黄牌、红牌及进球者信息时,能将这些信息打印出来。以下是我的测试代码,但无法实现需求,恳请提供解决办法。
import requests from bs4 import BeautifulSoup url = "https://www.sofascore.com/ajax-chelsea-fc-women/tKBskpwb#id:12049907" # Fetch the page content response = requests.get(url) if response.status_code == 200: soup = BeautifulSoup(response.text, 'html.parser') # Find all div elements with specified attributes player_divs = soup.find_all('div', {'elevation': '2', 'class': 'sc-fqkvVR grUnmB', 'fill': 'var(--secondary-default)'}) if player_divs: for player_div in player_divs: # Extract player name from the parent div player_name = player_div.find_parent('div', class_='sc-EHOje gzAAoj').find('span', class_='name').text.strip() print("Player Name:", player_name) else: print("No player names found matching the specified criteria.") else: print("Failed to fetch the page. Status code:", response.status_code)我尝试打印输出但仍无法解决问题。
问题根源
- 动态类名失效:代码中依赖的
sc-fqkvVR grUnmB、sc-EHOje gzAAoj这类类名是前端框架动态生成的,每次页面加载都会变化,固定写死根本抓不到目标内容。 - 静态请求无法获取实时数据:Sofascore的实时赛事更新通过WebSocket或轮询API实现,
requests.get只能拿到页面初始静态内容,无法捕获后续新增的黄牌、红牌、进球数据。
可行解决方案
方案1:调用Sofascore数据API(推荐)
Sofascore提供了未公开但可直接调用的API接口,能获取结构化的实时赛事数据,比解析HTML稳定得多。
实现步骤
- 提取赛事
eventId:你提供的链接中#id:12049907里的12049907就是该赛事的eventId。 - 轮询API对比新旧数据,输出新增的目标事件。
代码示例
import requests import time # 目标赛事ID EVENT_ID = 12049907 # 存储已处理的事件ID,避免重复输出 processed_events = set() def fetch_live_events(): api_url = f"https://api.sofascore.com/api/v1/event/{EVENT_ID}/feed" headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36" } response = requests.get(api_url, headers=headers) return response.json() if response.status_code == 200 else None while True: event_data = fetch_live_events() if event_data and "events" in event_data: for event in event_data["events"]: event_id = event["id"] if event_id not in processed_events: processed_events.add(event_id) player = event.get("player", {}).get("name", "未知球员") team = event.get("team", {}).get("name", "未知球队") event_type = event["type"] if event_type == "goal": print(f"⚽ 进球:{team} - {player}") elif event_type == "yellowCard": print(f"🟡 黄牌:{team} - {player}") elif event_type == "redCard": print(f"🔴 红牌:{team} - {player}") # 每隔5秒轮询一次,可根据需求调整间隔 time.sleep(5)
方案2:Selenium模拟浏览器(备用)
如果API调用受限,可用Selenium模拟浏览器加载页面,监听DOM变化获取实时更新,但这种方式资源消耗较大,不推荐长期运行。
代码示例(简化版)
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 import time event_url = "https://www.sofascore.com/event/12049907" driver = webdriver.Chrome() # 需要提前安装对应版本的ChromeDriver driver.get(event_url) processed_event_texts = set() while True: # 等待事件列表加载完成 events = WebDriverWait(driver, 10).until( EC.presence_of_all_elements_located((By.CSS_SELECTOR, ".EventFeed_event__x5I2O")) ) for event in events: event_text = event.text.strip() if event_text not in processed_event_texts: processed_event_texts.add(event_text) event_classes = event.get_attribute("class") if "goal" in event_classes: print(f"⚽ {event_text}") elif "yellowCard" in event_classes: print(f"🟡 {event_text}") elif "redCard" in event_classes: print(f"🔴 {event_text}") time.sleep(3)
注意事项
- API接口可能随平台更新变动,若出现请求失败,需检查接口路径或请求头是否需要调整。
- 不要过于频繁调用API,建议设置5-10秒的间隔,避免触发反爬机制。
- 使用Selenium时,需确保浏览器驱动程序与浏览器版本匹配。
内容的提问来源于stack exchange,提问作者xMoTiVz
相关产品推荐
相关产品推荐

