0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

e-StatのAPIを使ってデータを取得しCSVファイルに保存する方法

Posted at

この記事で共有したいこと

すでにe-StatのAPIに関する記事はいくつか投稿されているのですが、まだAPIなどに詳しくない身としては、どうすればいいのか分からない部分がありました。そこでこの記事では、私がGeminiを使いながら模索して見つけた「こうすればなんとか分析に使えるデータを用意できるやり方」を皆さんと共有したいと思います。

準備するもの

  • e-Statのユーザー登録
  • e-Statで作成したアプリケーションID

これらの紹介は政府統計の総合窓口(e-Stat)のAPIを使ってみようの記事冒頭にあります。用意するのに10分もかからないと思います。

加えて、e-Statで取得できるAPIのURLが必要です。

スクリーンショット 2025-03-14 090543.png

スクリーンショット 2025-03-14 090650.png

Pythonモジュールの実装

ここからはGoogle Colabで実行した様子を紹介します。
モジュール実装のプログラムはPythonでe-Stat APIを使うの記事にあるものをそのまま使います。

スクリーンショット 2025-03-14 091752.png
まずはGoogle Drive上でプログラムを実行できるように準備します。過去の記事(e-Statの活用例①)で紹介しているの参考にしてみてください。

次のセルでモジュールを実装します。以下のプログラムをコピペして自身のアプリケーションIDを入力してください。

sample.py
import urllib
import requests


class EstatRestApiClient:
    """
    This is a simple python module class for e-Stat API (ver.3.0).
    See more details at https://www.e-stat.go.jp/api/api-info/e-stat-manual3-0
    """

    def __init__(self, api_version=None, app_id=None):
        # base url
        self.base_url = "https://api.e-stat.go.jp/rest"

        # e-Stat REST API Version
        if api_version is None:
            self.api_version = "3.0"
        else:
            self.api_version = api_version

        # Application ID
        if app_id is None:
            self.app_id = "****************" # ここにアプリケーションIDをいれる
        else:
            self.app_id = app_id

    def getStatsList(self, params_dict, format="csv"):
        """
        2.1 統計表情報取得 (HTTP GET)
        """
        params_str = urllib.parse.urlencode(params_dict)
        if format == "xml":
            url = (
                f"{self.base_url}/{self.api_version}"
                f"/app/getStatsList?{params_str}"
            )
        elif format == "json":
            url = (
                f"{self.base_url}/{self.api_version}"
                f"/app/json/getStatsList?{params_str}"
            )
        elif format == "jsonp":
            url = (
                f"{self.base_url}/{self.api_version}"
                f"/app/jsonp/getStatsList?{params_str}"
            )
        elif format == "csv":
            url = (
                f"{self.base_url}/{self.api_version}"
                f"/app/getSimpleStatsList?{params_str}"
            )
        return url

    def getMetaInfoURL(self, params_dict, format="csv"):
        """
        2.2 メタ情報取得 (HTTP GET)
        """
        params_str = urllib.parse.urlencode(params_dict)
        if format == "xml":
            url = (
                f"{self.base_url}/{self.api_version}"
                f"/app/getMetaInfo?{params_str}"
            )
        elif format == "json":
            url = (
                f"{self.base_url}/{self.api_version}"
                f"/app/json/getMetaInfo?{params_str}"
            )
        elif format == "jsonp":
            url = (
                f"{self.base_url}/{self.api_version}"
                f"/app/jsonp/getMetaInfo?{params_str}"
            )
        elif format == "csv":
            url = (
                f"{self.base_url}/{self.api_version}"
                f"/app/getSimpleMetaInfo?{params_str}"
            )
        return url

    def getStatsDataURL(self, params_dict, format="csv"):
        """
        2.3 統計データ取得 (HTTP GET)
        """
        params_str = urllib.parse.urlencode(params_dict)
        if format == "xml":
            url = (
                f"{self.base_url}/{self.api_version}"
                f"/app/getStatsData?{params_str}"
            )
        elif format == "json":
            url = (
                f"{self.base_url}/{self.api_version}"
                f"/app/json/getStatsData?{params_str}"
            )
        elif format == "jsonp":
            url = (
                f"{self.base_url}/{self.api_version}"
                f"/app/jsonp/getStatsData?{params_str}"
            )
        elif format == "csv":
            url = (
                f"{self.base_url}/{self.api_version}"
                f"/app/getSimpleStatsData?{params_str}"
            )
        return url

    def postDatasetURL(self):
        """
        2.4 データセット登録 (HTTP POST)
        """
        url = (
            f"{self.base_url}/{self.api_version}"
            "/app/postDataset"
        )
        return url

    def refDataset(self, params_dict, format="xml"):
        """
        2.5 データセット参照 (HTTP GET)
        """
        params_str = urllib.parse.urlencode(params_dict)
        if format == "xml":
            url = (
                f"{self.base_url}/{self.api_version}"
                + f"/app/refDataset?{params_str}"
            )
        elif format == "json":
            url = (
                f"{self.base_url}/{self.api_version}"
                f"/app/json/refDataset?{params_str}"
            )
        elif format == "jsonp":
            url = (
                f"{self.base_url}/{self.api_version}"
                f"/app/jsonp/refDataset?{params_str}"
            )
        return url

    def getDataCatalogURL(self, params_dict, format="xml"):
        """
        2.6 データカタログ情報取得 (HTTP GET)
        """
        params_str = urllib.parse.urlencode(params_dict)
        if format == "xml":
            url = (
                f"{self.base_url}/{self.api_version}"
                f"/app/getDataCatalog?{params_str}"
            )
        elif format == "json":
            url = (
                f"{self.base_url}/{self.api_version}"
                f"/app/json/getDataCatalog?{params_str}"
            )
        elif format == "jsonp":
            url = (
                f"{self.base_url}/{self.api_version}"
                f"/app/jsonp/getDataCatalog?{params_str}"
            )
        return url

    def getStatsDatasURL(self, params_dict, format="xml"):
        """
        2.7 統計データ一括取得 (HTTP GET)
        """
        params_str = urllib.parse.urlencode(params_dict)
        if format == "xml":
            url = (
                f"{self.base_url}/{self.api_version}"
                f"/app/getStatsDatas?{params_str}"
            )
        elif format == "json":
            url = (
                f"{self.base_url}/{self.api_version}"
                f"/app/json/getStatsDatas?{params_str}"
            )
        elif format == "csv":
            url = (
                f"{self.base_url}/{self.api_version}"
                f"/app/getSimpleStatsDatas?{params_str}"
            )
        return url

スクリーンショット 2025-03-14 092738.png

次のセルでデータをCSVファイルに保存するところまで行きます。
使うプログラムは以下のものです。

sample
import requests
import csv
import io # 文字列をファイルのように扱うために使用

# EstatRestApiClientのインスタンスを作成
client = EstatRestApiClient(app_id='****************')# ここにアプリケーションIDをいれる

# パラメータを定義
# cntGetFlgを"Y"に設定
params = {
    "statsDataId": "0003005798",  # 統計データID
    "lang": "J",
    "metaGetFlg": "Y",
    "cntGetFlg": "Y",  # データコンテンツを取得するように設定
    "explanationGetFlg": "Y",
    "annotationGetFlg": "Y",
    "sectionHeaderFlg": "1",
    "replaceSpChars": "0",
    "appId": client.app_id # app_idをパラメータに追加
    # ... other parameters ...
}

# getStatsDataURLを使ってCSV形式でデータを取得するURLを取得
url = client.getStatsDataURL(params, format="csv")

# APIリクエストを送信
response = requests.get(url)

# レスポンスの確認
if response.status_code == 200:
    # レスポンスボディをCSVデータとして読み込む
    csv_data = response.content.decode('utf-8') # utf-8でデコード

    # ファイルに書き込む
    with open('estat_data.csv', 'w', encoding='utf-8', newline='') as f:
        writer = csv.writer(f)
        reader = csv.reader(csv_data.splitlines()) # splitlines()で文字列を行に分割
        for row in reader:
            writer.writerow(row)

    print("CSVファイル 'estat_data.csv' が保存されました。")
else:
    print(f"Error: {response.status_code}")

このプログラムの中に「パラメータ定義」があり、そこで先ほど取得したURLを使います。URLはコピーしたものをそのまま使うのではなく、

http://api.e-stat.go.jp/rest/3.0/app/getSimpleStatsData?appId=&lang=J&statsDataId=0003005798&metaGetFlg=Y&cntGetFlg=N&explanationGetFlg=Y&annotationGetFlg=Y&sectionHeaderFlg=1&replaceSpChars=0

lang以降の文字について切り取りながら、パラメータ定義に書き込んでいきます。パラメータは&で区切られているので、それを頼りに上記の形式に合わせながら書き込んでください。

私が試したときはパラメータ定義の中にアプリケーションIDがないとエラーが出たため最後の方に書き加えています。

スクリーンショット 2025-03-14 093927.png

スクリーンショット 2025-03-14 094023.png

成功すればこのように、フォルダにCSVファイルが作成されます。
CSVファイルの中身は以下のようになります。

スクリーンショット 2025-03-14 094219.png

ここまでできればpandasを使って分析準備まで持っていけると思います。作成したCSVファイルを見ると、メタ情報が入っています。APIでデータを取得する際にメタ情報は取得しないようにすれば以降の操作が楽になるかもしれません。

おわりに

今回は、使えるデータをAPIで取得すること優先に試したことを紹介しました。プログラムについてはGeminiに相談しながら書いたため間違っているところがあるかもしれません。間違いに気づいた方はコメントしてくださるととても助かります。
ここまで読んでくださりありがとうございました。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?