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

如何批量爬取GBGB网站的灵缇赛事结果,无需手动指定URL?

问题

我目前通过Python代码手动指定带meeting ID和race ID的URL,从GBGB网站下载Crayford赛道的灵缇赛事结果(示例为5月25日至6月2日的数据)。但如果要下载3个月甚至9个月的数据,逐行添加URL太耗时。作为网络爬虫新手,想知道如何批量获取6个月的结果,不用手动逐个指定URL。

原代码如下:

import httpx
from selectolax.parser import HTMLParser
import json
from urllib.request import urlopen
import requests
from datetime import datetime, timedelta
import ndjson

   
URLs = [
"https://api.gbgb.org.uk/api/results/meeting/411238?raceId=1040677",#25th May Sat
     "https://api.gbgb.org.uk/api/results/meeting/411239?raceId=1040615",#26th May Sun
     "https://api.gbgb.org.uk/api/results/meeting/411378?raceId=1041270",#28st May Tue
     "https://api.gbgb.org.uk/api/results/meeting/411461?raceId=1042006",#30rd May Thu
     "https://api.gbgb.org.uk/api/results/meeting/411477?raceId=1042178",#31th May Fri
    
    #June
     
     "https://api.gbgb.org.uk/api/results/meeting/411583?raceId=1042517",#01st Jun Sat
     "https://api.gbgb.org.uk/api/results/meeting/411452?raceId=1042214",#02nd Jun Sun
]

json_list = []
for url in URLs:
    resp = requests.get(url)
    page_context = resp.text
    print(page_context)
    json_file = json.loads(page_context)
    json_list.extend(json_file)
with open('C:/mypath/Grey_results.json', 'w') as f:
    ndjson.dump(json_list, f)
解决方案

核心思路是通过GBGB的赛事列表API自动获取指定日期范围、指定赛道的meeting ID和race ID,无需手动收集。具体步骤如下:

  1. 确定赛事列表API:GBGB提供按日期和赛道查询赛事列表的接口,请求格式为https://api.gbgb.org.uk/api/meetings?date={日期字符串}&trackId={赛道ID}。Crayford赛道的trackId为7(可从网站页面源码或接口返回中确认)。
  2. 遍历目标日期范围:用datetime模块生成6个月内的所有日期,逐个日期请求赛事列表。
  3. 提取必要ID:从每个日期的赛事列表响应中,提取每个赛事的meetingId和raceId,构造结果请求URL。
  4. 批量获取并保存数据:遍历所有构造好的URL,请求结果数据,汇总后保存为NDJSON文件。

修改后的代码如下:

import requests
import json
from datetime import datetime, timedelta
import ndjson
import time

# 配置参数
TARGET_TRACK_ID = 7  # Crayford赛道的ID
START_DATE = datetime(2024, 5, 25)  # 起始日期
END_DATE = datetime(2024, 11, 25)  # 结束日期(6个月后)
OUTPUT_PATH = 'C:/mypath/Grey_results.json'
REQUEST_DELAY = 1  # 请求间隔(秒),避免触发反爬

def get_race_urls_for_date(date):
    """获取指定日期Crayford赛道所有赛事的结果URL"""
    date_str = date.strftime('%Y-%m-%d')
    # 请求当日赛事列表
    meeting_url = f'https://api.gbgb.org.uk/api/meetings?date={date_str}&trackId={TARGET_TRACK_ID}'
    try:
        resp = requests.get(meeting_url)
        resp.raise_for_status()  # 检查请求是否成功
        meetings = resp.json()
    except Exception as e:
        print(f"获取{date_str}赛事列表失败: {e}")
        return []
    
    race_urls = []
    for meeting in meetings:
        # 遍历该场次下的所有赛事
        for race in meeting.get('races', []):
            race_id = race.get('raceId')
            meeting_id = meeting.get('meetingId')
            if race_id and meeting_id:
                race_url = f'https://api.gbgb.org.uk/api/results/meeting/{meeting_id}?raceId={race_id}'
                race_urls.append(race_url)
    return race_urls

def main():
    json_list = []
    current_date = START_DATE
    # 遍历日期范围
    while current_date <= END_DATE:
        print(f"处理日期: {current_date.strftime('%Y-%m-%d')}")
        race_urls = get_race_urls_for_date(current_date)
        # 遍历当日所有赛事URL
        for url in race_urls:
            try:
                resp = requests.get(url)
                resp.raise_for_status()
                race_data = resp.json()
                json_list.extend(race_data)
                print(f"成功获取赛事数据: {url}")
                time.sleep(REQUEST_DELAY)  # 添加请求间隔
            except Exception as e:
                print(f"获取赛事数据失败{url}: {e}")
        # 日期加1天
        current_date += timedelta(days=1)
    
    # 保存数据
    with open(OUTPUT_PATH, 'w') as f:
        ndjson.dump(json_list, f)
    print(f"所有数据已保存至: {OUTPUT_PATH}")

if __name__ == '__main__':
    main()
注意事项
  • 反爬规避:加入请求间隔避免频繁请求被封禁,若仍出现问题可适当延长间隔时间。
  • 参数验证:若赛道ID不确定,可访问GBGB官网的Crayford赛道页面,查看页面源码或网络请求中的trackId参数。
  • 错误处理:代码包含基础异常捕获,可根据需求扩展重试机制或日志记录功能。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 21:35:03