导读:本期聚焦于大卫创作的《Python教程:如何使用API高效抓取GBGB赛狗结果数据(指定日期与赛道)》,敬请观看详情。想用Python获取GBGB英国赛狗比赛的官方结果数据吗?本文完整讲解如何通过GBGB公开API接口,按指定日期和赛道抓取比赛结果,内容涵盖接口分析、requests请求封装、参数拼接技巧、JSON数据解析以及数据入库保存。文章还会介绍分页处理、异常重试、请求频率控制等实用优化手段,帮助你构建一套稳定高效的赛狗数据采集程序,适合想学习API数据抓取的Python开发者参考。

GBGB(Greyhound Board of Great Britain)是英国赛狗运动的官方管理机构,其官网提供了完整的比赛结果查询功能。相比传统网页爬虫,直接调用其背后的API接口可以更稳定、更高效地获取结构化数据。本文将以Python为例,带你完整实现一套按日期和赛道抓取GBGB赛狗结果数据的采集程序。

Python教程:如何使用API高效抓取GBGB赛狗结果数据(指定日期与赛道)

一、分析GBGB的结果查询接口

打开GBGB官网的结果查询页面,通过浏览器的开发者工具(F12)切换到Network标签页,选择XHR过滤,就能观察到页面在查询时实际请求的接口地址。结果查询的核心接口大致形式如下:

https://api.gbgb.org.uk/api/results?date=2024-05-01&track=Newcastle

这个接口返回标准的JSON数据,包含当天该赛道的所有比赛场次(Race)以及每场比赛的详细结果,包括犬只名称、名次、起跑箱号、SP赔率、最终时间、训犬师等字段。需要注意的是,接口的域名和参数格式可能随官方调整而变化,动手前务必先自己抓包确认一遍。

接口通常支持的参数包括:

  • date:比赛日期,格式为YYYY-MM-DD
  • track:赛道名称,如Newcastle、Romford等
  • page:分页参数,部分查询结果较多时需要翻页

返回的JSON结构一般是嵌套的字典和列表,先手动请求一次,把返回内容格式化打印出来,弄清字段层级后再编写解析代码,可以少走很多弯路。

二、用requests封装请求并解析数据

确认接口后,我们用requests库编写基础的请求函数。为了降低被拦截的概率,建议带上浏览器标准的请求头,尤其是User-Agent字段。下面是完整的请求与解析示例:

import requests

def fetch_results(date: str, track: str) -> dict:
    """按日期和赛道抓取GBGB赛狗结果"""
    url = "https://api.gbgb.org.uk/api/results"
    headers = {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)",
        "Accept": "application/json",
        "Referer": "https://www.gbgb.org.uk/"
    }
    params = {"date": date, "track": track}
    resp = requests.get(url, headers=headers, params=params, timeout=15)
    resp.raise_for_status()
    return resp.json()

if __name__ == "__main__":
    data = fetch_results("2024-05-01", "Newcastle")
    print(data)

拿到JSON后,解析的关键是找准字段路径。假设返回数据中results字段是比赛列表,每场比赛又有greyhounds字段保存参赛犬只明细,可以这样提取核心信息:

def parse_races(data: dict) -> list:
    """提取每场比赛的关键信息"""
    rows = []
    for race in data.get("results", []):
        race_time = race.get("raceTime", "")
        race_name = race.get("raceName", "")
        for dog in race.get("greyhounds", []):
            rows.append({
                "date": race.get("date", ""),
                "track": race.get("track", ""),
                "race_time": race_time,
                "race_name": race_name,
                "position": dog.get("position"),
                "trap": dog.get("trap"),
                "dog_name": dog.get("name", ""),
                "sp": dog.get("sp", ""),
                "run_time": dog.get("runTime", ""),
                "trainer": dog.get("trainer", "")
            })
    return rows

解析时建议统一使用.get()方法并提供默认值,避免个别场次缺少某个字段时抛出KeyError导致整个采集任务中断。犬只名次字段在不同接口版本中可能是positionfinishingPosition,实际使用时根据抓包结果调整即可。

三、批量采集与稳定性优化

如果要抓取一段日期范围内的多个赛道,就需要循环拼接参数并控制请求节奏。高频请求不仅容易触发对方风控,也会给服务器造成压力,务必在每次请求之间加入延迟。同时加上异常重试机制,保证长时间任务稳定运行:

import time
import random
from datetime import date, timedelta

def daterange(start: date, end: date):
    d = start
    while d <= end:
        yield d
        d += timedelta(days=1)

TRACKS = ["Newcastle", "Romford", "Sunderland", "Yarmouth"]

def crawl(start: date, end: date):
    all_rows = []
    for d in daterange(start, end):
        for track in TRACKS:
            for attempt in range(3):  # 最多重试3次
                try:
                    data = fetch_results(d.isoformat(), track)
                    all_rows.extend(parse_races(data))
                    break
                except requests.RequestException as e:
                    print(f"请求失败: {d} {track}, 第{attempt+1}次: {e}")
                    time.sleep(5)
            time.sleep(random.uniform(1.5, 3.5))  # 随机延迟,模拟人工访问
    return all_rows

采集到的数据建议直接保存为CSV文件或写入SQLite数据库,方便后续用pandas做统计分析。CSV保存非常简单,一行代码即可:

import csv

def save_csv(rows: list, filename: str):
    if not rows:
        return
    keys = rows[0].keys()
    with open(filename, "w", newline="", encoding="utf-8-sig") as f:
        writer = csv.DictWriter(f, fieldnames=keys)
        writer.writeheader()
        writer.writerows(rows)

使用utf-8-sig编码可以避免Excel打开中文时出现乱码。如果数据量大、需要增量更新,推荐改用SQLite,按比赛日期和场次ID建立唯一索引,每次采集时用INSERT OR IGNORE跳过已存在的记录,就能实现幂等的增量采集。

四、常见问题与注意事项

第一,接口返回为空。有些赛道当天没有比赛,接口可能返回空列表或错误信息,代码中要对此做容错判断,不要当成异常处理。第二,日期边界问题。英国时间和本地时间存在时差,抓取当天数据时建议以英国当地日期为准,避免漏抓或重复。第三,遵守爬虫礼仪。控制请求频率、设置合理的超时时间、不要在高峰期大规模并发请求,这既是技术要求,也是对数据提供方的尊重。

另外,如果接口启用了更严格的反爬机制(比如动态Token校验),可以考虑使用cloudscraper库或者结合Selenium先获取有效会话再回退到requests。不过就目前的实际情况来看,GBGB的接口对正常频率的请求是比较宽容的,规范使用requests就足够了。

总结一下,整套流程的核心就是:抓包分析接口、封装请求函数、容错解析JSON、循环批量采集、控制节奏并持久化存储。掌握这套思路后,你可以把它迁移到几乎所有提供JSON接口的数据网站上,快速搭建属于自己的数据采集管道。

Python爬虫API接口GBGB赛狗数据修改时间:2026-09-02 19:18:51

免责声明:已尽一切努力确保本网站所含信息的准确性。网站作品多为原创整理与精心创作,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们进行处理Email:chomcom@qq.com。
引用或转载本作品时,请注明当前出处:https://www.ipipp.com/html/20260902/49093.html,基于非商业用途的前提下,欢迎转载或二创本作品。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。