OpenWeatherMapで郵便番号が使えないときのアプローチ
OpenWeatherMap
OpenWeatherMapは、開発者に、現在の天候や予測履歴を含む各種気象データを提供する無料APIです(一部有料あり)。
使い方については、記事が沢山出ているので、参考程度にQiitaのリンクを貼っておきます。
郵便番号を指定してデータを取得する
zip
パラメータを指定することで郵便番号指定検索ができます。
import requests url = https://api.openweathermap.org/data/2.5/forecast params = { "APPID" : API_KEY, "units" : "metric", "zip" : "100-0001,jp" } res = requests.get(url,params=params)
APPID
はAPI keyです。取得方法については、多くの記事で紹介されているので省略します。
エンドポイント(url)にhttps://api.openweathermap.org/data/2.5/forecast
を指定すると、5日間分の3時間予報が取得できます。
https://api.openweathermap.org/data/2.5/weather
を指定すると、現在の天候が取得できます。
郵便番号を指定してもデータが取得できないとき
ここからがメインです。
例えば郵便番号に 100-0001(東京都千代田区千代田)を指定すると、データが取得できます。
ただし、100-0000(東京都千代田区)を指定すると、取得できません。
{ "cod": "404", "message": "city not found" }
この問題・解決策を記載している記事が少なかったので、一つのアプローチとして、HeartRailsGeo APIを使用して緯度・経度を算出した後に、緯度経度から気象情報を取得するという方法を紹介します。
他には、そもそも郵便番号を利用しない(CityCode等の他パラメータを用いて検索)などの方法があります。
この記事は、どうしても郵便番号が使いたい人向けです。
HeartRailsGeo API
「HeartRails Geo API」 は、郵便番号/住所/緯度経度データ等の地理情報を、XML、JSON(P) 形式の API により無料でご提供させていただくサービスです。
API は商用、非商用を問わず、無料でご利用になれます。
url : http://geoapi.heartrails.com/api.html
この中の、郵便番号から郵便番号による住所検索 APIを使用します。
import requests url = http://geoapi.heartrails.com/api/json params = { "method" : "searchByPostal", "postal" : "<郵便番号>" (例:1000000) } res = requests.get(url,params=params)
郵便番号1000000
を指定したときのレスポンスは次のようなものです。
x : 経度,y :緯度
{ "response": { "location": [ { "city": "千代田区", "city_kana": "ちよだく", "town": "(その他)", "town_kana": "(そのた)", "x": "139.754927", "y": "35.68576", "prefecture": "東京都", "postal": "1000000" } ] } }
緯度経度を指定してOpenWeatherMapから情報を取得する
ここで取得した緯度経度を使います。
# res : 郵便番号から郵便番号による住所検索 APIのレスポンス longitude = res["response"]["location"][0]["x"] latitude = res["response"]["location"][0]["y"] url='https://api.openweathermap.org/data/2.5/weather' params={ "lon":longitude, "lat":latitude, "units":"metric", "APPID":APIKEY } res = requests.get(url,params=params)
これで(ほぼすべての郵便番号について、正しい情報が)取得できました。
注意点
郵便番号が被る地域があります。
この記事を見ると、よくわかります。
郵便番号は必ず1つの町名に紐づいているわけではない
市区町村をまたいで同じ郵便番号を持つケースがある
市区町村はおろか県を飛び越えて同じ郵便番号を持ちうるケースがある
例えば、6180000
を指定して、住所検索APIにリクエストを送ると次のようなレスポンスが返ってきます。
{ "response": { "location": [ { "city": "乙訓郡大山崎町", "city_kana": "おとくにぐんおおやまざきちょう", "town": "(その他)", "town_kana": "(そのた)", "x": "135.688862", "y": "34.904159", "prefecture": "京都府", "postal": "6180000" }, { "city": "三島郡島本町", "city_kana": "みしまぐんしまもとちょう", "town": "(その他)", "town_kana": "(そのた)", "x": "135.667274", "y": "34.902399", "prefecture": "大阪府", "postal": "6180000" } ] } }
取得できるデータは正しいですが、上記の通り、安直に
longitude = res["response"]["location"][0]["x"] latitude = res["response"]["location"][0]["y"]
のように0番目を指定すると誤った情報を提供する可能性があります。
まとめ
OpenWeatherMapで郵便番号を指定してリクエストをする方法と、できないときのアプローチとしてHeartRailsGeo APIを使用して緯度・経度を算出した後に、緯度経度から気象情報を取得する方法を紹介しました。
しかし、日本の郵便番号の設定上、誤った情報を提供する可能性があることに注意する必要があります。
郵便番号が被っていない地域に対してサービスを提供するような場合、今回のアプローチは有効ですが、サービス提供先の地域の郵便番号が複数の地域に及ぶ場合は、今回の方法は使えません。