LoginSignup
2
2

不動産情報ライブラリAPIから情報をGeoJSONやCSVで取得する【Python】

Last updated at Posted at 2024-04-30

不動産情報ライブラリAPIとは

不動産情報ライブラリは、不動産の取引価格、地価公示等の不動産に関する情報を閲覧・取得できる国土交通省のWEBサイトです。
2024年4月よりサービス提供が開始されました。

不動産情報ライブラリ : 公式リンク
不動産情報ライブラリAPI : 公式リンク

本記事の作成動機

不動産取引価格など有益な情報が取得できそうなこのAPIですが、リクエストの投げ方やレスポンスの形式がやや難解に感じたので、それらに対応しやすい形でデータ取得できるPythonスクリプトを書いてみました。

前準備

APIキーの取得

このAPIを利用するには、事前にAPIキーの取得申請を行う必要があります。
下記リンクから必要事項を記入して申請を行うと、数日〜1週間くらいでAPIキーが取得できます。

APIキー取得申請ページ:公式リンク

APIキーが取得できたら、後述のPythonスクリプトでデータ取得をしてみます。

Pythonによるデータ取得スクリプト

実行環境

  • MacOS 14.4.1
  • Python 3.9.6

スクリプト

Loader_MlitRealEstateInfoAPI.py
import requests
import gzip
import json
import csv

base_url = "https://www.reinfolib.mlit.go.jp/ex-api/external/" #ベースURL
api_type = "XIT001" #APIの種類を記入。後の出力ファイル名にも反映させるため変数として格納しておく。

mlit_url = base_url + api_type #リクエスト用URL
mlit_params = {"year": "2015", "area": "12"} #パラメータの設定 例:"response_format": "geojson", "z": "13", "x": "7280", "y": "3219", "from": "20223", "to": "20234"

mlit_key = input("Input your API key: ") #コマンドライン上でAPIキーの入力を求める
mlit_headers = {"Ocp-Apim-Subscription-Key": mlit_key, "Accept-Encoding": "gzip"} #APIキーをリクエストヘッダー用に格納する。gzipのレスポンスを許可する。

response = requests.get(mlit_url, headers=mlit_headers, params=mlit_params) #APIへリクエストを投げて、結果を変数に格納する

#APIからの応答に成功した場合の処理
if response.status_code == 200:
    #Content-Encodingヘッダーを確認してgzip形式であるかどうかを判断する
    if response.headers.get('Content-Encoding') == 'gzip':
        print("Response data is gzip encoded.")
        #gzip形式の場合は中身の解凍を試行する
        try:
            decoded_data = gzip.decompress(response.content) #gzipを解凍
            json_data = json.loads(decoded_data) #解凍したデータを格納
        except Exception as e:
            print("Error decoding gzip content:", e)
            json_data = response.json() #gzipの解凍にエラーが生じた場合は、レスポンス内容をそのままJSON形式で格納
    else:
        print("Response data is not gzip encoded.")
        json_data = response.json() #gzip形式でなければ、レスポンス内容をそのままJSON形式で格納
            
    #URLパラメータにおけるデータ形式の指定の仕方によって出力形式を分岐(GeoJSONかPBFか、response_formatの指定がないか)
    if "response_format" in mlit_params:
        response_format = mlit_params["response_format"].upper()
        if response_format == "GEOJSON":
            output_format = "GeoJSON" #パラメータで出力形式にGeoJSONが指定されていたらGeoJSONで出力する
        elif response_format == "PBF":
            print("Sorry, this program does not support PBF format. Output will be in GeoJSON format instead.")
            output_format = "GeoJSON" #パラメータで出力形式にPBFが指定されていたら、このプログラム上で対応できないので、代わりにGeoJSONで出力する
        else:
            print("Sorry, specified format is not supported in this program. Output will be in JSON format instead.")
            output_format = "JSON" #パラメータで不明な出力形式が指定されていたら、JSONで出力する
    else:
        output_format = input("Choose output format (JSON/CSV): ").upper() #response_formatの指定がないケースでは、出力形式をJSONかCSVで選択
    
    #選択した出力形式に応じて出力データの整形処理と保存を行う
    if output_format == "GeoJSON":
        with open("mlit_data_" + api_type + ".geojson", "w") as file:
            json.dump(json_data, file, indent=4, ensure_ascii=False) #JSON形式での文字列への変換。日本語の文字化け回避のためensure_ascii=Falseで対応。
        print("Data saved as GeoJSON successfully. Please see mlit_data_" + api_type + ".geojson")
    elif output_format == "CSV":
        headers = list(json_data["data"][0].keys()) #ヘッダー項目列の抽出
        with open("mlit_data_" + api_type + ".csv", "w", newline="", encoding="utf-8") as csvfile:
            csv_writer = csv.writer(csvfile)
            csv_writer.writerow(headers) #ヘッダー行を書き込む
            for item in json_data["data"]:
                csv_writer.writerow(item.values())
        print("Data saved as CSV successfully. Please see mlit_data_" + api_type + ".csv")
    else:
        with open("mlit_data_" + api_type + ".json", "w") as file:
            json.dump(json_data["data"], file, indent=4, ensure_ascii=False) #JSON形式での文字列への変換。日本語の文字化け回避のためensure_ascii=Falseで対応。
        print("Data saved as JSON successfully. Please see mlit_data_" + api_type + ".json")
#APIからの応答がエラーだった場合はその旨をコマンドラインに示す
else:
    print("Error:", response.status_code)

解説

  • ほとんどの説明はスクリプト内のコメントで済むと思います。Pythonの外部モジュールとしてrequestsを使っているので、これは必要に応じてpipでインストールしてください
  • スクリプトを実行すると、コマンドライン上でAPIキーを要求されますので、そこに自身のAPIキーを入力してください
  • 最初の api_type = "XIT001" と mlit_params = {"year": "2015", "area": "12"} の部分はそれぞれ対象データの種類とそれに応じたパラメータなので、ここを取得したいデータに応じて書き換えることで、このAPIが提供する様々なデータにアクセスできると思います
  • 注意点として、パラメータのyearに"2024"など直近年を入れるとデータがないのでエラーが返されたりします。パラメータの適正な範囲と、各データ種類における必須パラメータについては、公式マニュアル(リンク) の記載に従ってください
  • このAPIの仕様で厄介に感じたのは、レスポンスがgzip圧縮形式となる場合がある点です。さらに、レスポンスのヘッダーを確認してgzipと判断したもののPythonでのgzip解凍エラーが生じたりしたので、その辺はtry構文や条件分岐にて、出力結果がうまく得られるように補正しています
  • 出力結果はGeoJSONで得られるものやJSONで取得するものがあります。JSON形式のレスポンスに関してはCSVのほうが使いやすいケースもあると思うので、 選択式でCSV形式の出力にも対応しました
  • PBFはバイナリファイルなので非対応としています。パラメータでPBFを出力形式に指定してもGeoJSONで出力します

出力結果の例

不動産価格(取引価格・成約価格)情報取得API(XIT001)で千葉県(area=12)の2015年データをCSVで取得し、EXCELに読み込ませた結果が下記です。
このデータには緯度経度など詳細な位置情報はなく、大まかな住所のみが含まれています。

image.png

また、位置座標値が含まれるデータはGeoJSON形式で出力することで、GIS(地理情報システム)でそのまま可視化できます
一例として、都市計画決定GISデータ(立地適正化計画区域)API(XKT003)で特定箇所のデータを取得し、QGISで読み込ませると下記のようになります。

image.png

おわりに

以上、国土交通省の不動産情報ライブラリAPIからデータ取得するためのPythonスクリプトについて説明しました。
近年、国が整備した情報をオープンデータとしてサービス提供する流れが活発化しています。
これらをうまく活用することで、オーブンデータの活動をさらに加速していくことができると思うので、この記事が何らかの助けになれば幸いです。

2
2
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
2
2