公共CSV、配り方で差がつくよね?HTTPとフォーマットで見るオープンデータ最適化

IT政策の提案
公共CSV、配り方で差がつくよね?HTTPとフォーマットで見るオープンデータ最適化

どうも〜おかむーです!今日はちょっとエンジニア寄りの話で、公共データの“配り方”にフォーカスしますよ〜

  • 3行要約
- 政府・自治体が公開するCSV、配信レイヤ(HTTP)とフォーマット選びで使い勝手が劇的に変わる!

- HEAD/HEAD的なチェックで「圧縮・キャッシュ・範囲取得」が設定されているかすぐ分かる。コード例付き!

- 解決策は「オブジェクトストレージ+CDN+ストリーミング向けフォーマット(ndjson/parquet)」の組合せで現実的に導入可能。

結論

公共データはただ公開すればOKじゃないんです。エンジニア的に言うと、HTTPヘッダとファイルフォーマットが“API感”を左右します。軽量な改善(gzip、Cache-Control、Accept-Ranges)から、データフォーマットの切替(ndjson/parquet)まで組み合わせれば、利活用のハードルがグッと下がりますよね。

レポート本文

これ見てくださいよ:現場の実例

以下は実際に公開されているCSVの例です。

  • https://notice.go.jp/docs/status_notice.csv
  • https://www.jinji.go.jp/content/900024615.csv
  • https://www.env.go.jp/content/900398071.csv
  • https://www.mhlw.go.jp/content/001682075.csv

エンジニア的に言うと、まずはHTTPレイヤをチェックしましょう。これで多くの問題が見つかります。

1) ヘッダ確認(すぐできる)

# ヘッダだけ見る

curl -I https://notice.go.jp/docs/status_notice.csv

実体とヘッダを確認

curl -s -D - https://www.env.go.jp/content/900398071.csv -o /dev/null

見るべきヘッダ:Content-Type, Content-Encoding, Content-Length, Cache-Control, ETag/Last-Modified, Accept-Ranges

要するに:これで「圧縮されてる?キャッシュ効く?部分取得できる?」が分かるということです。

2) よくある問題点

  • 圧縮なし(Content-Encoding: gzip がない)→ 転送が遅い
  • Cache-Control未設定→ 同じファイルに複数アクセスが行くたび負荷増
  • Accept-Rangesなし→ 大きいCSVの範囲取得や並列ダウンロードができない
  • Content-Typeが汚い(text/plain)→ 自動判定が怪しくなる

3) フォーマットの話:CSVは万能じゃない

CSVは人に優しいけど、ストリーミングと解析性の観点で弱点あり。

  • ndjson(JSON Lines):ストリーミング処理に強い。行単位でパース可能
  • Parquet/Arrow:カラムナ形式で大規模分析や列選択が速い(ただしバイナリ)

エンジニア的に言うと、API一本で解決する話なんですよね:小さなCSVはそのまま、重い・頻繁アクセスされるデータはParquetに変えてCDNで配ると最高です。

4) 実践コード例:ヘッダチェック+ストリーミング処理

PythonでAccept-Rangesや圧縮、行数をチェックする例:

import requests

url = 'https://notice.go.jp/docs/status_notice.csv'

r = requests.head(url, timeout=5)

print(r.headers.get('Content-Encoding'), r.headers.get('Cache-Control'), r.headers.get('Accept-Ranges'))

ストリーミングで先頭100行だけ見る

with requests.get(url, stream=True) as r:

for i, line in enumerate(r.iter_lines(decode_unicode=True)):

print(line)

if i>99: break

データ変換の例(CSV→Parquet):

import pandas as pd

import pyarrow as pa

import pyarrow.parquet as pq

for chunk in pd.read_csv(url, chunksize=100000):

table = pa.Table.from_pandas(chunk)

pq.write_table(table, 'out.parquet', compression='snappy')

政策運用の観点:コストとガバナンス

  • 小さな自治体サイトが大きなCSVを直接配るとアクセス集中で落ちるリスクあり
  • オブジェクトストレージ(S3互換)+CDNを使えば可用性と帯域を安く確保可能
  • バージョンはファイル名で管理(v2026-04-15.csv)か、HTTPのETag/Last-Modifiedを確実に出す

改善提案(実務レシピ)

  • まずHEADチェックを自動化:GitHub Actionsで毎日curl -Iを回す
  • 圧縮を有効化:サーバ側でgzip圧縮またはParquet配布
  • Cache-Control: public, max-age=86400, s-maxage=604800を設定
  • Accept-Ranges: bytesを有効化して大きいファイルは部分取得可能に
  • 大規模データはParquetで配布、利用者向けにndjsonやCSVのスライス提供
  • 公式に「配信ポリシー(Delivery Policy)」を公開しておくと、利用者が最適化できる
  • まとめ

    • 単純にファイルを置くだけだと利用性が下がる!HTTPヘッダとフォーマットが重要
    • 小さな改善(gzip, cache, ranges)で体感速度がぜんぜん変わる
    • 大量データはParquet/CDNへの移行が現実的で、ndjsonはストリーミング用途に最適

    おかむーから一言

    オープンデータって技術的にはそこまで難しくないんです。適切な配信レイヤを整えるだけで、データが一気に“使える”ものになります。テクノロジーで社会を一段上に引き上げましょう!

    シェアする