关于 duv
duv 是面向超长距离跑步数据查询的技能,使用 DUV 官方统计数据库的 JSON 接口及必要的 HTML 页面。随附的 Python 3 标准库客户端可查询选手、赛事、成绩、排名、纪录和统计,并输出 CSV、Markdown 或 JSON。
主要功能
- 01查询选手资料与成绩
- 02搜索赛事并查看历史
- 03筛选排名、纪录和日历
- 04生成多类统计与对比
- 05导出 CSV、Markdown 或 JSON
适用场景
- 01查询国家或洲际最佳成绩
- 02比较选手成绩与职业生涯
- 03查找赛事届次、获胜者和赛道纪录
- 04统计赛事或选手相关数据
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ jablonkai/ skills --skill duv安装后在 Claude Code 中输入/duv确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/analysis.mdendpoints.mdjson-api.mdparameters.mdrecords.mdstatistics.mdscripts/duv.py详细介绍
DUV 超级马拉松统计
https://statistik.d-u-v.org/ 是全球超级马拉松成绩的权威数据库。
它没有文档化的 API,但确实提供了 JSON 接口:为 DUV 移动应用提供数据的 json/m*.php 端点会返回跑者、赛事、成绩、排名、日历和国家纪录的纯 JSON。优先使用这些接口;只有少数没有对应 JSON 接口的页面才抓取 HTML。所有内容均公开且无需身份验证——但该网站由志愿者运营,因此请按顺序发送请求,并间隔一段时间。
最快的方式:使用捆绑客户端
scripts/duv.py(Python 3,标准库)封装了所有 JSON 端点,默认输出 CSV(--format md|json、--out FILE)。请在技能目录中运行:
python3 scripts/duv.py records --nat HUN --dist 100km --dist 24h # national records
python3 scripts/duv.py records --nat HUN --dist all --overall-only --format md
python3 scripts/duv.py records --nat 1 --dist 24h --type track --gender W # Europe, track, women
python3 scripts/duv.py rankings --year 2024 --dist 100km --gender W --nat HUN
python3 scripts/duv.py rankings --year all --dist 24h --gender M --pages all --primary-only --out 24h.csv
python3 scripts/duv.py runner --name "Berces, Edit" # or --id 5752
python3 scripts/duv.py search-event "Spartathlon" # or "York,100,USA"
python3 scripts/duv.py event --id 100580 # finisher list (scraped HTML)
python3 scripts/duv.py event-detail --id 100580 # organizer, venue, editions
python3 scripts/duv.py calendar --year 2024 --country HUN --dist 100km
python3 scripts/duv.py get "json/msearchrunner.php?sname=Jablonkai" # any JSON URL, raw
派生视图和仅提供 HTML 的页面也各有一个对应命令:
python3 scripts/duv.py event-history --id 100580 --format md # editions, winners, course records
python3 scripts/duv.py multiple-finishers --id 100580 # most finishes of a race series
python3 scripts/duv.py event-list --year 2024 --country HUN --from 80 --to 120 --sort finishers
python3 scripts/duv.py progression --nat HUN --dist 24h --gender W # record progression
python3 scripts/duv.py head-to-head --runner 3510 --runner "Sipos, Istvan"
python3 scripts/duv.py champions --dist 24hWC --cnt 3 # IAU WC/EC medallists, every edition
python3 scripts/duv.py stats lifetime-mileage --country HUN # also: year-km, oldest-finishers,
# timespan, female-winners, top-abroad, long-running-races, 100x100mi, doping
运行 python3 scripts/duv.py <subcommand> -h 可列出所有标志。该脚本处理了手动编写请求时容易踩到的两个问题——某些响应携带的 UTF-8 BOM,以及 DUV 会对无法识别的参数值返回空的 200 响应正文,而不是报错。如果 Python 的 urllib 无法验证网站证书(例如在 macOS 上直接安装 python.org 版本的 Python),脚本会静默改用 curl 重试。服务器有时会突发断开或拒绝连接;脚本会逐步延长等待时间后重试,因此请勿再为其套上一层自己的重试循环。HTTP 401 表示 DUV 已将该端点设为需要登录——请改用对应的 HTML 页面,而不是重试。meventdetail.php 返回 404 并非错误:响应正文就是完整数据,脚本会正确处理。
纪录——最常被问到的内容
DUV 列出的是最佳成绩,而非经认证的纪录,并且会在每个纪录页面上说明这一点。在此提供“国家纪录”时,请附上这句说明;如需官方世界纪录,请引导用户查看 IAU 表格(链接位于 overview_records.php)。可查询的内容如下:
| 查询内容 | 操作 |
|---|---|
| 国家 X、距离 D、任一性别的纪录 | records --nat X --dist D——一次调用即可返回两个性别及所有年龄组的成绩 |
| 一个或多个国家的所有纪录 | 使用 --dist all,重复指定 --nat;添加 --overall-only 仅查询公开组纪录 |
| 大洲最佳成绩 | --nat 1..6(1 欧洲,2 亚洲,3 非洲,4 北美洲,5 南美洲,6 大洋洲) |
| 仅查询公路/赛道/室内成绩 | `--type road |
| 年龄组(大师组)纪录 | 每一行均为一个年龄组;--cat DOB = IAU 年龄组(U23/23/35/40…),--cat YOB = 德国出生年份组(U20/20/30/35…) |
| 世界纪录 | DUV 不提供 → 查询 IAU;非官方的“历史最佳成绩”可通过 rankings --year all --dist D --gender G 查询,取第一行 |
| 德国官方纪录 | recordsGER.php?dist=D(仅 HTML) |
回答任何纪录相关问题之前,请阅读 references/records.md——其中说明了 S/T/I 跑道/赛道/室内分类标志(24 小时赛中的 100 km 分段成绩不属于独立赛事纪录)、分类方案的差异,以及如何措辞回答。
选择端点
| 需求 | 端点(JSON,除非另有说明) |
|---|---|
| 通过姓名查找跑者 ID | msearchrunner.php?sname=Surname,Given |
| 个人资料、PB、每项成绩、逐年对比 | mgetresultperson.php?runner=<id> — 只有符合排名资格的距离才有 PB;非标准距离(81 km、111 km)位于 AllPerfs |
| 通过姓名或城镇查找赛事 ID | msearchevent.php?sname=Name,100,HUN — 命中项已包含完整元数据 |
| 完赛者列表 | getresultevent.php?event=<id>(HTML,每页 2000 行)— JSON 对应端点 mgetresultevent.php 现在会返回 401(需要登录令牌);duv.py event 会抓取 HTML |
| 主办城镇、组织者、限制、历届赛事 | meventdetail.php?event=<id> — editions[] 会列出赛事历史 |
| 某年的前 N 名/历史最佳列表 | mgetintbestlist.php — 每页 400 行,没有硬性上限;行中包含运动员、国家、日期和场地,因此无需跟进链接 |
| 国家/洲际纪录 | mbestperfcountry.php — 见上文 |
| 某年的赛事,无论过去还是未来 | `mcalendar.php?year=2024 |
过去的赛事,包含完赛人数、公里数范围(from/to)、按完赛人数排序 | geteventlist.php(HTML) |
| 俱乐部成绩 | getresultclub.php(HTML) |
| 赛道纪录、各届冠军、赛事历史 | event-history(来自 meventdetail.php)— getresulteventalltime.php 现在会返回 404 |
| 统计数据、锦标赛、杯赛、德国列表 | references/statistics.md 中的 HTML 页面 |
详情请参阅:references/json-api.md,了解每个 JSON 字段; references/endpoints.md,了解 HTML 页面及其表单特性; references/parameters.md,了解通用值词汇表。请阅读即将调用的端点对应章节,无需通读全部内容。
需要多次调用的问题
赛道纪录、纪录进展、直接对决、跑者职业生涯曲线、“谁跑得最多”、奖牌榜、某个国家规模最大的赛事:references/analysis.md 为每项问题提供了操作方案,并列出回答中应说明的限制(仅包含符合排名资格的成绩、分段成绩、净成绩与总成绩、推算数据与列出的数据)。对于任何并非单次查询的问题,请先阅读该文档。
首次请求前需要了解的陷阱
- 必须使用精确令牌。
dist=100km,而非100 km;gender=W,而非F;nat=1,而非Europe;surface=Backy/Indoo(截断为 5 个字符,区分大小写)。JSON 遇到无效令牌会返回空响应体;HTML 页面可能返回 0 行、忽略筛选条件,或显示很短的Error - Invalid input页面。结果可疑时,通常是参数无效,而非数据缺失。 nat按运动员国籍筛选,而非场地所在地。 要查询“欧洲 24 小时跑最佳成绩”,需要在客户端按赛事Country筛选世界列表。- 排名中的多项成绩行会标为
(2)、(3)……统计不同运动员前,先将这些行剔除(--primary-only)。 - 纪录不支持全球范围。
nat=all在此类查询中不会返回任何结果。 - 相同概念,不同页面使用不同令牌:
geteventlist.php使用label=Y,而排名页面使用label=IAU;日历使用country=,而排名和纪录使用nat=;HTML 列表使用数字排序值sort=1|2。 - 日历特性。
calendar --year all表示“从今天起”;查询历史赛事时,请逐年循环。JSON 日历会忽略cups,因此请使用--cupname "NC 24h"筛选锦标赛。 - 切勿猜测 ID。 跑者、赛事和俱乐部 ID 都是不透明的,应先通过搜索查找。姓名搜索返回多人时,
ActivRange(活跃年份)和YOB(出生年份)比逐个打开个人资料更快区分同名者。 - 隐私。
Privacy: "1"的跑者已要求匿名;请勿绕过此设置。
提供优质答案
提供 DUV ID 或链接,方便用户核查;如果某项数据是推算得出的(例如,根据各届获奖者整理课程记录,或根据排名重放进步情况),而非 DUV 列出的数据,请明确说明。注明所用范围(按国家还是国籍、按年份还是所有年份、路面、年龄方案、是否包含分段成绩)。跨端点排序时,请留意 DUV 的 dd.mm.yyyy 日期格式与 ISO 日期格式之间的差异。如果问题存在歧义——例如“欧洲女子 24 小时赛最佳成绩”——请选择更可能的理解方式,说明采用了哪种理解,并提供另一种解读。