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

如何获取Python无法解析的网球预订网站动态表格数据?

解决网球预订网站数据爬取及转DataFrame的方案

一、核心问题分析

该网站的预订表格数据是通过JavaScript动态渲染生成的,普通requests无法获取渲染后的DOM结构;若使用Selenium时未等待元素完全加载,也会拿不到目标<div class="booking-sheet clearfix">内的完整数据。

二、具体实现方案(Selenium+BeautifulSoup)

1. 等待元素加载并获取渲染后的页面源码

必须用显式等待确保目标元素完全渲染后再提取,避免强制等待的低效问题:

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 pandas as pd

# 初始化Chrome浏览器(需提前配置对应版本的ChromeDriver)
driver = webdriver.Chrome()
driver.get("https://clubspark.lta.org.uk/StJohnsParkLondon/Booking/BookByDate")

# 显式等待目标div加载完成,最长等待10秒
try:
    WebDriverWait(driver, 10).until(
        EC.presence_of_element_located((By.CLASS_NAME, "booking-sheet"))
    )
    # 获取完全渲染后的页面源码
    page_source = driver.page_source
finally:
    driver.quit()

# 解析页面源码
soup = BeautifulSoup(page_source, "html.parser")
booking_div = soup.find("div", class_="booking-sheet clearfix")

2. 提取数据并构造DataFrame

遍历目标div内的子元素,提取时间段、场地、预订状态等信息:

# 提取顶部的场地名称
courts = [court.text.strip() for court in booking_div.find_all("div", class_="booking-sheet-header-column")]
# 提取所有时间段行
time_rows = booking_div.find_all("div", class_="booking-sheet-row")

data = []
for row in time_rows:
    # 获取当前时间段
    time_slot = row.find("div", class_="booking-sheet-row-time").text.strip()
    # 获取该行所有场地的预订状态
    booking_cells = row.find_all("div", class_=["booking-sheet-cell", "booking-sheet-cell-booked"])
    
    for idx, cell in enumerate(booking_cells):
        # 判断预订状态
        status = "已预订" if "booking-sheet-cell-booked" in cell.get("class", []) else "可预订"
        # 提取预订详情(如预订人信息)
        detail = cell.find("div", class_="booking-sheet-cell-details")
        detail_text = detail.text.strip() if detail else ""
        
        data.append({
            "时间段": time_slot,
            "场地": courts[idx] if idx < len(courts) else f"场地{idx+1}",
            "状态": status,
            "详情": detail_text
        })

# 转换为DataFrame
df = pd.DataFrame(data)
print(df.head())

三、优化方案(直接调用API)

打开浏览器开发者工具的Network面板,刷新页面后筛选XHR请求,找到加载预订数据的接口(通常命名含Booking或GetBookings),直接用requests请求该接口获取JSON数据,再转为DataFrame,这种方式比渲染页面更高效:

import requests
import pandas as pd

# 替换为实际找到的API接口URL
api_url = "https://clubspark.lta.org.uk/xxx/GetBookings"
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",
    # 可能需要添加其他请求头(如Cookie、Referer等,从Network面板复制)
}

response = requests.get(api_url, headers=headers)
booking_data = response.json()

# 根据返回的JSON结构提取数据并构造DataFrame
df = pd.DataFrame(booking_data["xxx"])

四、注意事项

  • 若网站需登录才能查看数据,需在Selenium中模拟登录流程:定位用户名/密码输入框,输入后点击登录按钮,再跳转至预订页面。
  • 若遇到验证码,需手动处理或遵守网站规则,避免使用违规打码工具。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 10:43:39