e-Gov法令API v2をPythonで使う:法令検索・本文保存とBase64復号
e-Gov法令API v2をPythonの標準ライブラリで呼び出す実践ガイド。法令名からIDを探し、asofで時点を指定してJSON・XMLを保存します。Base64の復号、ページ送り、エラー対応まで、実行確認済みのダウンロード用コード付きで解説します。
e-Gov法令API v2をPythonで使うなら、lawsで法令IDを調べ、選んだIDでlaw_dataを呼び出すと、検索と本文取得を分けて確認できます。この記事では、標準ライブラリだけで動くスクリプトを使い、法令名の検索からJSON・XMLの保存まで進めます。
特に気をつけたいのは本文の形式です。レスポンス全体をJSON、本文をXMLにすると、law_full_textはBase64文字列で返ります。そのままXMLパーサーへ渡すと失敗するため、復号を挟みます。以下はこの組み合わせを含めて、2026年9月6日に実際のAPIで確認した手順です。

まず動かす:検索して、法令IDを選ぶ
Pythonを導入済みで、法令データを小さな検証プログラムやMCPへ取り込みたい人向けです。MCPの接続設定より先に、API単体の応答を確かめられます。
Pythonサンプルをダウンロードする。保存したフォルダーで、次の2行を実行します。外部パッケージの追加は不要です。Windowsではpythonが見つからない場合、導入環境に合わせてpyへ置き換えてください。
python --versionpython egov-law-api-v2.py search "労働基準法" --limit 3今回の環境はPython 3.10.11です。サンプルの対象はPython 3.10以降で、APIキーは指定していません。検索時は候補を表示するだけで、先頭の法令の本文を勝手に取得しない作りにしています。
実行時の先頭部分は次のとおりでした。件数は取得時の値であり、固定の期待値ではありません。
count=3 total_count=11 next_offset=3322AC0000000049 労働基準法322M40000100023 労働基準法施行規則この例で取得したいのは労働基準法なので、ID 322AC0000000049 を選びます。タイトルが似ていても本法、施行規則、関連する政令は別の資料です。名称を読まずに検索の先頭1件を採用する処理は避けましょう。
同じ検索をcurlで確認する
Pythonでうまくいかないときは、同じ条件をcurlで確認すると切り分けられます。次は1行のコマンドです。Windows PowerShellではcurl.exeを使うと、別のコマンドへのエイリアスを避けられます。
curl.exe --get "https://laws.e-gov.go.jp/api/2/laws" --data-urlencode "law_title=労働基準法" --data-urlencode "limit=3" --data-urlencode "response_format=json"law_titleは法令名を探す条件です。API全体の入口やパラメーターの説明はe-Govの公式仕様で確認できます。通称で見つからない場合は、法令名・通称・改題の違いも確認してください。
本文を取得し、JSONとXMLを保存する
選んだ法令IDを渡すと、本文とメタデータを取得します。
python egov-law-api-v2.py get 322AC0000000049実行したフォルダーのegov-resultsに、日時を含む名前で2ファイルを保存します。
| ファイル | 保存する内容 | 後から確認すること |
|---|---|---|
get-日時.json | 取得日時、リクエストURL、指定日、APIの応答全体 | どの条件で取得したか、法令IDと履歴ID |
get-日時.xml | APIの本文をBase64復号したバイト列 | 条・項・号などの構造、原文への対応 |
JSON側のresponseには、APIが返した値をそのまま保持します。したがって、その中のlaw_full_textはBase64のままです。XML側は閲覧・解析用に復号した別ファイルで、両者の役割を分けています。
保存先を指定したい場合は、共通オプションの--outを**getやsearchより前**に置きます。
python egov-law-api-v2.py --out "egov-check" get 322AC0000000049サンプルは既存ファイルの上書きを避けるため、日時入りファイルを新規作成します。ネットワーク接続には30秒のタイムアウトを設定しています。これはサンプル側の設定値で、APIが応答時間を保証するという意味ではありません。
Base64の落とし穴:response_formatと本文形式は別
今回の本文取得では、次の2つを指定しています。
response_format=jsonlaw_full_text_format=xml外側のレスポンスと中の法令本文は、別々に形式を選べます。公式OpenAPI仕様にも、両者の形式が異なる場合は本文をBase64で返すと説明されています。
| 外側の指定 | 本文の指定 | 本文を読む処理 |
|---|---|---|
json | xml | JSONを解析 → law_full_textをBase64復号 → XMLを解析 |
json | json | JSONを解析 → law_full_textの構造を確認 |
この記事で実行確認したのは1行目の組み合わせです。法令本文のJSON形式は公式仕様上、試行版の扱いがあるため、構造を前提に実装する場合は仕様の変更に備えてください。
配布コードの要点は、この部分です。
import base64import xml.etree.ElementTree as ET
# dataはjson.load()で解析済みのAPI応答xml_bytes = base64.b64decode(data["law_full_text"], validate=True)root = ET.fromstring(xml_bytes)validate=Trueを付け、想定外の文字列を黙って読み進めないようにしています。Pythonのbase64ドキュメントに、検証オプションの挙動が記載されています。復号した後にXMLとして解析できることを確かめてから保存します。
今回の検証でも、最初に復号を省いた状態ではParseErrorになりました。Base64復号を加えて再実行すると、指定日と現行の両方でXMLを保存できました。XMLのパースエラーが出たら、まず受信データの形式を確認するのが近道です。
過去の日付を指定する:asofと履歴ID
2025年6月1日時点の本文を取得する例です。
python egov-law-api-v2.py get 322AC0000000049 --asof 2025-06-012026年9月6日の実行では、同じ法令IDから次の履歴IDが返りました。これは取得記録であり、法令の改正内容を比較・解釈した結果ではありません。
| 取得条件 | 応答のlaw_revision_id |
|---|---|
asof=2025-06-01 | 322AC0000000049_20250601_504AC0000000068 |
asofなし | 322AC0000000049_20260717_508AC0000000060 |
保存JSONでは、リクエストURLとrequested_asofのほかに、応答のrevision_info.law_revision_idを確認します。指定日だけをメモするより、返ってきた版を追いやすくなります。
法令履歴IDをURLのパスに指定すると、asofは無視されます。 日付を変えて取り比べるときは、この例のように法令IDを使います。時点指定の背景や別の取得例は、asofで過去の条文を取得する記事で詳しく扱っています。
検索結果の続きはnext_offsetを見る
最初の検索で返ったcount=3は今回のページに入った件数です。total_count=11は条件に合った全件数で、続きがあることをnext_offset=3から確認できます。
python egov-law-api-v2.py search "労働基準法" --limit 3 --offset 3この呼び出しでは、今回の検証でcount=3、next_offset=6が返りました。続ける場合は返却された次のオフセットを使い、nullになったら末尾です。サンプルは1回に1ページだけ取得し、自動で全件を巡回しません。
--limitの範囲を1〜20に制限しているのも、この入門用サンプルの設計です。API自体の最大件数を表す値ではありません。全法令を収集したい場合は、APIを大量に呼ぶ前に、公式仕様から案内されているXML一括ダウンロードを確認してください。
エラーが出たときに確認する場所
| 症状 | 最初に見る場所 | 対処 |
|---|---|---|
| 検索候補が0件 | law_titleの表記、通称、改題 | 正式名称でも試す。推測で別の法令へ置き換えない |
XMLでParseError | 外側と本文の形式 | JSON内のBase64文字列をXMLと誤認していないか確認 |
| HTTPエラー | URL、ID、パラメーター、公式のお知らせ | 応答コードを記録し、条件を確認してから再実行 |
| タイムアウト | 回線、プロキシ、サービス稼働状況 | 少し時間を置いて単発で確認する |
| 証明書エラー | OS・Pythonの証明書設定 | TLS検証を無効にする変更で済ませず、環境を確認する |
| 保存した日本語が読みにくい | ファイルとターミナルの文字コード | JSONはUTF-8で保存されるため、UTF-8対応エディターで開く |
ダウンロード用コードはHTTPエラーや解析失敗を成功扱いせず、終了コード1で止まります。自動リトライも行いません。urllib.requestの公式ドキュメントで通信処理を、urllib.parseの公式ドキュメントで日本語やIDをURLに組み込む処理を確認できます。
取得した本文をMCPへ渡す前に
まず保存したXMLを開き、対象の法令・版を人間が確認します。その後、必要な条項だけを取り出し、法令ID、履歴ID、原文参照と一緒に返す形へ進めます。
XMLを単純な文章1本へ潰すと、引用元の位置を追いづらくなります。次の作業は条・項・号を保持してMCP用JSONへ変換する実装例が参考になります。法令以外のデータ源を探している場合は、日本の公共データAPIの選び方から用途を比較できます。
よくある質問
このサンプルにAPIキーやrequestsのインストールは必要ですか?
今回使う検索・本文取得は、APIキーなしで実行確認しました。Python 3.10以降の標準ライブラリだけを使い、requestsやMCPサーバーのインストールは不要です。
law_full_textがPExhdyなどで始まり、XMLとして読めないのはなぜですか?
外側がJSON、本文がXMLの場合はBase64文字列になります。指定した形式を確認し、base64.b64decodeで復号してからXMLを解析してください。
過去の条文を保存するには、どの値を残しますか?
法令ID、指定日、返却された履歴ID、取得URL・日時、本文を保存します。法令履歴IDをパスへ渡す場合はasofが無視される点にも注意してください。
次に試すこと
e-Gov法令API v2とPythonの接続は、検索・ID選択・本文保存に分けると確認しやすくなります。まずダウンロード用サンプルで検索を1回実行し、目的の法令IDを選んでください。保存したJSONとXMLの対応が分かれば、時点比較やMCP用の変換へ進めます。
この記事の情報・検証メモ
- 公開日
- 情報確認
- 参考リンク
- 6件
- 更新性
- 定期更新
仕様・料金・提供範囲が変わりやすいテーマは、公開日・更新日・情報確認日を分けて管理します。 導入前には必ず記事末尾の一次情報と公式ドキュメントで最新状況を確認してください。
一次情報・参考リンク
- e-Gov法令API Version 2:エンドポイント・形式・時点指定 https://laws.e-gov.go.jp/api/2/swagger-ui/
- e-Gov法令API v2 OpenAPI仕様(確認版2.1.139) https://laws.e-gov.go.jp/api/2/swagger-ui/lawapi-v2.yaml
- Python urllib.request:HTTPリクエストとタイムアウト https://docs.python.org/3/library/urllib.request.html
- Python urllib.parse:urlencodeとquote https://docs.python.org/3/library/urllib.parse.html
- Python base64:b64decodeとvalidate https://docs.python.org/3/library/base64.html
- 法令の構造と法令標準XML https://laws.e-gov.go.jp/docs/law-data-basic/8ebd8bc-law-structure-and-xml/