本文へスキップ

e-Gov法令API v2をPythonで使う:法令検索・本文保存とBase64復号

e-Gov法令API v2をPythonの標準ライブラリで呼び出す実践ガイド。法令名からIDを探し、asofで時点を指定してJSON・XMLを保存します。Base64の復号、2時点比較、MCP向け1条のJSON化まで、実行確認済みのダウンロード用コード付きで解説します。

SHAYOUWORLD 更新 約8分

広告:この記事には楽天アフィリエイトの購入リンクがあります。リンク経由の購入により運営者が紹介料を受け取る場合があります。

e-Gov法令API v2をPythonで使うなら、lawsで法令IDを調べ、選んだIDでlaw_dataを呼び出すと、検索と本文取得を分けて確認できます。この記事では、標準ライブラリだけで動くスクリプトを使い、法令名の検索からJSON・XMLの保存まで進めます。

特に気をつけたいのは本文の形式です。レスポンス全体をJSON、本文をXMLにすると、law_full_textはBase64文字列で返ります。そのままXMLパーサーへ渡すと失敗するため、復号を挟みます。2026年9月26日に検索と2時点比較を実APIで再確認し、保存後に1条をJSONへ取り出す機能を追加しました。単独取得・ページ送りの旧記録には、2026年9月6日と明記しています。

濃紺と青緑の書籍を積み、透明なガラスを配した明るい机上の静物画像
公開資料をプログラムから扱う記事のためにComfyUIで生成したイメージ。行政機関の設備や実際のAPI画面の写真ではありません。

まず動かす:検索して、法令IDを選ぶ

Pythonを導入済みで、法令データを小さな検証プログラムやMCPへ取り込みたい人向けです。MCPの接続設定より先に、API単体の応答を確かめられます。

Pythonサンプルをダウンロードする。保存したフォルダーで、次の2行を実行します。外部パッケージの追加は不要です。Windowsではpythonが見つからない場合、導入環境に合わせてpyへ置き換えてください。

Terminal window
python --version
python egov-law-api-v2.py search "労働基準法" --limit 3

今回の環境はPython 3.10.11です。サンプルの対象はPython 3.10以降で、APIキーは指定していません。検索時は候補を表示するだけで、先頭の法令の本文を勝手に取得しない作りにしています。

2026年9月26日の検索結果の先頭部分です。件数は取得時の値であり、固定の期待値ではありません。

count=3 total_count=11 next_offset=3
322AC0000000049 労働基準法
322M40000100023 労働基準法施行規則

この例で取得したいのは労働基準法なので、ID 322AC0000000049 を選びます。タイトルが似ていても本法、施行規則、関連する政令は別の資料です。名称を読まずに検索の先頭1件を採用する処理は避けましょう。

同じ検索をcurlで確認する

Pythonでうまくいかないときは、同じ条件をcurlで確認すると切り分けられます。次は1行のコマンドです。Windows PowerShellではcurl.exeを使うと、別のコマンドへのエイリアスを避けられます。

Terminal window
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を渡すと、本文とメタデータを取得します。

Terminal window
python egov-law-api-v2.py get 322AC0000000049

実行したフォルダーのegov-resultsに、日時を含む名前で2ファイルを保存します。

ファイル保存する内容後から確認すること
get-日時.json取得日時、リクエストURL、指定日、APIの応答全体どの条件で取得したか、法令IDと履歴ID
get-日時.xmlAPIの本文をBase64復号したバイト列条・項・号などの構造、原文への対応

JSON側のresponseには、APIが返した値をそのまま保持します。したがって、その中のlaw_full_textはBase64のままです。XML側は閲覧・解析用に復号した別ファイルで、両者の役割を分けています。

保存先を指定したい場合は、共通オプションの --out を、get や search より前に置きます。

Terminal window
python egov-law-api-v2.py --out "egov-check" get 322AC0000000049

サンプルは15文字の法令IDだけを受け付け、法令番号や履歴IDを誤って渡すと通信前に停止します。既存ファイルの上書きを避けるため、日時入りファイルを新規作成します。ネットワーク接続には30秒のタイムアウトを設定しています。これはサンプル側の設定値で、APIが応答時間を保証するという意味ではありません。

Base64の落とし穴:response_formatと本文形式は別

今回の本文取得では、次の2つを指定しています。

response_format=json
law_full_text_format=xml

外側のレスポンスと中の法令本文は、別々に形式を選べます。公式OpenAPI仕様にも、両者の形式が異なる場合は本文をBase64で返すと説明されています。

外側の指定本文の指定本文を読む処理
jsonxmlJSONを解析 → law_full_textをBase64復号 → XMLを解析
jsonjsonJSONを解析 → law_full_textの構造を確認

この記事で実行確認したのは1行目の組み合わせです。法令本文のJSON形式は公式仕様上、試行版の扱いがあるため、構造を前提に実装する場合は仕様の変更に備えてください。

配布コードの要点は、この部分です。

import base64
import 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日時点の本文を取得する例です。

Terminal window
python egov-law-api-v2.py get 322AC0000000049 --asof 2025-06-01

2026年9月6日の実行では、同じ法令IDから次の履歴IDが返りました。これは取得記録であり、法令の改正内容を比較・解釈した結果ではありません。

取得条件応答のlaw_revision_id
asof=2025-06-01322AC0000000049_20250601_504AC0000000068
asofなし322AC0000000049_20260717_508AC0000000060

保存JSONでは、リクエストURLとrequested_asofのほかに、応答のrevision_info.law_revision_idを確認します。指定日だけをメモするより、返ってきた版を追いやすくなります。

法令履歴IDをURLのパスに指定すると、asofは無視されます。 日付を変えて取り比べるときは、この例のように法令IDを使います。時点指定の背景や別の取得例は、asofで過去の条文を取得する記事で詳しく扱っています。

2つの日付の版をまとめて保存する

compareは、同じ法令IDへ日付を2つ指定してAPIを呼び出します。日付を省略した「現在」を比較先にせず、両方を固定して再実行できるようにしています。

Terminal window
python egov-law-api-v2.py --out results compare 331AC0000000120 --before 2025-06-01 --after 2026-01-01

2026年9月26日の実行では次の結果でした。

before: 331AC0000000120_20250523_507AC0000000041
after: 331AC0000000120_20260101_507AC0000000041
same_revision: false
same_xml_bytes: false

日時付きフォルダーへ、before.json・before.xml・after.json・after.xml・xml.diff・comparison.jsonを保存します。両応答の検証後に保存を始め、完了を示すcomparison.jsonは最後に書きます。失敗時に要約ファイルのないフォルダーが残ったら、保存先の権限・空き容量を確認して別フォルダーで再実行してください。

実測記録JSONには取得日時・URL・原文のSHA-256を残しています。差分はXML表現の変化であり、法的な改正内容を判定したものではありません。履歴IDと本文の差を分けて見る方法は、asofによる2時点比較で説明しています。

保存した1条を、通信せずにJSONへ取り出す

compare-実行日時を、実行時に表示されたフォルダー名へ置き換えます。

Terminal window
python egov-law-api-v2.py --out results excerpt results/compare-実行日時/after.json --article 1

excerptはAPIを呼ばず、保存済みJSONから本則の第1条を抽出します。条・項・号の要素順や属性を残したJSONに、指定日・履歴ID・原文URLを付けます。これは独立した変換CLIで、MCP接続は行いません。

APIを使う前に試す場合は、架空の入力JSONを同じフォルダーに保存して、次を実行してください。

Terminal window
python egov-law-api-v2.py --out results excerpt egov-law-example-fixture.json --article 1

FIXTUREを含む結果は実在の法令ではありません。XMLをMCP向けJSONへ変換する記事で、出力構造、本則と附則の指定、枝番号、存在しない条のエラーを確認できます。READMEとMITライセンスも配布しています。

検索結果の続きはnext_offsetを見る

最初の検索で返ったcount=3は今回のページに入った件数です。total_count=11は条件に合った全件数で、続きがあることをnext_offset=3から確認できます。

Terminal window
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検証を無効にする変更で済ませず、環境を確認する
ARTICLE_NOT_FOUND指定版のNumと本則/附則XMLを開いて番号を確認。存在しない条を推測しない
12 MiB超過小さなサンプルの応答・入力上限必要範囲を絞る設計や公式の一括配布を検討
保存した日本語が読みにくいファイルとターミナルの文字コードJSONはUTF-8で保存されるため、UTF-8対応エディターで開く

ダウンロード用コードはHTTPエラーや解析失敗を成功扱いせず、終了コード1で止まります。自動リトライも行いません。urllib.requestの公式ドキュメントで通信処理を、urllib.parseの公式ドキュメントで日本語やIDをURLに組み込む処理を確認できます。

取得した本文をMCPへ渡す前に

まず保存したXMLを開き、対象の法令・版を人間が確認します。その後、上記のexcerptで必要な条だけを取り出し、法令ID、履歴ID、原文参照と一緒に返す形へ進めます。リクエストを組み立て直す場合は、APIリクエスト作成ツールでURLやcurlを確認できます。

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用の変換へ進めます。

Pythonの基礎から学び直す場合の参考書

このサンプルを動かすために、書籍の購入は必要ありません。JSONやXMLの関数を調べたい場合は、Python公式のJSON・XMLの説明から確認できます。ほかの言語でプログラミングの経験がある方には、公式チュートリアルも参考になります。利用中のPythonの版に対応するドキュメントを選んでください。

この記事の情報・検証メモ
Tags
公開日
情報確認
参考リンク
6件
更新性
定期更新
更新管理

仕様・料金・提供範囲が変わりやすいテーマは、公開日・更新日・情報確認日を分けて管理します。 導入前には必ず記事末尾の一次情報と公式ドキュメントで最新状況を確認してください。

検証メモ
Windows / Python 3.10.11 e-Gov法令API v2 / OpenAPI 2.1.139 2026-09-26に検索・2時点比較・保存JSONから1条抽出を実行 単独get・ページ送りの旧記録は2026-09-06
図解を保存・共有

記事の要点を1枚にまとめました。画像は新しいタブで開いて保存できます。

e-Gov法令API v2をPythonで使う:法令検索・本文保存とBase64復号 検索してIDを選び、時点を決めて本文と出典を残す 検索する:法令名で候補を3件表示。本法と施行規則のIDを見分ける。続きはnext_offsetを確認。 本文を保存する:選んだ法令IDでlaw_dataを呼ぶ。過去時点はasofで指定。JSON内のXMLはBase64を復号。 検証して使う:取得URL・日時・履歴IDを保存。復号したXMLをパースして確認。確認した原文からMCP用の型へ。
e-Gov法令API v2をPythonで使う:法令検索・本文保存とBase64復号 記事の要約 2026.09.06 実装・公開事例
Primary sources

一次情報・参考リンク

About the author
SHAYOUWORLD

日本の公共データAPIを使うMCPサーバーを作って公開し、ローカルLLMを自分のGPUで測った記録を、一次情報・検証ログ・失敗例とあわせて整理します。