5分钟抓完整个英超赛季:Understat异步Python包免费足球数据实战

📅 2026/8/19 16:04:08
5分钟抓完整个英超赛季:Understat异步Python包免费足球数据实战
5分钟抓完整个英超赛季Understat异步Python包免费足球数据实战【免费下载链接】understatAn asynchronous Python package for https://understat.com/.项目地址: https://gitcode.com/gh_mirrors/un/understat周末聚餐朋友阿凯当着全桌预测对了三场英超比分他得意地晃了晃手机屏幕上是一张密密麻麻的xG数据表来源叫 Understat.com。几天后我才知道支撑他这套神预测的其实是一个免费开源的 Understat异步Python包——而我那时还以为专业足球数据是年费几万美元的商业API专属。为什么你明明上网很方便却拿不到一份干净的足球数据先别急着怪自己技术不行。你大概率也踩过这几道坎数据散落在各处进球、助攻、xG、xGA 分散在不同网页靠手点鼠标复制粘贴整理一个赛季就得一晚上。页面是假的想自己写爬虫结果浏览器里能看到的数据用普通请求根本抓不到——Understat 的数据藏在网页脚本里直接拉 HTML 只有一堆让你怀疑人生的代码。清洗比抓取更累就算侥幸拿到了原始数据字段名乱、格式乱、还有一堆空值清洗工作量大到让你怀疑人生。商业 API 太贵正经足球数据 API 动不动按年收费个人爱好者根本玩不起。这四条是不是条条戳中你如果是下面这段从笨办法到巧办法的完整过程就是为你写的。第一次笨拙尝试正则硬抠 JSON能跑但很脆我的第一反应是既然页面是 JS 渲染的那我就用requests把 HTML 拿回来再用正则把藏在 script 标签里的 JSON 硬抠出来。代码如下import re import json import requests html requests.get(https://understat.com/league/EPL/2018).text # 硬抠 script 里的 JSON页面结构一变就崩 m re.search(rplayersData\s*\s*JSON\.parse\((.*?)\), html) raw m.group(1).encode(utf-8).decode(unicode_escape) players json.loads(raw) print(len(players))运行它居然真的打印出了一个数字——那一刻我是得意的。但很快我就笑不出来了因为这段代码有三个致命伤脆playersData这个变量名是页面内部的实现细节网站哪天改版、字段改名我的正则立刻全军覆没傻它是同步请求一次只能拉一个页面抓六个联赛就得写六个循环慢得像挤牙膏脏拿回来的数据是原始矿石过滤、排序、转类型全得我自己手写。说白了它能跑但像用指甲刀削苹果——勉强能用体验极差。方案升级换个思路让异步包替我们干活痛定思痛我决定找现成的轮子于是遇到了understat。它本质上是一个封装好的异步 Python 包把发请求、找数据、转 JSON这些脏活累活全包了你只需要调方法、拿结果。先安装装不上就用pip3pip install understat也可以把仓库克隆到本地再装git clone https://gitcode.com/gh_mirrors/un/understat cd understat pip install .装完同样的拿一整个英超赛季球员数据的需求变成了这样import asyncio import aiohttp from understat import Understat async def grab_epl(season): async with aiohttp.ClientSession() as session: understat Understat(session) players await understat.get_league_players(epl, season) return players players asyncio.run(grab_epl(2018)) print(len(players), players[0][player_name])注意看这里发生了什么没有正则、没有json.loads、没有字符串转义三行代码搞定。核心的Understat类定义在 understat/understat.py它内部借助 understat/constants.py 里的接口地址再通过 understat/utils.py 里的get_data统一完成请求和解析所以你不需要碰任何页面细节。更妙的是它天生支持过滤底层就是 understat/utils.py 里的filter_data函数。比如我只想要曼联球员players await understat.get_league_players( epl, 2018, {team_title: Manchester United} )而它异步架构的威力在一次抓多年数据时才会真正显现。用asyncio.gather并发请求五个赛季的数据几秒就能同时回来import asyncio import aiohttp from understat import Understat async def one_season(session, season): understat Understat(session) return await understat.get_league_players(epl, season) async def main(): async with aiohttp.ClientSession() as session: results await asyncio.gather( *[one_season(session, s) for s in range(2016, 2021)] ) print([len(r) for r in results]) asyncio.run(main())同一个会话session复用连接五个赛季一次性拉回。对比我先前那个同步正则脚本效率差距不是一点点——这正是异步二字的含金量。复盘与避坑这些坑希望你一次都别踩把整个过程走完我总结了一份血泪清单每一条都是真金白银换来的坑正确做法用正则硬抠页面里的 JSON用现成包解析别碰页面内部结构每次请求都新建 session复用同一个aiohttp.ClientSession省下大量连接开销拿到的字段直接做加减乘除很多值返回的是字符串记得先float()转换一股脑拉全量数据再慢慢筛用options参数在源头过滤又快又省内存对网站疯狂并发请求加个延时或缓存尊重数据源避免被封传日期时不带格式日期参数严格用YYYY-MM-DD格式如start_date2020-11-01另外一个小提醒这里的赛季年份指的是开始年比如2018代表 2018-2019 赛季联赛名用的是简写epl、la_liga、bundesliga、serie_a、ligue_1、rfpl分别对应英超、西甲、德甲、意甲、法甲和俄超映射关系写在 understat/utils.py 的to_league_name里。举一反三同一套 API还有多少隐藏玩法你以为这就完了远着呢。同一个Understat类里还藏着不少高级接口随便挑两个就能玩出花get_player_shots(player_id)把某个球员比如 ID 为 619 的塞尔吉奥·阿圭罗历年的每一脚射门都拉下来包含位置坐标和 xG复刻一张射门热区图就是几行代码的事官方文档 docs/classes/understat.rst 里附了完整示例get_league_table(league, season, start_date..., end_date...)不只是静态积分榜还能按日期区间截取做某段时间内谁状态最火的时段分析甚至能拿到 PPDA、OPPDA 这类战术指标get_match_shots(match_id)赛后立刻复盘某场比赛的每一次射门写球评、做赛后分析都够用。行动收尾现在就动手从一条命令开始别想太多也别等准备好——最小可行的第一步就两步执行pip install understat复制上文第一段抓取英超球员的代码把season改成2018跑一次看看控制台打印出来的球员名。跑通之后建议你再翻翻 tests/test_understat.py里面每个测试都对应一个真实用法等于手把手教你把所有接口摸一遍。记住数据只是理解足球的工具它替代不了你的判断——但有了它你和那些数据派之间的距离正在被一个免费的开源包抹平。【免费下载链接】understatAn asynchronous Python package for https://understat.com/.项目地址: https://gitcode.com/gh_mirrors/un/understat创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考