このプロジェクトについて
e-Stat・日本銀行・財務省・世界銀行・IMF・OECDなど官公庁・国際機関の統計データを自動収集・加工し、マクロ経済ダッシュボードとして公開している個人開発プロジェクトです。
公開サイトはこちら →
https://japandata.happy-life-design.net
前回の記事はこちら →
https://qiita.com/rightcross-ae86/items/b575061b9e3bcedaaca1
現在の規模: 929指標・28データソース
見つかった問題
取得先の不調が続いていた2件に着手しました。1件目は農林水産省(maff)の食料自給率データで、毎日エラーが出続けていました。2件目は世界銀行(World Bank)のデータ取得で、更新頻度に対して取得量が過剰でした。
調査①: 取得先ページの恒久的な消滅と、隠れていた行ズレ
maffのエラーを調べたところ、一時的なアクセス制限ではなく、取得先ページ自体が恒久的に無くなっていました。ブラウザ用のヘッダーを付けても結果は同じで、アクセス制限による403ではないと確認しました。現在の該当ページを探したところ、移動先が見つかり、そこから最新年度分のファイルを取得できました。
ここで、新しいファイルでは行構成そのものが変わっていることに気づきました。新しい指標が1行分挿入されており、それ以降の指標が軒並み1行ずつズレていたのです。
気づかずにURLだけ張り替えていた場合、「飼料自給率」という指標に、本来は別の指標である「摂取熱量ベースの食料自給率」の値(2025年度で45%)が、エラーも警告も出ないまま入れ替わるところでした(正しい飼料自給率は24%)。
対応①: 行番号だけでなく見出しの文字も照合する
指標を取得する行番号を、あらかじめ登録しておいた見出し文字と突き合わせて検証する仕組みをparsers/maff_parser.pyに追加しました。一致しなければその場でエラーとして取り込みを止めます。
def _row_label(ws, row: int) -> str:
"""該当行の左側の文字列セルを連結して行ラベルを作る
Excelのセル結合により「品」「目」「別」等の縦書き見出しが左列に混ざるため、
先頭4列を連結した上で空白・改行を除去した文字列を返す。
"""
parts = []
for c in range(0, min(4, ws.ncols)):
v = ws.cell_value(row, c)
if isinstance(v, str) and v.strip():
parts.append(v)
return "".join(parts).replace(" ", "").replace(" ", "").replace("\n", "")
# 行ラベル検証: 取得先の改編で行がずれた場合に、黙って別系列を取り込むのを防ぐ
expected = spec.get("label")
if expected:
actual = _row_label(ws, target_row)
if expected.replace(" ", "").replace(" ", "") not in actual:
logger.error(
"row %d のラベル不一致(期待='%s' 実際='%s')。"
"元ファイルの行構成が変わった可能性があるため取り込みを中止します",
target_row, expected, actual[:40],
)
return 0, 1
新しいファイルでは15指標すべてで見出しの一致を確認したうえで取り込みました。逆に、ズレる前の旧ファイルに新しい行番号を当てると、ズレた3指標だけが狙いどおり不一致として弾かれることも確認しています。
調査②: 更新頻度に対して過剰だった外部API取得
世界銀行の統計データ取得も見直しました。従来は121指標すべてを毎日「直近60年分」丸ごと取得し直しており、実際の更新頻度に対して取得量が過剰でした。
対応②: 日次は直近2年分、月初のみ全期間を取得
平日は直近2年分の差分のみを取得し、月初(1日)だけ全期間を取得し直す方式に変更しました。変更前に、対象の116通り(国×指標の組み合わせ)全てで、直近2年分だけの取得でも値の取りこぼしが無いかを実測で確認しています(取得できなかった2通りは、60年分を取得しても元々データが存在しない指標でした)。
結果
本番実行での実測値です。
| 指標 | 変更前 | 変更後 |
|---|---|---|
| DB書き込み行数/日 | 5,335行 | 621行(-88%) |
| 該当ステップの所要時間 | 2分12秒 | 1分07秒(-49%) |
まとめ
外部サイトの改編は、エラーになってくれれば気づけます。しかし今回のように形式を保ったまま中身の並びだけがズレると、何のシグナルも出ないまま別のデータに置き換わってしまいます。件数やエラーの有無だけでなく、内容そのものを照合する仕組みを組み込むことの大切さを再確認しました。あわせて、外部APIへの依存を必要な分だけに絞る見直しもできました。気になる点・ご質問があればコメントでお知らせください。