LINEでyahoo天気から好きな地域の天気を通知してもらおう！～PART３～

#前回までの流れ
前回まで行ったこととしては、yahoo天気からスクレイピングで全国地域の天気情報のURLを取得してファイルに書き込むということを行ってきました。

この回で一旦、自分が作成したコードについて全てまとめて説明できればと思います。
では早速行きましょう！

#LINEの登録
「[PythonでLINEに通知を送る](https://qiita.com/hiro-abe/items/e42f857bd6b40bc178a3)」という記事での説明が非常にわかりやすいので引用させていただきます。

#地方一覧と必要な関数の設定
これまでのPARTで取得してきた地方名を表示してみましょう。

```python
import pandas as pd
#DB読み込み
print("どこの天気が知りたいですか？")
weatherDF = pd.read_csv("./database.csv", encoding="cp932")

#地方一覧の表示
chihouList = []
for chihou in weatherDF["地方"]:
   if not chihou in chihouList:
      chihouList.append(chihou)

while True:
   for i, chihou in enumerate(chihouList):
      print(chihou + "・・・" + str(i))
   chihouNum = int(input())
   print(chihouList[chihouNum] + "でよろしいですか？")
   decision =  input("Yes・・・9 / No・・・0" + "\n")
   if decision == "9":
      shikuList = weatherDF.query('地方 == \"' + chihouList[chihouNum] + '\"')["市区町村"].values.tolist()
      for i, sikuchou in enumerate(shikuList):
         print(sikuchou + "・・・" + str(i))
      shikuNum = int(input())
      print(shikuList[shikuNum] + "でよろしいですか？")
      decision =  input("Yes・・・9 / No・・・0" + "\n")
      if decision == "9":
         targetDataDF = weatherDF.query('市区町村 == \"' + shikuList[shikuNum] + '\"')
         targetIndex = targetDataDF.index[0]
         rssurl = targetDataDF.at[targetIndex, "RSS"]
         targetURL = targetDataDF.at[targetIndex, "URL"]
         break
```

ざっとこんな感じです。例外値が入力された際の処理などはまだ書けていないですが、それはアプリケーション編までに改良しておきます。地方の一覧を表示して、知りたい地方の番号を入力→YES：市区町村一覧を表示する、NO：地方の一覧を表示するという流れです。
そして天気が知りたい市区町村がわかれば、そのURLとRSSを取得してきます。

次に天気情報を取得する際に必要な関数です。

```python
import requests, urllib, re
from bs4 import BeautifulSoup
#天気情報WebページのHTMLタグから天気情報を抽出メソッド
def Parser(rssurl):
   with urllib.request.urlopen(rssurl) as res:
      xml  = res.read()
      soup = BeautifulSoup(xml, "html.parser")
      for item in soup.find_all("item"):
         title       = item.find("title").string
         if title.find("[ PR ]") == -1:
            tenki.append(title)
            
#詳細地区URLから当日の降水確率を取得メソッド
def rainProbability(URL):
   res       = requests.get(URL)
   soup      = BeautifulSoup(res.text, 'lxml')
   rain_time = []
   for rt in soup.find_all(class_ = "time")[0].find_all("td"):
      tempList = re.findall(r"\d{1,2}", rt.text)
      rain_time.append(tempList[0]+"時~"+tempList[1]+"時")
   rain_probability = ["0%"if pb.text == "---" else pb.text for pb in soup.find_all(class_ = "precip")[0].find_all("td")]
   returnTextList = "降水確率\n"\
                         "{0:>7} | {4:>4}\n"\
                         "{1:>7} | {5:>4}\n"\
                         "{2:>7} | {6:>4}\n"\
                         "{3:>7} | {7:>4}".format(rain_time[0], rain_time[1], rain_time[2], rain_time[3],
              rain_probability[0].rjust(4, " "), rain_probability[1].rjust(4, " "), rain_probability[2].rjust(4, " "), rain_probability[3].rjust(4, " "))
   return returnTextList

```

関数PaserではRSSから地名やその日の最高気温・最低気温などを取得します。
また、関数rainProbabilityではRSSでは取得できなかった6時間ごとの降水確率を取得してきます。
これでLINEにyahoo天気情報を送る準備ができました。

最終的なソースコードを下記に残します。

```python
import requests, urllib
from bs4 import BeautifulSoup
import re, csv, pandas as pd

#天気情報WebページのHTMLタグから天気情報を抽出メソッド
def Parser(rssurl):
   with urllib.request.urlopen(rssurl) as res:
      xml  = res.read()
      soup = BeautifulSoup(xml, "html.parser")
      for item in soup.find_all("item"):
         title       = item.find("title").string
         if title.find("[ PR ]") == -1:
            tenki.append(title)
            
#詳細地区URLから当日の降水確率を取得メソッド
def rainProbability(URL):
   res       = requests.get(URL)
   soup      = BeautifulSoup(res.text, 'lxml')
   rain_time = []
   for rt in soup.find_all(class_ = "time")[0].find_all("td"):
      tempList = re.findall(r"\d{1,2}", rt.text)
      rain_time.append(tempList[0]+"時~"+tempList[1]+"時")
   rain_probability = ["0%"if pb.text == "---" else pb.text for pb in soup.find_all(class_ = "precip")[0].find_all("td")]
   returnTextList = "降水確率\n"\
                         "{0:>7} | {4:>4}\n"\
                         "{1:>7} | {5:>4}\n"\
                         "{2:>7} | {6:>4}\n"\
                         "{3:>7} | {7:>4}".format(rain_time[0], rain_time[1], rain_time[2], rain_time[3],
              rain_probability[0].rjust(4, " "), rain_probability[1].rjust(4, " "), rain_probability[2].rjust(4, " "), rain_probability[3].rjust(4, " "))
   return returnTextList


#DB読み込み
print("どこの天気が知りたいですか？")
weatherDF = pd.read_csv("./database.csv", encoding="cp932")

#地方一覧の表示
chihouList = []
for chihou in weatherDF["地方"]:
   if not chihou in chihouList:
      chihouList.append(chihou)


while True:
   for i, chihou in enumerate(chihouList):
      print(chihou + "・・・" + str(i))
   chihouNum = int(input())
   print(chihouList[chihouNum] + "でよろしいですか？")
   decision =  input("Yes・・・9 / No・・・0" + "\n")
   if decision == "9":
      shikuList = weatherDF.query('地方 == \"' + chihouList[chihouNum] + '\"')["市区町村"].values.tolist()
      for i, sikuchou in enumerate(shikuList):
         print(sikuchou + "・・・" + str(i))
      shikuNum = int(input())
      print(shikuList[shikuNum] + "でよろしいですか？")
      decision =  input("Yes・・・9 / No・・・0" + "\n")
      if decision == "9":
         #indexが振られるため列名だけを指定しても要素取得不可＞リストにする
         targetDataDF = weatherDF.query('市区町村 == \"' + shikuList[shikuNum] + '\"')
         targetIndex = targetDataDF.index[0]
         rssurl = targetDataDF.at[targetIndex, "RSS"]
         targetURL = targetDataDF.at[targetIndex, "URL"]
         break
      
tenki = []
#line_notify_tokenには自身で登録したトークンを指定
line_notify_token = 'xxxxxxxxxxxxxxxxxx'
line_notify_api = 'https://notify-api.line.me/api/notify'
Parser(rssurl) # 天気予報サイトのHTMLタグから天気情報を抽出
rain = rainProbability(targetURL)#降水確率を取得


#メッセージ内容(見出しと降水確率)
message = tenki[0] + "\n" + rain
payload = {'message': "\n" + message}
headers = {'Authorization': 'Bearer ' + line_notify_token}
#lineにメッセージ送信
line_notify = requests.post(line_notify_api, data=payload, headers=headers)

#メッセージ内容(当日の天気予報のURL)
message = targetURL
payload = {'message': "\n" + message}
headers = {'Authorization': 'Bearer ' + line_notify_token}
#lineにメッセージ送信
line_notify = requests.post(line_notify_api, data=payload, headers=headers)
print("送信完了")

```

ということでこれにて無事にpythonからLINEへyahoo天気の情報を送るプログラムが完成しました。

#おわりに

３パートに分けましたが見返してみるとスクレイピングしかやっていないような、、
一旦完成まで書きたかったので、中途半端ですがpythonからは送れるぞ！と言うことが伝われば良いかなと思いました。
次回の記事では、Herokuを使ってiphoneからやりとりできるところまで仕上げてアップしていく予定ですので、今しばらくお待ちください！

では、ここらへんで。

最後にgithubのURLを貼っておきます。
https://github.com/ryo0819/weather