duv について
duv は、DUV 統計データベースの JSON エンドポイントと必要に応じた HTML ページを使って、ウルトラマラソンのデータを調べるスキルです。付属の Python 3 標準ライブラリ製クライアントで選手、イベント、結果、ランキング、記録、統計を取得し、CSV、Markdown、JSON で出力できます。
主な機能
- 01選手プロフィールと結果の検索
- 02イベント検索と履歴の確認
- 03ランキング、記録、カレンダーの絞り込み
- 04統計と比較データの作成
- 05CSV、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 API はあります。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 のみのページも、それぞれ 1 つのコマンドで取得できます。
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 で、すべてのフラグを確認できます。このスクリプトは、手書きの呼び出しでつまずきやすい 2 つの点に対応しています。一部のレスポンスに含まれる UTF-8 BOM と、DUV が認識できないパラメーター値に対してエラーではなく空の 200 ボディを返す点です。Python の urllib がサイトの証明書を検証できない場合(macOS に python.org からインストールしただけの環境など)、curl 経由で自動的に再試行します。サーバーは接続を断ったり拒否したりすることがあるため、スクリプトは待機時間を徐々に延ばして再試行します。独自の再試行ループで囲まないでください。HTTP 401 は、DUV がそのエンドポイントをログイン必須にしたことを意味します。再試行せず、対応する HTML ページを使ってください。meventdetail.php の 404 はエラーではありません。ボディには完全なペイロードが含まれており、スクリプトはそれを使用します。
記録 — 最もよく尋ねられる項目
DUV が掲載しているのは最高成績であり、公認記録ではありません。この点は記録の各ページにも明記されています。ここから「国内記録」を紹介する場合は、この注意書きを一文添えてください。公式の世界記録を確認するには、ユーザーを IAU の一覧(overview_records.php からリンクされています)に案内してください。利用できる情報は次のとおりです。
| 質問 | 対応方法 |
|---|---|
| 国 X、距離 D、性別を問わない国内記録 | records --nat X --dist D — 男女およびすべての年齢グループが 1 回の呼び出しで返されます |
| ある国または複数の国の全記録 | --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、page ごとに 2000 行)— JSON 版の mgetresultevent.php は現在 401 を返します(ログイントークンが必要です)。duv.py event は HTML をスクレイピングします |
| 開催地、主催者、制限事項、過去の全開催回 | meventdetail.php?event=<id> — editions[] からレースの履歴をたどれます |
| 年間トップ N/歴代リスト | mgetintbestlist.php — page ごとに 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 ページ |
詳細は、JSON の全フィールドについては references/json-api.md、HTML ページとそのフォーム特有の仕様については references/endpoints.md、共通の値の一覧については 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時間走」のように質問が曖昧な場合は、より可能性の高い解釈を採用してその旨を伝え、もう一方の解釈も提示してください。