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)
お疲れ様でした。
