Wikipediaのダンプファイルから出典ISBNを抽出するツール
- 日本語版・英語版Wikipediaのダンプから出典ISBNを抽出
- 抽出したデータはLine-delimited JSON形式で保存
- ある程度の表記ゆれを吸収
- multistreamダンプをストリーム単位で並列処理(28コア環境で約16倍)
uv syncUsage: citation [OPTIONS] INPUT_FILENAME EXPORT_FILENAME
Options:
--show-exclusion / --no-show-exclusion
除外した項目を表示する
--unique / --no-unique 同じページに同じISBNが複数あれば1件にまとめる
-j, --jobs INTEGER 並列数。既定はCPU数。1を指定すると逐次処理する
--help Show this message and exit.1つのページで同じ出典を何度も参照していると、そのぶんレコードが増えます (jawiki-20260401で約9%が重複)。ISBNから記事を引く用途なら
--unique を付けると (ページ, ISBN)単位にまとまります。どのセクションで参照されたかを分析したい場合は、
h1 / h2 が失われるため既定のままにしてください。
wget https://dumps.wikimedia.org/jawiki/20260401/jawiki-20260401-pages-articles-multistream.xml.bz2
uv run citation jawiki-20260401-pages-articles-multistream.xml.bz2 citation-jawiki-20260401.jsonlmultistreamダンプは100ページごとに独立したbz2ストリームが連結されているため、 ストリーム単位で分割して並列に処理する。抽出の状態はページ境界で閉じるので、 出力は逐次処理と1バイトも変わらない。
# 件数、空のISBN、スコア分布、見出しの内訳
uv run citation-audit stats citation-jawiki-20260401.jsonl
# 2つの出力を比較して、増減した件数と内容が変わった件数を表示
uv run citation-audit diff before.jsonl after.jsonl抽出ロジックに手を入れたときの影響を測るために使う。未対応の問題は KNOWN_ISSUES.md を参照。
{
"isbn": "4772212272",
"raw": "4-7722-1227-2",
"title": "地理学",
"score": 2.9,
"h1": "参考文献",
"h2": null,
"is_ref": true
}| 項目 | 型 | 概要 |
|---|---|---|
| isbn | String | 正規化されたISBN(原則ISBN-10。979で始まるものはISBN-13) |
| raw | String | 解析される元のISBN表記 |
| title | String | Wikipediaのページ名 |
| score | Number | 独自指標により算出されたISBNの正確さ (スコアが低い場合は、誤って検出した場合がある) |
| h1 | String/null | 見出し1 |
| h2 | String/null | 見出し2 |
| is_ref | Boolean | 出典であることが明記されているか(作品リストなどではfalse) |
isbn は原則としてISBN-10に揃えていますが、979で始まるISBN-13だけは13桁のまま出力します。
979は2007年に追加されたプレフィックスで、ISBN-10の番号空間に対応する番号が存在しないためです (jawiki-20260401で約660件)。
スコアは2段階で算出しています。
- ISBN表記としての確からしさ — 接頭辞(
ISBNなど)の有無、チェックデジットの検証、 桁数パターンから算出します。 この値が1.0以上のものを抽出対象として採用します - 出典らしさの補正 — 採用したあとに、
<ref>タグやciteテンプレートの有無、 直近の見出しに応じて加減点します
出力される score は補正後の値です。採用の判定は補正前の値で済んでいるため、 「作品リスト」のような著作一覧の見出しで減点されたレコードは、
score が1.0を 下回ることがあります(jawiki-20260401で12,614件、全体の1.0%)。ISBN自体は有効なので、 出典かどうかで絞り込みたい場合は
score ではなく is_ref を使ってください。
いずれも現在の抽出ロジックで処理したものです。1年1本を基本に、入手できる最も古いダンプまで 遡っています。2012年・2013年はダンプがどこにも残っておらず欠番で、英語版は2011年から 2013年も同じ理由で作れていません。
- ダンプのリンクは実際に取得できる場所を指しています(公式・Internet Archive・torrent・
gs://isbn-citationに置いた控えのいずれか) - 2011年以前のダンプは記事以外の名前空間も含みます(KNOWN_ISSUES.md の25番)
- 旧ロジックで生成した出力は
gs://isbn-citation/archive/に退避してあります
公式サイトは直近数か月分のダンプしか置いていないため、過去のダンプは別の場所から取る。 年次シリーズの対象と取得元は
tools/backfill.py にまとめてある。
# 対象と手元の状態を一覧する
uv run python tools/backfill.py list
# 取得(md5照合まで)→ 抽出 → 件数の記録
uv run python tools/backfill.py run --wiki jawiki
# ダウンロードと抽出を並走させる場合(抽出は取得できたものから順に処理する)
uv run python tools/backfill.py fetch --wiki enwiki -j 3
uv run python tools/backfill.py extract --watch| 取得元 | 残っている範囲 |
|---|---|
| dumps.wikimedia.org | 直近5〜7か月分 |
| Internet Archive | jawiki・enwikiとも2014年11月〜2022年5月がほぼ毎月。ほかにjawikiの2011年、enwikiの2008〜2010年 |
| 公式のヒストリカルアーカイブ | enwikiの20080103と20100312(pages-articles) |
| people.wikimedia.org/~samtar | 20230820の全言語版のtorrent。ミラーが全滅した2023年を埋められる唯一の経路 |
gs://isbn-citation |
上のどこにも残っていないダンプの控え(jawikiの2019年〜、enwikiの2023年〜) |
Internet Archive のミラーは2022年5月で止まっているため、2012年・2013年のダンプはどこにも
残っておらず再処理できない(英語版は2011年も入手できない)。2011年以前のダンプは
multistream が無いため逐次処理になり、<ns> を持たないため記事以外の名前空間も混ざる
(KNOWN_ISSUES.md の25番)。
2023年はHTTPで取れるミラーが1つも残っていない。torrent内のweb seedも3ミラーとも404になるため、 BitTorrentのピアから取るしかない。Meta-Wikiの Data dump torrents には英語版しか 載っていないが、同じ配布元のディレクトリに20230820の全言語版が置かれている。
kind="torrent" の対象は aria2
(Windowsならzipを展開するだけ)で取得する。
ARIA2C=/path/to/aria2c.exe uv run python tools/backfill.py fetch --date 20230820公式のmd5sums.txtも消えているため、照合できるのはtorrent内のピースハッシュだけになる。 aria2cが全ピースを検証したら照合済みとして扱い、抽出後の件数が前後の年の間に収まるかで 妥当性を確かめている。
公式は数か月でダンプを消し、Internet Archive のミラーも止まっているため、 新しく処理した ダンプはどこにも残らない。実際に jawiki-20190420 から 20200801 までは公式もIAも消えており、 このバケットに置いた控えだけが残っている。そのため次の基準で控えを置く。
- 置く: 他に現存するコピーが無いもの(jawikiの2019年以降、enwikiの2024年以降)。 処理した直後に上げる。上げ忘れるとその日付は二度と再処理できなくなる
- 置かない: Internet Archive にあるもの(2008〜2022年)。
tools/backfill.pyが md5照合付きで取り直せるので、同じものを二重に持たない
バケットのライフサイクルで30日後にNearline、100日後にArchiveへ落ちる。 旧ロジックで生成した出力は archive/ に退避してある(
archive/NOTE.txt に違いを記載)。
- チェックデジットの一致により、ISBN以外を誤判定する場合があります。ただし、ISBNから参照記事を検索する目的では問題とならないため許容しています
- チェックデジット間違いのISBNは抽出されません
- 抽出精度に関する未対応の問題は KNOWN_ISSUES.md にまとめてあります
- 抽出結果が変わる変更は CHANGELOG.md に記録しています。過去のデータと比較する場合はバージョンを揃えてください
uv sync
uv run pytest
uv run ruff check && uv run ruff format --checktests/golden/ には現行実装の出力を固定したファイルを置いてある。抽出ロジックを変更すると ここに差分が出るので、意図した変更かどうかを確認すること。
slow マーカーのテストは実ダンプから切り出したフィクスチャ(3,000ページ)を使う。 手元で動かす場合は先に生成する。
uv run python tests/fixtures/make_fixture.py jawiki-20260401-pages-articles-multistream.xml.bz2
uv run pytest -m slow