はじめに

今回は『APIって、どんな動きをしているの?』と中の動きがサッパリだったので、構築を交えながらAPIについて学習していきたいと思いたち、下記参考資料を読みながら手を動かしてAPIを構築しました

参考資料

参考リンクにはAPIのHTTPリクエスト・レスポンスなどの記述の方法などの説明があり、API分からなかったコチラを読めばOKかと
どちらもハンズオンを進める中で大変理解が捗りました

APIの仕組みが分かる・使いこなせる人材になれる記事(Pythonコード付き)
HTTPとPOSTとGET

構成図

スクリーンショット 2021-11-23 13.03.05.png

ハンズオン

0:「Yahoo! JAPAN Webサービス」でアプリケーションIDを発行する

今回利用するAPIはYahoo!JAPANの「気象情報API」と「Yahoo!ジオコーダAPI」を使用するために「Yahoo!JAPAN ID」「アプリケーションID」を取得していきます

スクリーンショット 2021-11-23 9.44.19.png

「アプリケーションID」のアプリケーション名は後からでも変更可能なので拘らなくても構いません。
スクリーンショット 2021-11-23 9.53.44.png

アプリケーションの管理から自分のアプリケーションIDを確認する
スクリーンショット 2021-11-23 9.58.32.png

1:ブラウザから天気予報データを取得する

[気象情報API]
(https://developer.yahoo.co.jp/webapi/map/openlocalplatform/v1/weather.html)のページへ移動する

スクリーンショット 2021-11-23 10.07.17.png

気象情報APIを利用するためには『RESTリクエスト(GET)』で、エンドポイント(URL)の中に情報を含める必要があることが分かります。
そのためにURLに値を「?」で繋ぎ、それ以降の条件を「&」で繋いでいきますが日本語だと難しく感じますので、サンプルリクエストURLで確認していきます。

スクリーンショット 2021-11-23 10.26.14.png

上記のように色分けをすると、「?」以降の値を「&」で繋いでいるのが確認できるかと思います。
ちなみにサンプルリクエストにある「あなたのアプリケーションID」の____部分は不要のため削除しています。情報を取得するためブラウザにURLをCOPYして確認していきます。

スクリーンショット 2021-11-23 10.34.16.png

サンプルレスポンスにもあるような値が返信されていれば、無事にデータが取得できていることが分かります。

ちなみにMacのターミナルからでもcurlコマンドを利用することで確認することができますが、『zsh: no matches found:』が出た場合はURLをダブルクォーテーションかシングルクォーテーションで囲って対応ください

tetutetu214@mbp rainfall % curl "https://map.yahooapis.jp/weather/V1/place?coordinates=139.732293,35.663613&appid=XXXXX"

2:「Yahoo!ジオコーダAPI」で取得したい地点の『coordinates』データを取得する

スクリーンショット 2021-11-23 11.01.16.png

こちらも手順としては、気象情報APIと同様にエンドポイント(URL)の中に情報を含めていきます。YAHOO!にあるサンプルを利用してもいいですが、今回は自分が取得したい地点の情報が表示されるようにしていきます。確認はブラウザでもターミナルでも構いません。

・ブラウザのURLの場合(地名は任意)

https://map.yahooapis.jp/geocode/V1/geoCoder?appid=XXXXXXXXXX&query=埼玉県川口市

・ターミナルの場合のコマンド

tetutetu214@mbp rainfall % curl "https://map.yahooapis.jp/geocode/V1/geoCoder?appid=XXXXXXXXXX&query=埼玉県川口市"

ブラウザの場合、赤枠の値=取得したい地点の値を確認することができる
スクリーンショット 2021-11-23 11.44.19.png

3:上記の内容を踏まえてコードを記述していく(最後に、まとめたコードの記述あり)

# ライブラリのインポート
import requests
import json

#天気予報を出したい都市を入力(input()にすれば取得したい地点のGeoコード取得可能)
#AREA = input()
AREA = "埼玉県川口市"
print(AREA + "の天気を出力します")

AREA = input()をコメントアウトするれば、『埼玉県川口』など固定した場所ではなく、入力した箇所の天気予報(Yahoo!ジオコーダの地点の取得)をすることができる

#変数
api_key = "XXXXXXXXXX"
Weather_url = "https://map.yahooapis.jp/weather/V1/place?"
geo_url = "https://map.yahooapis.jp/geocode/V1/geoCoder?"
parm1 = "coordinates="
parm2 = "&output=json"
parm3 = "&query="

・#変数とあるparm2 = "&output=json"部分は、APIの説明にもあったリクエストパラメータ一覧にもあるアウトプットされる出力形式を指定することができるもので、取得した情報を利用するために記述
スクリーンショット 2021-11-23 12.22.26.png

# Yahoo!ジオコーダによる取得したい場所の情報をURLにする
geo = geo_url + api_key + parm2 + parm3 + AREA

# 取得した情報を整形する
geo_info = requests.get(geo)
geo_obj = json.loads(geo_info.text)

# Geometryから座標情報のみ取得する
parm = geo_obj["Feature"][0]["Geometry"]["Coordinates"]

・ブラウザでも確認しているかもしれませんが、下記範囲の情報を取得する
スクリーンショット 2021-11-23 12.29.24.png

# 気象情報APIに渡すための情報(「?」の後ろに「&」で条件を繋いでいく)をURLにする
url = Weather_url + parm1 + parm + parm2 + api_key

# 取得した情報を整形する
url_info = requests.get(url)
obj = json.loads(url_info.text)

・気象情報APIに『parm』で取得地点の値を渡して、こちらもjson形式で情報(地点の10分ごとの天気)を取得する

# 取得した気象情報7回分のうち10分後のものから表示させる
for i in range(1,7):
    type=obj['Feature'][0]['Property']['WeatherList']['Weather'][i]['Type']
    date=obj['Feature'][0]['Property']['WeatherList']['Weather'][i]['Date']
    rainfall=obj['Feature'][0]['Property']['WeatherList']['Weather'][i]['Rainfall']

    print("予想される天気")
    print(str(i*10) + "分後")
    print("降水強度は" + str(rainfall))

全部で今の時刻と60分後なので7回(今+6回)情報が取得されますが、予報なので今の情報は除いてfor文を利用して情報を表示させるようにしています
ブラウザでは赤枠で囲った部分を取得する記述となっています
スクリーンショット 2021-11-23 12.39.08.png

ちなみにレスポンスの言葉の意味は[気象情報API]
(https://developer.yahoo.co.jp/webapi/map/openlocalplatform/v1/weather.html)のレスポンスフィールドという部分に説明があります
スクリーンショット 2021-11-23 12.35.29.png

まとめたコードの記述(情報を取得表示を優先しています)

# ライブラリのインポート
import requests
import json

#天気予報を出したい都市を入力(input()にすれば取得したい地点のGeoコード取得可能)

#AREA = input()
AREA = "埼玉県川口市"
print(AREA + "の天気を出力します")

#変数
api_key = "XXXXXXXXXX"

Weather_url = "https://map.yahooapis.jp/weather/V1/place?"
geo_url = "https://map.yahooapis.jp/geocode/V1/geoCoder?"

parm1 = "coordinates="
parm2 = "&output=json"
parm3 = "&query="

# Yahoo!ジオコーダによる取得したい場所の情報をURLにする
geo = geo_url + api_key + parm2 + parm3 + AREA

# 取得した情報を整形する
geo_info = requests.get(geo)
geo_obj = json.loads(geo_info.text)

# Geometryから座標情報のみ取得する
parm = geo_obj["Feature"][0]["Geometry"]["Coordinates"]

# 気象情報APIに渡すための情報(「?」の後ろに「&」で条件を繋いでいく)をURLにする
url = Weather_url + parm1 + parm + parm2 + api_key

# 取得した情報を整形する
url_info = requests.get(url)
obj = json.loads(url_info.text)

# 取得した気象情報7回分のうち10分後のものから表示させる
for i in range(1,7):
    type=obj['Feature'][0]['Property']['WeatherList']['Weather'][i]['Type']
    date=obj['Feature'][0]['Property']['WeatherList']['Weather'][i]['Date']
    rainfall=obj['Feature'][0]['Property']['WeatherList']['Weather'][i]['Rainfall']

    print("予想される天気")
    print(str(i*10) + "分後")
    print("降水強度は" + str(rainfall))

上記をターミナルで動かした際の表示

tetutetu214@mbp rainfall % python lambda_function.py
埼玉県川口市の天気を出力します
予想される天気
10分後
降水強度は0.0
予想される天気
20分後
降水強度は0.0
予想される天気
30分後
降水強度は0.0
予想される天気
40分後
降水強度は0.0
予想される天気
50分後
降水強度は0.0
予想される天気
60分後
降水強度は0.0

さいごに

APIの知識も乏しく、なんとなくURLに書けばいいんでしょ程度の知識から、ある程度の書き方を理解して書けるようになったので、また違うAPIを利用しながら理解をより深めていきたいと勤労感謝の日に思うのでした。
次はこちらの内容をLINE APIでAWS APIGateway〜Lambdaで連動して起動できるようにしてみたいです。

Last modified: 2021-11-24

Author