Open Weather Map
前回、本家のOpen Weather Mapを使って、現在の天気を取得してみました。
今回は現在の天気だけでなく、天気予報も取得してみようと思います。
どんな天気予報が取得できるかというと、前々回にお話ししたOpen Weather Mapのプランのところに書かれています。
これによると「Minute Forcast 1hour(今後1時間の1分毎の予報)」、「Hourly Forcast 2days(今後2日間の1時間毎の予報)」、「Daily Forcast 7days(今後7日間の1日毎の予報)」が取得できるようです。
ただよく見ると「*(アスタリスク)」が付いています。
なんだろうと思って探してみると、こんな注意書きを見つけました。
Freeのプランである予報に関しては「One Call API」というAPIを介して、1日に1000コールまでとなっているようです。
通常、個人で使う分には1000コールもあれば十分でしょうが、例えばwebサイトに載せて、アクセスされるたびにコールするなんて使い方していたら足りなくなるかもしれませんので注意したいところですね。
One Call API
ただOne Call APIというのは何でしょうか。
ということで「One Call API」のリンクを辿ってみます。
これによると場所を指定することで、その場所の天気情報を全て取得できるAPIのようです。
となると1回のコールで現在の天気や何時間後の天気などの情報が一度に取得できるということなので、コール数を抑えることができそうです。
そしてAPIコールの例とオプションとしてはこんな感じでした。
最低限必要なのは「lat(緯度)」と「lon(経度)」、そして「appid(API key)」の三つなので、最低限こんな感じでコールすればよさそうです。
https://api.openweathermap.org/data/2.5/onecall?lat=33.44&lon=-94.04&appid={API key}
ということで基本が分かったので、データを取得してみましょう。
緯度と経度を取得
このOne Call APIは前に現在の天気を取得した時と違い、取得する場所の緯度と経度が必要になります。
ということでまずは緯度と経度の取得から行っていきますので、Open Weather Mapにアクセスします。
そして左上の検索バー「Weather in your city」に緯度と経度を知りたい場所の名前を英語で入れます。
とりあえず「Tokyo」と入れて検索してみました。
すると検索結果は何故か2つ出てきます。
どちらも経度緯度は[35.6895, 139.6917]で同じです。
もう一つ「Osaka」を調べてみましょう。
またもや結果は2つ出てきましたが、今度は一つ目が[34.6937, 135.5022]、二つ目が[35.95, 137.2667]と異なっています。
ちなみにこの緯度と経度をクリックすることで、その場所を地図で表示することができます。
一つ目を表示するとこんな感じでした。
そして二つ目はこんな感じ。
これから推測するに大阪の場合は「大阪府」と「大阪市」の違いのようです。
東京の場合は「東京都」と「東京23区」なのではないかなと思いますが、緯度経度が同じなので、特に区別していないのかもしれません。
とりあえずこれで緯度と経度を取得することができました。
One Call APIで天気データを取得
それでは東京を例にして、One Call APIを使って、現在の天気と天気予報を取得してみましょう。
まずは全データを取得してみます。
import requests
import json
point = [43.0642, 141.3469]
api_key = "Your_API_key"
api = "https://api.openweathermap.org/data/2.5/onecall?lat={lat}&lon={lon}&appid={key}"
url = api.format(lat=point[0], lon=point[1], key=api_key)
forcast_data = requests.request("GET", url)
forcast_json = json.loads(forcast_data.text)
print(forcast_json)
実行結果
{'lat': 43.0642, 'lon': 141.3469, 'timezone': 'Asia/Tokyo', 'timezone_offset': 32400,
'current': {'dt': 1634040698, 'sunrise': 1633985039, 'sunset': 1634025481, 'temp': 283.1,
'feels_like': 283.1, 'pressure': 1031, 'humidity': 93, 'dew_point': 282.02, 'uvi': 0,
'clouds': 7, 'visibility': 10000, 'wind_speed': 1.32, 'wind_deg': 180, 'wind_gust': 1.64,
'weather': [{'id': 800, 'main': 'Clear', 'description': 'clear sky', 'icon': '01n'}]},
'minutely': [{'dt': 1634040720, 'precipitation': 0}, {'dt': 1634040780, 'precipitation': 0},
{'dt': 1634040840, 'precipitation': 0}, {'dt': 1634040900, 'precipitation': 0},
{'dt': 1634040960, 'precipitation': 0}, {'dt': 1634041020, 'precipitation': 0},
{'dt': 1634041080, 'precipitation': 0}, {'dt': 1634041140, 'precipitation': 0},
{'dt': 1634041200, 'precipitation': 0}, {'dt': 1634041260, 'precipitation': 0},
{'dt': 1634041320, 'precipitation': 0}, {'dt': 1634041380, 'precipitation': 0},
(以下略)
今回も使うライブラリは「requests」と「json」です。
天気予報を取得したい場所の緯度と経度を「point」にAPI keyを「api_key」、アクセスするURLを「api」に格納します。
point = [43.0642, 141.3469]
api_key = "Your_API_key"
api = "https://api.openweathermap.org/data/2.5/onecall?lat={lat}&lon={lon}&appid={key}"
apiの「onecall?lat={lat}&lon={lon}&appid={key}」の部分は次の「url = api.format(lat=point[0], lon=point[1], key=api_key)」で場所とAPI keyが挿入されます。
あとは「requests」でデータを取得し、jsonとして読み込み、表示しています。
forcast_data = requests.request("GET", url)
forcast_json = json.loads(forcast_data.text)
print(forcast_json)
このままではデータが丸々表示されるので、必要なデータにアクセスしていきましょう。
現在の天気の取得
まずは現在の天気の取得をしてみます。
もちろん前回の現在の天気を取得するAPIで現在の天気だけ取得してきてもいいのですが、そうするとAPIコール数を1回余分に使ってしまうことになります。
ですが、もしこのOne Call APIのデータから取得できれば、APIコール数の節約になります。
One Call APIで現在の天気を取得するにはこんな感じになります。
print(forcast_json['current']['weather'][0]['main'])
実行結果
Clear
前回の現在の天気を取得するAPIでは「weather_json[‘weather’][0][‘main’]」だったので、「’current’」というキーでデータを取得するというのが一つ増えています。
1時間ごとの天気予報を取得
次に1時間ごとの天気予報を取得してみましょう。
1時間ごとの天気予報データを取得するには「forcast_json[‘hourly’]」とします。
print(forcast_json['hourly'])
実行結果
[{'dt': 1634040000, 'temp': 283.1, 'feels_like': 283.1, 'pressure': 1031, 'humidity': 93,
'dew_point': 282.02, 'uvi': 0, 'clouds': 7, 'visibility': 10000, 'wind_speed': 1.32,
'wind_deg': 180, 'wind_gust': 1.64, 'weather': [{'id': 800, 'main': 'Clear',
'description': 'clear sky', 'icon': '01n'}], 'pop': 0}, {'dt': 1634043600, 'temp': 283.25,
'feels_like': 282.67, 'pressure': 1031, 'humidity': 90, 'dew_point': 281.69, 'uvi': 0,
'clouds': 6, 'visibility': 10000, 'wind_speed': 1.44, 'wind_deg': 171, 'wind_gust': 1.94,
'weather': [{'id': 800, 'main': 'Clear', 'description': 'clear sky', 'icon': '01n'}],
'pop': 0}, {'dt': 1634047200, 'temp': 283.32, 'feels_like': 282.69, 'pressure': 1031,
'humidity': 88, 'dew_point': 281.42, 'uvi': 0, 'clouds': 5, 'visibility': 10000,
'wind_speed': 1.38, 'wind_deg': 164, 'wind_gust': 1.99, 'weather': [{'id': 800, 'main':
'Clear', 'description': 'clear sky', 'icon': '01n'}], 'pop': 0}, {'dt': 1634050800,
(以下略)
これで取得できる1時間ごとの天気予報データが全て取得できます。
ちなみに1分ごとの場合は「forcast_json[‘minutely’]」(ただし降水確率だけ)
print(forcast_json['minutely'])
実行結果
[{'dt': 1634040720, 'precipitation': 0}, {'dt': 1634040780, 'precipitation': 0},
{'dt': 1634040840, 'precipitation': 0}, {'dt': 1634040900, 'precipitation': 0},
{'dt': 1634040960, 'precipitation': 0}, {'dt': 1634041020, 'precipitation': 0},
{'dt': 1634041080, 'precipitation': 0}, {'dt': 1634041140, 'precipitation': 0},
{'dt': 1634041200, 'precipitation': 0}, {'dt': 1634041260, 'precipitation': 0},
{'dt': 1634041320, 'precipitation': 0}, {'dt': 1634041380, 'precipitation': 0},
(以下略)
1日ごとの場合は「forcast_json[‘daily’]」です。
print(forcast_json['daily'])
[{'dt': 1634004000, 'sunrise': 1633985039, 'sunset': 1634025481, 'moonrise': 1634009280,
'moonset': 1634040540, 'moon_phase': 0.21, 'temp': {'day': 289.63, 'min': 282.75,
'max': 290.28, 'night': 283.32, 'eve': 285.44, 'morn': 283.12}, 'feels_like':
{'day': 288.67, 'night': 282.69, 'eve': 284.63, 'morn': 283.12}, 'pressure': 1028,
'humidity': 51, 'dew_point': 278.76, 'wind_speed': 2.19, 'wind_deg': 27, 'wind_gust': 2.85,
'weather': [{'id': 800, 'main': 'Clear', 'description': 'clear sky', 'icon': '01d'}],
'clouds': 0, 'pop': 0, 'uvi': 3.28}, {'dt': 1634090400, 'sunrise': 1634071510,
'sunset': 1634111781, 'moonrise': 1634099220, 'moonset': 1634130900, 'moon_phase': 0.25,
'temp': {'day': 290.05, 'min': 283.64, 'max': 290.37, 'night': 283.94, 'eve': 285.95,
(以下略)
また時間に関してですが「dt」という項目が時間なのですが、これはエポック秒(UNIX秒)と呼ばれるもので1970年1月1日午前0時0分0秒を基準として、そこからの経過時間として表記する方法です。
これに関してはまた機会がありましたら、解説していきたいと思います。
ちょっと話が逸れてしまいましたが、1時間ごとの天気予報の取得に戻ります。
先ほど1時間ごとの天気予報データの全データの取得はできました。
ここから特定の時間の天気予報データを取得します。
その場合は取得したい経過時間後の数字をインデックスとして使い、このようにします。
print(forcast_json['hourly'][6])
実行結果
{'dt': 1634061600, 'temp': 284.6, 'feels_like': 283.92, 'pressure': 1030, 'humidity': 81,
'dew_point': 280.46, 'uvi': 0, 'clouds': 28, 'visibility': 10000, 'wind_speed': 1.96,
'wind_deg': 142, 'wind_gust': 2.79, 'weather': [{'id': 802, 'main': 'Clouds',
'description': 'scattered clouds', 'icon': '03n'}], 'pop': 0},
これで6時間後のデータが取得できます。
ここから天気のデータを取得しますが、ここからは前の現在の天気の取得の方法と同じです。
ということでこんな感じ。
print(forcast_json['hourly'][6]['weather'][0]['main'])
実行結果
Clouds
これで6時間後の天気予報を取得できました。
現在の天気だけでなく、天気予報も取得できると色々と用途が広がりそうです。
ではでは今回はこんな感じで。
コメント