Pythonで天気予報をLINE通知する

# 概要
* 天気予報をLINEで通知してみた時のメモです。
* 使用した言語はPython3です。

# 使用したサービスなど
* Python3
* Weather Hacks
* LINE Notify

# 天気予報
* livedoorのWeather Hacksが事前登録不要で楽だったので利用しました。
* http://weather.livedoor.com/forecast/webservice/json/v1 に都市コードのクエリを付けることで天気予報を取得できます。
* 取得できる情報は http://weather.livedoor.com/weather_hacks/webservice を参考にしました。
* 都市コードは http://www.nankuma.com/etc/livedoor-weather-id.html を参考にさせていただきました。
* 天気予報を取得するためのコードは以下。

```python

WEATHER_URL="http://weather.livedoor.com/forecast/webservice/json/v1?city=%s"
CITY_CODE="130010" # TOKYO

def get_weather_info():
    try:
        url = WEATHER_URL % CITY_CODE
        html = urllib.request.urlopen(url)
        html_json = json.loads(html.read().decode('utf-8'))
    except Exception as e:
        print ("Exception Error: ", e)
        sys.exit(1)
    return html_json
```
* 取得した天気予報をLINE通知用に整形するコードは以下。
* 例外処理は最低気温が返ってこない場合があったので。

```python

def set_weather_info(weather_json, day):
    max_temperature = None
    min_temperature = None
    try:
        date = weather_json['forecasts'][day]['date']
        weather = weather_json['forecasts'][day]['telop']
        max_temperature = weather_json['forecasts'][day]['temperature']['max']['celsius']
        min_temperature = weather_json['forecasts'][day]['temperature']['min']['celsius']
    except TypeError:
        # temperature data is None etc...
        pass
    msg = "%s\nweather: %s\nmin: %s\nmax: %s" % \
               (date, weather, min_temperature, max_temperature)
    return msg
```

# LINE通知

* LINE Notifyを使用してLINE通知を行います。
* https://notify-bot.line.me/ja/ から登録して、通知用のトークンを取得しておきます。
* https://notify-api.line.me/api/notify にトークンと通知メッセージをPOSTします。

```python

LINE_TOKEN="xxxxxxxxxxxxxxxxxxxxx"
LINE_NOTIFY_URL="https://notify-api.line.me/api/notify"

def send_weather_info(msg):
    method = "POST"
    headers = {"Authorization": "Bearer %s" % LINE_TOKEN}
    payload = {"message": msg}
    try:
        payload = urllib.parse.urlencode(payload).encode("utf-8")
        req = urllib.request.Request(
            url=LINE_NOTIFY_URL, data=payload, method=method, headers=headers)
        urllib.request.urlopen(req)
    except Exception as e:
        print ("Exception Error: ", e)
        sys.exit(1)

```

# まとめ
上述の内容を纏めたコードは下記

```python:weather.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-

import json
import sys
import urllib.parse
import urllib.request

# weather's API
WEATHER_URL="http://weather.livedoor.com/forecast/webservice/json/v1?city=%s"
CITY_CODE="130010" # TOKYO
TODAY=0
TOMMOROW=1

# LINE notify's API
LINE_TOKEN="xxxxxxxxxxxxxxxxxxxxx"
LINE_NOTIFY_URL="https://notify-api.line.me/api/notify"

def get_weather_info():
    try:
        url = WEATHER_URL % CITY_CODE
        html = urllib.request.urlopen(url)
        html_json = json.loads(html.read().decode('utf-8'))
    except Exception as e:
        print ("Exception Error: ", e)
        sys.exit(1)
    return html_json

def set_weather_info(weather_json, day):
    min_temperature = None
    max_temperature = None
    try:
        date = weather_json['forecasts'][day]['date']
        weather = weather_json['forecasts'][day]['telop']
        max_temperature = weather_json['forecasts'][day]['temperature']['max']['celsius']
        min_temperature = weather_json['forecasts'][day]['temperature']['min']['celsius']
    except TypeError:
        # temperature data is None etc...
        pass
    msg = "%s\nweather: %s\nmin: %s\nmax: %s" % \
               (date, weather, min_temperature, max_temperature)
    return msg

def send_weather_info(msg):
    method = "POST"
    headers = {"Authorization": "Bearer %s" % LINE_TOKEN}
    payload = {"message": msg}
    try:
        payload = urllib.parse.urlencode(payload).encode("utf-8")
        req = urllib.request.Request(
            url=LINE_NOTIFY_URL, data=payload, method=method, headers=headers)
        urllib.request.urlopen(req)
    except Exception as e:
        print ("Exception Error: ", e)
        sys.exit(1)

def main():
    weather_json = get_weather_info()
    for day in [TODAY, TOMMOROW]:
        msg = set_weather_info(weather_json, day)
        send_weather_info(msg)

if __name__ == '__main__':
    main()
```

# 実行結果
上記のコードを実行すると、LINE Notifyで下記のように通知が飛んできます。
<img width="360" alt="スクリーンショット 2018-03-18 14.34.07.png" src="https://qiita-image-store.s3.amazonaws.com/0/165991/c074b243-ab96-ead1-f923-0a51ea563464.png">