如何定位HTML代码实现bwin体育投注赔率表格爬取?
问题分析与解决方案
你的代码返回空对象的核心原因是:这个网站的赔率表格是通过JavaScript动态渲染的,直接用requests获取的初始HTML里根本没有你要找的marketboard-event-without-header__markets-list类的表格元素——这些内容是页面加载完成后,浏览器执行JS从后端API拉取数据再生成的。
下面分两种方案帮你解决这个问题:
方案1:直接调用后端API(推荐,效率更高)
动态网站的数据通常来自后端的API接口,我们可以跳过浏览器渲染,直接请求API拿到原始数据:
- 打开浏览器的开发者工具(按F12),切换到「Network」标签页;
- 刷新目标页面,过滤「XHR/Fetch」类型的请求,找到包含赔率数据的接口(通常URL里会有
api、sports、odds这类关键词); - 复制该接口的请求URL、请求头和参数,用
requests直接请求并解析JSON。
举个例子(实际接口需要你自己在开发者工具里确认):
import requests # 替换成你找到的真实API接口URL api_url = "https://sports.bwin.com/api/sports/v2/events/filtered?sportId=4&leagueIds=42" headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36', 'Accept': 'application/json' } response = requests.get(api_url, headers=headers) data = response.json() # 解析JSON里的赔率数据,比如遍历赛事和对应的赔率 for event in data.get('events', []): event_name = event.get('name') print(f"\n赛事: {event_name}") for market in event.get('markets', []): market_name = market.get('name') print(f" 玩法: {market_name}") for outcome in market.get('outcomes', []): outcome_name = outcome.get('name') odds = outcome.get('odds', {}).get('decimal') print(f" {outcome_name}: {odds}")
方案2:用Selenium模拟浏览器渲染
如果找不到API接口,或者接口有复杂的签名验证,可以用Selenium模拟真实浏览器加载页面,等待元素渲染完成后再提取数据:
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 bs4 url = "https://sports.bwin.com/it/sports#leagueIds=42&sportId=4" headers = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36'} # 初始化Chrome浏览器(需要提前下载对应版本的chromedriver) options = webdriver.ChromeOptions() options.add_argument(f'user-agent={headers["User-Agent"]}') driver = webdriver.Chrome(options=options) try: driver.get(url) # 等待赔率表格加载完成,最多等待10秒 WebDriverWait(driver, 10).until( EC.presence_of_element_located((By.CLASS_NAME, "marketboard-event-without-header__markets-list")) ) # 获取渲染后的页面源码 page_html = driver.page_source page_soup = bs4.BeautifulSoup(page_html, "html.parser") betting_tables = page_soup.findAll("table", {"class": "marketboard-event-without-header__markets-list"}) # 遍历表格提取数据 for table in betting_tables: rows = table.find_all('tr') for row in rows: cells = row.find_all('td') if cells: # 根据实际单元格内容提取信息,比如队伍名、赔率等 print([cell.get_text(strip=True) for cell in cells]) finally: driver.quit()
额外提示
- 原代码里同时用了
urllib的uReq和requests,建议统一用requests,更简洁易用; - 注意网站的反爬机制,不要频繁请求,必要时添加请求间隔(
time.sleep()); - 如果你用Selenium,需要确保
chromedriver的版本和你的Chrome浏览器版本一致。
内容的提问来源于stack exchange,提问作者Parsifal
相关产品推荐
相关产品推荐

