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

为何Inspect Element可见的DraftKings数据无法被BeautifulSoup解析?

问题根源

DraftKings这类体育博彩网站的部分页面内容是JavaScript动态渲染的,requests.get只能获取页面初始的静态HTML,动态加载的数据不会出现在返回内容里,所以BeautifulSoup找不到对应的选择器元素。之前爬本垒打数据成功,大概率是那个页面的内容刚好是静态嵌入的,而总垒打(total-bases)的内容需要浏览器执行JS后才会加载。

解决方案

按优先级推荐两种处理方式:


方法1:直接爬网站的API接口(最优)

这类网站通常会通过API接口加载数据,比解析HTML稳定得多,步骤如下:

  1. 打开浏览器访问目标URL,按F12打开开发者工具,切换到「Network」标签后刷新页面
  2. 过滤「XHR」或「Fetch」请求,找包含球员数据的接口(URL通常带有odds、props、players这类关键词)
  3. 用requests直接请求该API URL,解析返回的JSON数据生成DataFrame

示例代码(需替换为你找到的真实API接口):

import requests
import pandas as pd

# 替换为实际找到的API地址
api_url = "https://api.draftkings.com/sportsbook/v1/odds/baseball/mlb/batter-props/total-bases"
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"
}
response = requests.get(api_url, headers=headers)
data = response.json()

# 从JSON结构中提取所需字段(需根据实际返回结构调整)
player_data = []
for event in data["events"]:
    for offering in event["offerings"]:
        line = offering["line"]
        for outcome in offering["outcomes"]:
            player_name = outcome["participant"]["name"]
            odds = int(outcome["odds"].replace('−', '-'))
            if outcome["label"] == "Over":
                over_odds = odds
                under_odds = None
            else:
                under_odds = odds
                over_odds = None
            player_data.append({
                "Player Name": player_name,
                "Line": line,
                "Over": over_odds,
                "Under": under_odds
            })

# 整理数据并去重
df = pd.DataFrame(player_data)
df = df.groupby(["Player Name", "Line"]).agg({"Over": "first", "Under": "first"}).reset_index()

方法2:用动态渲染工具(Selenium)

如果找不到可用的API,就用Selenium模拟浏览器加载页面,等JS渲染完成后再解析HTML:

  1. 安装依赖:pip install selenium
  2. 下载对应浏览器的驱动(比如ChromeDriver,需和浏览器版本匹配),放到系统PATH或指定路径
  3. 编写代码模拟浏览器访问并等待内容加载

示例代码:

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 pandas as pd
from bs4 import BeautifulSoup

url = 'https://sportsbook.draftkings.com/leagues/baseball/mlb?category=batter-props&subcategory=total-bases'

# 初始化Chrome浏览器(需确保ChromeDriver已配置)
driver = webdriver.Chrome()
driver.get(url)

# 等待页面核心元素加载完成(最长等待10秒)
wait = WebDriverWait(driver, 10)
wait.until(EC.presence_of_element_located((By.CLASS_NAME, "sportsbook-row-name")))

# 获取渲染后的完整HTML
page_source = driver.page_source
soup = BeautifulSoup(page_source, 'html.parser')

# 提取数据(需根据实际页面结构调整选择器)
player_names = [row.get_text(strip=True) for row in soup.find_all(class_="sportsbook-row-name")]
lines = [float(el.text.strip().replace(",", "")) for el in soup.select(".sportsbook-outcome-cell__line") if el.text.strip()]
over_odds = [int(el.text.strip().replace('−', '-')) for el in soup.select(".sportsbook-outcome-cell:has(.sportsbook-outcome-cell__label:contains('Over')) .default-color")]
under_odds = [int(el.text.strip().replace('−', '-')) for el in soup.select(".sportsbook-outcome-cell:has(.sportsbook-outcome-cell__label:contains('Under')) .default-color")]

# 生成DataFrame(确保各列表长度匹配)
df = pd.DataFrame({
    "Player Name": player_names,
    "Line": lines[::2],  # 按实际页面结构调整索引逻辑
    "Over": over_odds,
    "Under": under_odds
})

# 关闭浏览器
driver.quit()

要不要换工具包?

不需要完全换掉BeautifulSoup——它只是HTML解析工具,本身处理不了动态内容。你可以结合API请求或者动态渲染工具(Selenium/Playwright)获取完整页面内容后,再用BeautifulSoup解析,或者直接处理JSON数据即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 12:43:11