【Python】Weather Hackから天気の取得
livedoorが提供してくださっている天気予報サービス「Wether Hacks」を利用して、Pythonで天気予報を取得してみます。
今回使わせていただくのは、「お天気Webサービス(REST)」。JSON形式で取得できるのでお手軽。ありがとうございます。
お天気Webサービス(REST)の仕様はこちらに書かれています。
作る
仕様のページを見ながら、pythonで作ります。
ライブラリは'requests'と'json'を使います。
リクエストパラメータ(URL)
はじめにアクセスするURLを決めようと思います。
仕様によるとベースになるURLは次のもの。
http://weather.livedoor.com/forecast/webservice/json/v1
で、その後ろにクエリがくるようだ。
パラメーター名は'city'、値は1次細分区のID。全国の地点定義表(RSS)のソースからcityタグのidを見てね。とのこと。
とりあえずブラウザでアクセスして見てみる。以下のようになっていた(東京のみ抜粋)。
~省略~ <pref title="東京都"> <warn title="警報・注意報" source="http://weather.livedoor.com/forecast/rss/warn/13.xml" /><city title="東京" id="130010" source="http://weather.livedoor.com/forecast/rss/area/130010.xml" /> <city title="大島" id="130020" source="http://weather.livedoor.com/forecast/rss/area/130020.xml" /> <city title="八丈島" id="130030" source="http://weather.livedoor.com/forecast/rss/area/130030.xml" /> <city title="父島" id="130040" source="http://weather.livedoor.com/forecast/rss/area/130040.xml" /> </pref> ~省略~
上記のソースから東京の1次細分区のidは'130010'だと言うことが分かる。
ベースURLにクエリ(?city=1次細分区のid)を付加すれば良いので、東京の天気情報取得URLは次のものになる。
http://weather.livedoor.com/forecast/webservice/json/v1?city=130010
天気情報(json)を取得してみる
URLが決まったのでpython2で取得して表示してみます。
#! /usr/bin/env python
# coding: utf-8 import requests # インターネット接続のため import json # json形式を扱いやすくするため base_url = 'http://weather.livedoor.com/forecast/webservice/json/v1' # ベースURL params = {'city': '130010'} # クエリの準備(地域を変えたい場合は値を変更) response = requests.get(base_url, params=params) # ベースURL + クエリでGET json_data = json.loads(response.content) # json_dataにレスポンスを辞書型で代入 # 読みやすくするためdumpsしたものをprint print('{0}'.format(json.dumps(json_data, indent=4, ensure_ascii=False).encode('utf-8')))
printの部分がグチャッとしてるけど、まあいいでしょう。python2は日本語不得意なのです。
実行すると以下のように表示された。
~省略~ "title": "東京都 東京 の天気", "forecasts": [ { "date": "2019-07-04", "image": { "url": "http://weather.livedoor.com/img/icon/8.gif", "width": 50, "height": 31, "title": "曇り" }, "telop": "曇り", "temperature": { "max": null, "min": null }, "dateLabel": "今日" }, ~省略~
問題なく取得できているようです。
欲しい情報だけ表示する
無事JSON形式で天気情報を取得できました。が、なんせ読みにくい。
欲しい情報だけ表示するようにします。
仕様ページのレポンスフィールドを参考にします。jsonライブラリを使っていれば辞書型の扱いと同じなので簡単ですね。
例えば「1次細分区名」のデータを指定して取得する場合は次のようになる。
json_data['location']['city']
上記の方法で各々の値を取得する。
以下に表にまとめた。
共通
値(内容) | データの指定(書式) |
---|---|
地方名 | json_data['location']['area'] |
都道府県名 | json_data['location']['pref'] |
1次細分区名 | json_data['location']['city'] |
タイトル・見出し | json_data['title'] |
リクエストされたデータの地域に該当するlivedoor天気情報のURL | json_data['link'] |
予報の発表日時 | json_data['publicTime'] |
天気概況文 | json_data['description']['text'] |
天気概況文の発表時刻 | json_data['description']['publicTime'] |
コピーライトの文言 | json_data['copyright']['title'] |
livedoor天気情報のURL | json_data['copyright']['link'] |
livedoor天気情報へのURL、アイコンなど | json_data['copyright']['image'] |
livedoor天気情報で使用している気象データの配信元 | json_data['copyright']['provider'] |
天気情報
配列になっていて'0'が今日、'1'が明日、'2'が明後日。
値(内容) | データの指定(書式) |
---|---|
予報日(yyyy-mm-dd) | json_data['forecasts'][0]['date'] |
予報日(今日) | json_data['forecasts'][0]['dateLabel'] |
天気 | json_data['forecasts'][0]['telop'] |
天気 | json_data['forecasts'][0]['image']['title'] |
リクエストされたデータの地域に該当するlivedoor天気情報のURL | json_data['forecasts'][0]['image']['link'] |
天気アイコンのURL | json_data['forecasts'][0]['image']['url'] |
天気アイコンの幅 | json_data['forecasts'][0]['image']['width'] |
天気アイコンの高さ | json_data['forecasts'][0]['image']['height'] |
最高気温(摂氏) | json_data['forecasts'][0]['temperature']['max']['celsius'] |
最高気温(華氏) | json_data['forecasts'][0]['temperature']['max']['fahrenheit'] |
最低気温(摂氏) | json_data['forecasts'][0]['temperature']['min']['celsius'] |
最高気温(華氏) | json_data['forecasts'][0]['temperature']['min']['fahrenheit'] |
'pinpointLocation'ってのもあるけど省略。
3日間の天気・気温を表示
上記を踏まえてpython2で書くと次のようになった。
#! /usr/bin/env python
# coding: utf-8 import requests # インターネット接続のため import json # json形式を扱いやすくするため base_url = 'http://weather.livedoor.com/forecast/webservice/json/v1' # ベースURL params = {'city': '130010'} # クエリの準備(地域を変えたい場合は値を変更) response = requests.get(base_url, params=params) # ベースURL + クエリでGET json_data = json.loads(response.content) # json_dataにレスポンスを辞書型で代入 # ここから画面表示の処理 print('{0}'.format(json_data['title'].encode('utf-8'))) # タイトルの表示 for forecast in json_data['forecasts']: # 'forecasts'内は配列になっているのでループ処理 date = forecast['date'] # 予報日(yyyy-mm-dd) dateLabel = forecast['dateLabel'].encode('utf-8') # 予報日 print('{0} ({1})'.format(date, dateLabel)) # 予報日の表示 telop = forecast['telop'].encode('utf-8') # 天気 t_max = forecast['temperature'].get('max') # 'max'の値がnullの場合があるのでgetメソッド t_min = forecast['temperature'].get('min') # 'min'の値がnullの場合があるのでgetメソッド if t_max is not None and t_min is not None: # 'max', 'min'の値がNoneじゃなかった場合の処理 t_max = '{0}℃'.format(t_max['celsius']) t_min = '{0}℃'.format(t_min['celsius']) print('天気: {0}\n最高気温: {1}\t最低気温: {2}'.format(telop, t_max, t_min)) # 天気・気温の表示
辞書型のキーを直接指定して値を取得しようとすると、気温の部分でエラーが発生する(値がnullの場合)ため一部get()で取得している。
ちなみに、上記スクリプトを実行すると以下の結果が得られる。
東京都 東京 の天気 2019-07-04 (今日) 天気: 曇り 最高気温: None 最低気温: None 2019-07-05 (明日) 天気: 曇のち雨 最高気温: 26℃ 最低気温: 20℃ 2019-07-06 (明後日) 天気: 曇時々雨 最高気温: None 最低気温: None
おわりに
天気のAPIは他にもあるけど、livedoor社のWeather Hacksは登録もなしに気軽に使えるので嬉しいですね。livedoor社さんには本当に感謝です。