Google Colaboratoryを使って、BODIK APIを使ったPythonプログラムを書いてみます。
課題1:BODIK APIを呼び出してみる
問題:BODIK APIを使って、AEDを検索してみる。
基本情報
- PythonからWebAPIを呼び出す方法はいくつかありますが、ここでは「requests」を使います。
- BODIK APIの検索結果はJSON形式で取得できます。
- 検索結果は辞書形式データの配列になっています。
- Pythonで配列の各要素を調べる場合、「for ... in ...」を使います。
swaggerで試す
最初に、WAPIのswagger(https://wapi.bodik.jp/docs)でAPIを試してみましょう。

AED(GET /aed)のエンドポイントを表示し、「try it out」のボタンを押して、下の方にある青い「Execute」ボタンを押します。

検索結果が表示されます。「Request URL」のところを確認します。

「Request URL」は「?」の前方がAPIのURL部分、後方がパラメータになります。
URL部分 パラメータ部分 https://wapi.bodik.jp/aed?select_type=data&maxResults=10&distance=2000
URL部分
https://wapi.bodik.jp/aed これを分解すると BODIK APIのURL:https://wapi.bodik.jp データセット名:aed
パラメータ部分:複数のパラメータが「&」で結合されています。
select_type=data&maxResults=10&distance=2000 これを分解すると select_type=data maxResults=10 distance=2000
pythonで記述
では、Pythonで「BODIK API」を呼び出してみましょう。
「python requests」で検索すると、requestsの使い方を説明したサイトが見つかりますので、参考にしてください。
ライブラリのimport
まず、必要なライブラリを宣言します
import requests import json
Pythonで「requests」ライブラリを使ってWebAPIを呼び出すときは、次のような流れになります。
url = 'https://xxxxxxxx?a=123&b=456&c=789' # WebAPIのURLを用意する response = requests.get(url) # requestsのgetメソッドを実行する data = response.json() # 結果のJSONを取り出す
この流れに合わせて、BODIK APIを呼び出してみましょう。
WebAPIのURLを用意する
WebAPIのURLは、APIサーバーのURLとパラメータの組み合わせになります。Pythonで文字列を組み立てる方法はいくつかありますが、「f文字列」が便利です。
api_server = 'https://wapi.bodik.jp' apiname = 'aed' url = f'{api_server}/{apiname}'
requestsのgetメソッドを実行
response = requests.get(url)
結果のJSONを取り出す
「response」のjsonメソッドを呼び出すと、APIの実行結果をJSONで取り出すことができます。取り出したデータは、print関数で表示することができます。
data = response.json() print(data)
プログラム(Ver1)
まとめると次のようになります。
import requests import json api_server = 'https://wapi.bodik.jp' apiname = 'aed' url = f'{api_server}/{apiname}' response = requests.get(url) data = response.json() print(data)
このプログラムを実行すると、「data」の内容が表示されます。
「data」の中は次のような形式になっています。
{ 'metadata': { 'api': 'aed', 'selectType': 'DATA', 'totalCount': 27430, 'count': 10 }, 'resultsets': { 'type': 'FeatureCollection', 'features': [ { 'type': 'Feature', 'properties': { 'municipalityCode': '12301', 'ID': '', 'municipalityName': '北海道三笠市', ・・・・・・・ } } ・・・・・・・・ ] } }
BODIK APIの実行結果の構造は、次のようになります。
data = { metadata resultsets: { features: [ 配列 feature 辞書 feature 辞書 ・・・・ ] } }
featureは次のようになります。
feature = { properties, # 各種属性情報 geometry # 位置情報 }
このデータ構造をpythonで解析するには、次のようなプログラムを書きます。
features = data['resultsets']['features'] # featuresは配列 for feature in features: # 配列は、「for .. in」で回す properties = feature['properties'] # propertiesは辞書 print(properties) # 表示する
プログラム(Ver2)
まとめると次のようになります。
import requests import json api_server = 'https://wapi.bodik.jp' apiname = 'aed' url = f'{api_server}/{apiname}' response = requests.get(url) data = response.json() features = data['resultsets']['features'] for feature in features: properties = feature['properties'] print(properties)
辞書である「properties」をそのまま表示してもわかりにくいですね。このようなときは、json.dumpsメソッドを使って、辞書を整形します。
プログラム(Ver3)
import requests import json api_server = 'https://wapi.bodik.jp' apiname = 'aed' url = f'{api_server}/{apiname}' response = requests.get(url) data = response.json() features = data['resultsets']['features'] for feature in features: properties = feature['properties'] print(json.dumps(properties, indent=2))
日本語部分がおかしな表示になっているので、対応します。
プログラム(Ver4)
import requests import json api_server = 'https://wapi.bodik.jp' apiname = 'aed' url = f'{api_server}/{apiname}' response = requests.get(url) data = response.json() features = data['resultsets']['features'] for feature in features: properties = feature['properties'] print(json.dumps(properties, indent=2, ensure_ascii=False))
プログラム(完成版)
実際には、コメントとエラー処理を入れて、完成です。
import requests import json try: # BODIK APIを呼び出す準備 api_server = 'https://wapi.bodik.jp' apiname = 'aed' url = f'{api_server}/{apiname}' # BODIK APIを呼び出す response = requests.get(url, timeout=5.0) # APIの実行結果を確認する if response is not None and response.status_code == 200: # 結果をJSONで取得する data = response.json() # BODIK APIの検索結果を解析する if data is not None and 'resultsets' in data: resultsets = data['resultsets'] if 'features' in resultsets: features = resultsets['features'] for feature in features: properties = feature['properties'] print(json.dumps(properties, indent=2, ensure_ascii=False)) else: print('no features', resultsets) else: print('no resultsets', data) else: print('status_code', response) except Exception as e: # 例外が発生 print('Exception', e)
お疲れ様でした。