【Python】FeedParserとLINE Notifyを利用して厚生労働省の新型コロナウイルスに関する最新情報をLINE通知するスクリプトを作る

# きっかけ
新型コロナウイルス関連のニュースを日々見ていて、エンジニアとして何か技術を使ってできることは無いかと考えていました。コロナウイルス関連情報は1次情報として[厚生労働省のサイト](https://www.mhlw.go.jp/stf/seisakunitsuite/bunya/0000164708_00001.html)を見ていたりしていたのですが、[RSSフィード](https://www.mhlw.go.jp/stf/news.rdf)があることに気が付き、これを何か使えないかと考えていました。

そこで、最近学び始めたPythonを使って、厚生労働省の最新情報のURLをLINE通知するスクリプトを組んでみることにしました。Pythonは勉強中なので、大目に見ていただけると幸いです。
環境は`Windows10`、`Python3.8`ですが、MacやPython3系なら問題ないと思います。

# 事前準備
### ライブラリをインストール
必要なライブラリをpipでインストールします。

```terminal
$ pip install feedparser requests
```

### LINE Notifyのトークンを取得
[こちらから、LINEへ通知するためのトークンを取得します。](https://notify-bot.line.me/ja/)

LINE Notifyトークン取得は、こちらを参考にしてサクッとできます。
[[超簡単]LINE notify を使ってみる](https://qiita.com/iitenkida7/items/576a8226ba6584864d95)

# RSSにアクセスし最新のURLを取得
RSSへアクセスし最新のURLを取得するスクリプトを書きます。
`newpage`という文字列を含むリンクの一番最初のものが最新情報のようなので、こちらを返すメソッドを作ります。

```python
# RSSへアクセスし最新のURLを取得する
def getRssFeedData():
    # アクセスするrdfのURLを記載
    RSS_URL = 'https://www.mhlw.go.jp/stf/news.rdf'
    xml = feedparser.parse(RSS_URL)
    for entry in xml.entries:
        # linkの中からnewpageの最初のURLを取り出す
        if('newpage' in entry.link):
            print(entry.link)
            return entry.link
```

# 取得したURLが最新かどうかを判定する
取ってきたURLが最新かどうかを判定します。
ここでは、↑のメソッドで常に最新が取れていると仮定します。
URLをローカルファイル(`latest_url.txt`)に記録しておき、そのローカルファイルのURLとRSSから取得してきたURLを比較して、違っていた場合、最新情報としてLINE通知を行います。

```python
# 新着情報があるかチェック
def checkLatestNews():
    rss_url = getRssFeedData()
    path = './latest_url.txt'
 
    # latest_url.txtがなければ新規作成
    if not os.path.isfile(path):
        string = 'new file'
        with open(path, mode='w') as file:
            file.write(string)
 
    local_url = ''
    with open(path, mode='r') as file:
        local_url = file.read()
 
    # 新着情報があるかチェック
    if (local_url == rss_url):
        print('新着情報はありませんでした')
    else:
        with open(path, mode='w') as file:
            string = rss_url
            file.write(string)
        print('新着情報がありました')
```

# 新着情報があった場合にLINE通知をする
最後に、新着情報があった場合に、LINEを通知する処理を作ります。
新着情報のURLを受け取り、LINEに通知します。

```python
# LINEへ通知を行うメソッド
def lineNotify(url):
    # 発行したトークンを記載します
    LINE_NOTIFY_TOKEN = '1234567890abcdefghijklmnopqrstuvwxyz'
 
    # LINE NotifyのAPI URLを記載します
    LINE_NOTIFY_API = 'https://notify-api.line.me/api/notify'
 
    message = '\n厚生労働省からの最新情報があります。\n' + url
    payload = {'message': message}
    headers = {'Authorization': 'Bearer ' + LINE_NOTIFY_TOKEN }
 
    # LINE通知を行う
    requests.post(LINE_NOTIFY_API, data=payload, headers=headers)
```

# 定期的にチェックさせる
ローカルで動かすものとして、5分間隔でチェックさせます。

```python
while True:
    checkLatestNews()
    # 5分ごとにチェック※適宜変更
    sleep(300)
```

# それぞれの処理をつなげる
これまでの処理をつなげます。

```python:line_notify.py
import requests
import feedparser
from time import sleep
import os
 
# RSSへアクセスし最新のURLを取得する
def getRssFeedData():
    # アクセスするrdfのURLを記載
    RSS_URL = 'https://www.mhlw.go.jp/stf/news.rdf'
    xml = feedparser.parse(RSS_URL)
    for entry in xml.entries:
        # linkの中からnewpageの最初のURLを取り出す
        if('newpage' in entry.link):
            print(entry.link)
            return entry.link
 
# LINEへ通知を行うメソッド
def lineNotify(url):
    # 発行したトークンを記載します
    LINE_NOTIFY_TOKEN = '1234567890abcdefghijklmnopqrstuvwxyz'
 
    # LINE NotifyのAPI URLを記載します
    LINE_NOTIFY_API = 'https://notify-api.line.me/api/notify'
 
    message = '\n厚生労働省からの最新情報があります。\n' + url
    payload = {'message': message}
    headers = {'Authorization': 'Bearer ' + LINE_NOTIFY_TOKEN }
 
    # LINE通知を行う
    requests.post(LINE_NOTIFY_API, data=payload, headers=headers)
 
# URLが更新されたかチェック
def checkLatestNews():
    rss_url = getRssFeedData()
    path = './latest_url.txt'
 
    # latest_url.txtがなければ新規作成
    if not os.path.isfile(path):
        string = 'new file'
        with open(path, mode='w') as file:
            file.write(string)
 
    local_url = ''
    with open(path, mode='r') as file:
        local_url = file.read()
 
    # 新着情報があるかチェック
    if (local_url == rss_url):
        print('新着情報はありませんでした')
    else:
        # LINE通知
        lineNotify(rss_url)
        with open(path, mode='w') as file:
            string = rss_url
            file.write(string)
        print('新着情報があったので通知しました')
    
while True:
    checkLatestNews()
    # 5分ごとにチェック※適宜変更
    sleep(300)
```

# 完成！✨（きまぐれクック風）
ローカルで実行します。

```terminal
$ python line_notify.py

https://www.mhlw.go.jp/stf/seisakunitsuite/newpage_00016.html
新着情報があったので通知しました
https://www.mhlw.go.jp/stf/seisakunitsuite/newpage_00016.html
新着情報はありませんでした
https://www.mhlw.go.jp/stf/seisakunitsuite/newpage_00016.html
新着情報はありませんでした
https://www.mhlw.go.jp/stf/seisakunitsuite/newpage_00016.html
新着情報はありませんでした
・・・
```

通知が来ました。
![LINE.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/124088/be975bd4-9c84-aee4-a735-0ceb46e833a9.png)

# 改善
Lambdaに上げたり、環境変数をenvファイルに移したり、まだまだ改善の余地はあると思います。
Lambdaに上げて定期実行させるのはやりたいです。