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

如何使用Python抓取HTML弹窗表格/图表?——BestFightOdds网站MMA赛事DraftKings开盘赔率抓取需求

解决MMA赔率抓取中动态弹窗内容的问题

问题描述

我在做一个MMA机器学习项目,要从bestfightodds.com网站抓取每位选手的DraftKings开盘赔率。现在能顺利拿到选手姓名,但开盘赔率得点击DraftKings列对应的赔率值,在弹出的表格里才能看到——这个表格的HTML是点击后才动态生成并加载的,直接用requests拉取静态页面的话,根本找不到这部分内容,所以用BeautifulSoup查找时返回None。

我目前写的代码是这样的:

# Importing packages
from bs4 import BeautifulSoup
import requests
# Specifying website URL
html_text = requests.get('https://www.bestfightodds.com/events/ufc-273-2411').text
soup = BeautifulSoup(html_text, 'lxml')
# Finding values
fighter_names = soup.find_all('span', class_ = 't-b-fcc')
opening_odds = soup.find_all('span, style_ = 'margin-left: 4px; margin-right: 4px;')
for fighter_names in soup.find_all('span', class_ = 't-b-fcc'):
    print (fighter_names.get_text())

(补充:开盘赔率定位说明——蓝色框是触发弹窗的点击区域,红色框是需要抓取的开盘赔率位置)


核心问题分析

静态HTTP请求(比如requests库)只能获取页面初始加载的HTML,而弹窗里的赔率数据是用户点击后,网站通过AJAX请求动态加载的,所以静态请求拿不到这部分内容。要解决这个问题,得用能模拟浏览器交互行为的工具,比如Selenium,它可以帮你模拟点击操作,等待弹窗加载完成后再抓取数据。

具体解决方案

步骤1:准备工具

首先安装Selenium库:

pip install selenium

然后下载对应你浏览器的驱动(比如Chrome的ChromeDriver),确保驱动版本和浏览器版本匹配,把驱动放在系统能找到的路径,或者在代码里指定驱动路径。

步骤2:编写抓取代码

下面是调整后的代码,实现模拟点击、等待弹窗加载、提取开盘赔率的功能:

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 bs4 import BeautifulSoup
import time

# 初始化Chrome浏览器驱动(用其他浏览器的话替换为对应驱动,比如Firefox的GeckoDriver)
driver = webdriver.Chrome()
# 打开目标赛事页面
driver.get('https://www.bestfightodds.com/events/ufc-273-2411')

try:
    # 等待页面加载完成,找到所有DraftKings的赔率点击元素
    draftkings_odds_links = WebDriverWait(driver, 10).until(
        EC.presence_of_all_elements_located((By.CSS_SELECTOR, 'td[data-book="draftkings"] a'))
    )

    # 遍历每个赔率链接,点击后抓取开盘赔率
    for idx, link in enumerate(draftkings_odds_links):
        # 同一组比赛的两位选手,弹窗只需点击一次即可查看两人数据,所以隔一个点击一次
        if idx % 2 == 0:
            link.click()
            time.sleep(1)  # 给弹窗一点加载时间
            # 解析当前页面(包含弹窗)的HTML
            page_soup = BeautifulSoup(driver.page_source, 'lxml')
            # 定位开盘赔率元素(根据你提供的样式,这里用style属性定位,实际可能需要根据弹窗真实结构调整)
            opening_odds = page_soup.find('span', style='margin-left: 4px; margin-right: 4px;')
            # 获取对应选手的姓名
            fighter_name = driver.find_elements(By.CSS_SELECTOR, 'span.t-b-fcc')[idx].text
            
            if opening_odds:
                print(f"选手: {fighter_name} | 开盘赔率: {opening_odds.get_text()}")
            else:
                print(f"选手: {fighter_name} | 未找到开盘赔率")
            
            # 点击页面空白处关闭弹窗
            driver.find_element(By.CSS_SELECTOR, 'body').click()
            time.sleep(0.5)

finally:
    # 完成抓取后关闭浏览器
    driver.quit()

关键注意点

  • 选择器调整:如果弹窗的实际HTML结构和你描述的有差异,一定要打开浏览器开发者工具,点击弹窗后查看真实的元素属性,替换代码里的CSS选择器,否则可能抓不到数据。
  • 反爬应对:网站可能有反爬机制,建议不要太快地连续点击,适当增加time.sleep()的时长,也可以设置随机等待时间,避免被封禁IP。
  • 效率优化:如果要抓取多个赛事页面,可以复用浏览器实例,不用每次都重新打开关闭,提升抓取效率。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.28 18:07:42