OpenWeatherMapのAPIを使用して今日の天気予報を取得する(Python3)

# 目的

- 今日の天気予報を取得する。
 - 取得するだけでなく、後ほどLINEなどで送信できるよう出力可能な状態にする。
 - 欲しいのは天気だけなので気温の情報は試す程度でいいかな。
- APIの知見を深める。
 - Json形式を扱ったことがないので練習。
 - そもそも全体的に初学者なのでとりあえずやってみようの精神
- Qiitaに投稿するネタ作り
 - もしも誰かの役に立てば嬉しい

# 準備

まず、[OpenWeatherMap](https://openweathermap.org)の利用登録を行う。
その後、サインインしてAPI-Keyを発行する
※数時間待たないと有効にならないので注意。
何も読まずにPGを書いて「できねえ！！！」となってたが翌朝やったらできた。

# 書いてみる

とりあえず書いた。


```python:weather.py
import requests
import json
import datetime

def call_weather_api():
    api_key = 'yourApiKey'
    api = 'http://api.openweathermap.org/data/2.5/forecast?units=metric&q={city}&APPID={key}&cnt={limit}'

    city_name = 'Tokyo,JP'
    # cntパラメータで取得する行数を指定可能（指定しないと3時間単位で5日分来るので膨大な行数になる）
    request_line = 7
    url = api.format(city = city_name, key = api_key, limit = request_line)
    print(url)

    # APIを叩いて結果をJSONで取得
    response = requests.get(url)
    data = response.json()

    # 現在日時表示
    print(datetime.datetime.now())

    # key'list'のなかに辞書型で予報が格納されているので、for文で回して整形・表示してみる
    for i in data['list']:
        print(json.dumps(i, indent = 4))

call_weather_api()
```

## 結果

> 2019-06-14 00:04:11.158585
{
    "dt": 1560438000,
    "main": {
        "temp": 20.11,
        "temp_min": 20.11,
        "temp_max": 23.06,
        "pressure": 1015.22,
        "sea_level": 1015.22,
        "grnd_level": 1010.97,
        "humidity": 65,
        "temp_kf": -2.95
    },
    "weather": [
        {
            "id": 800,
            "main": "Clear",
            "description": "clear sky",
            "icon": "01n"
        }
    ],
    "clouds": {
        "all": 0
    },
    "wind": {
        "speed": 4.33,
        "deg": 173.949
    },
    "sys": {
        "pod": "n"
    },
    "dt_txt": "2019-06-13 15:00:00"
}
(中略）
{
    "dt": 1560502800,
    "main": {
        "temp": 25.05,
        "temp_min": 25.05,
        "temp_max": 25.05,
        "pressure": 1012.61,
        "sea_level": 1012.61,
        "grnd_level": 1009.01,
        "humidity": 47,
        "temp_kf": 0
    },
    "weather": [
        {
            "id": 804,
            "main": "Clouds",
            "description": "overcast clouds",
            "icon": "04d"
        }
    ],
    "clouds": {
        "all": 99
    },
    "wind": {
        "speed": 7.26,
        "deg": 166.253
    },
    "sys": {
        "pod": "d"
    },
    "dt_txt": "2019-06-14 09:00:00"
}



上記を見ていただければわかるように、取得時刻にズレが生じている。
これは時差によるものだと思うのだが、タイムゾーンの指定方法がわからないのでとりあえず放置・・・
（どなたかご教示願います）


## 天気のみを取得

実は今回の最終目的は雨の日のみ朝LINEで教えてくれる機能を作成することなので、判定のために天気の箇所のみを抜き出す必要がある。
とりあえず以下で試してみる


```python:weather.py

import requests
import json

def call_weather_api():
    api_key = 'yourApiKey'
    api = 'http://api.openweathermap.org/data/2.5/forecast?units=metric&q={city}&APPID={key}&cnt={limit}'

    city_name = 'Tokyo,JP'
    # cntパラメータで取得する行数を指定可能（指定しないと3時間単位で5日分来るので膨大な行数になる）
    request_line = 7
    url = api.format(city = city_name, key = api_key, limit = request_line)
    print(url)

    # APIを叩いて結果をJSONで取得
    response = requests.get(url)
    data = response.json()

    # key'list'のなかに辞書型で予報が格納されているので、for文で回して天気の部分を取得する
    for i in data['list']:
        print(i['weather'][0]['main'])
        

call_weather_api()


```


## 結果

> Clear
Clear
Clouds
Clouds
Clouds
Clouds
Clouds


これは先ほどの結果からもわかるように約8時間前の時点から15時間後までの天気予報を3時間毎に並べたものになっている（はず）。
時間のズレのせいで適切な範囲設定になっていないので、取得する行数を増やして対応する。

request_line = 15

としてみる。
さらに、時間も表示する

```python:weather.py

# key'list'のなかに辞書型で予報が格納されているので、for文で回して天気の部分を取得する
    for i in data['list']:
        print(i['weather'][0]['main'])
        print(i['dt_txt'])      
```


> Clear
2019-06-13 18:00:00
Clear
2019-06-13 21:00:00
Clouds
2019-06-14 00:00:00
Clouds
2019-06-14 03:00:00
Clouds
2019-06-14 06:00:00
Clouds
2019-06-14 09:00:00
Clouds
2019-06-14 12:00:00
Clouds
2019-06-14 15:00:00
Rain
2019-06-14 18:00:00
Rain
2019-06-14 21:00:00
Rain
2019-06-15 00:00:00
Rain
2019-06-15 03:00:00
Rain
2019-06-15 06:00:00
Rain
2019-06-15 09:00:00
Rain
2019-06-15 12:00:00

とりあえず取得できた。
ここまで書いて思ったのだが、この時間表示がそもそも日本時間ではないということなのか・・・？


# 結論

とりあえずやりたいことの大まかな部分はできた。
ただ、OpenWeatherMapのAPIの仕様がまだよくわかっていないため、ドキュメントを読むなどして煮詰めていきたい。

様々な指摘があるかと思うので、何でも教えていただけたらと思います。

次はこの結果雨が降りそうならLINEで通知する機能の実装をしていきたい。
ここまで読んでくださった方、ありがとうございました！:)


# 追記

公式ドキュメントを読んだところ、やはり"dt_txt"自体がUTCでだということがわかった。
なので、シンプルに5行分取得すれば判定には使えそう。
（レスポンスはUTCで固定のようなので時間を表示する場合は+9:00する必要がありそう。)