pythonでスクレイピングして天気予報をGoogleHomeにしゃべらせる

はじめに

myThingsからIFTTT経由で天気予報をテキスト出力して、GoogleHomeに喋らせることをしていたのですが、myThingsのサービスが終了してしまったため、IFTTTの天気予報を利用していたのですが、「今日の天気はPartyCloudyです。」みたいに、帰国子女感が抜けないので、自分でスクレイピングすることにしました。


本記事の前提となる、IFTTTの設定はこちらのリンクでご確認願います。



設定方法

天気予報の情報収集python処理

#作業ディレクトリ作成
mkdir /home/username/myShell/tenki
cd /home/username/myShell/tenki

#仮想環境作成
virtualenv --python python3 tenki
source tenki/bin/activate #プロンプトが(tenki)になる

pip install urllib3
pip install bs4

vim todayTenki.py


まずは環境づくりです。

その後、以下の記事を参考に、天気予報のサイトから情報を取得するpythonコードを書きました。記事はpython2で書かれているので、python3用に書き換えるのに少し苦労しました。

Python Webスクレイピング テクニック集「取得できない値は無い」JavaScript対応@追記あり6/12 - Qiita
# この記事について 本記事はPythonを使ったWebスクレイピングのテクニックを紹介します。 ※お酒飲みながら暇つぶしで書いたので割と適当です。 今回紹介するテクニックを使えれば経験上大体どんな値でも取得でき、これらはRubyだ...



<todayTenki.py>

#coding: UTF-8
import urllib3
from bs4 import BeautifulSoup

#アクセスするURL
url = 'https://tenki.jp/pollen/3/17/4620/14153/'

#URLにアクセスする 戻り値にはアクセスした結果やHTMLなどが入ったinstanceが帰ってきます
http = urllib3.PoolManager()
instance = http.request('GET', url)
instanceからHTMLを取り出して、BeautifulSoupで扱えるようにパースします
soup = BeautifulSoup(instance.data, 'html.parser')

#CSSセレクターを使って指定した場所のtextを表示します
#今日の天気
tenki = soup.select_one('#main-column > section:nth-child(1) > div > section.today-weather > div > div.weather-icon-box > p.weather-telop').text
tenki = 'text=おはようございます。今日の相模原市南区の天気は、' + tenki + '、'
print (tenki)

#今日の気温
kionMAX = soup.select_one('#main-column > section:nth-child(1) > div > section.today-weather > div > div.weather-icon-box > p.pollen-weather-date-value > span.high-temp').text
kionMIN = soup.select_one('#main-column > section:nth-child(1) > div > section.today-weather > div > div.weather-icon-box > p.pollen-weather-date-value > span.low-temp').text
kion = '最高気温は、' + kionMAX + '。最低気温は' + kionMIN + '、'
print (kion)

#今日の降水確率
kosui = soup.select_one('#main-column > section:nth-child(1) > div > section.today-weather > div > div.weather-icon-box > p.pollen-weather-date-value > span.precip').text
kosui = '降水確率は、' + kosui + 'です。'
print (kosui)

#花粉情報
kafun = soup.select_one('#main-column > section:nth-child(1) > div > section.today-weather > div > div.pollen-icon-box > span').text
kafun = '今日の花粉は、' + kafun + 'です。'
print (kafun)

#======================================================================
#アクセスするURL
url = 'https://weather.yahoo.co.jp/weather/jp/14/4620/14153.html'

#URLにアクセスする 戻り値にはアクセスした結果やHTMLなどが入ったinstanceが帰ってきます
http = urllib3.PoolManager()
instance = http.request('GET', url)

#instanceからHTMLを取り出して、BeautifulSoupで扱えるようにパースします
soup = BeautifulSoup(instance.data, 'html.parser')

#洗濯情報
sentaku = soup.select_one('#main > div.indexList > dl.indexList_item.indexList_item-laundry > dd:nth-child(2) > p.index_text').text
sentaku = 'お洗濯は、' + sentaku + ' 。'
print (sentaku)

#傘情報
kasa = soup.select_one('#main > div.indexList > dl.indexList_item.indexList_item-umbrella > dd:nth-child(2) > p.index_text').text
kasa = '、' + kasa + ' 、'
print (kasa)

#洋服情報
yofuku = soup.select_one('#main > div.indexList > dl.indexList_item.indexList_item-clothing > dd:nth-child(2) > p.index_text').text
yofuku = '服装は、' + yofuku + 'です。以上です。今日も元気に頑張りましょう!'
print (yofuku)

簡単に情報を取得できるサイトと取得できないサイトがあるので、途中でurlを変更しています。また、翌日の情報も取りたいので、以下の翌日用のコードも作りました。

<tomorrowTenki.py>

#coding: UTF-8
import urllib3
from bs4 import BeautifulSoup

#アクセスするURL
url = 'https://tenki.jp/pollen/3/17/4620/14153/'

#URLにアクセスする 戻り値にはアクセスした結果やHTMLなどが入ったinstanceが帰ってきます
http = urllib3.PoolManager()
instance = http.request('GET', url)
instanceからHTMLを取り出して、BeautifulSoupで扱えるようにパースします
soup = BeautifulSoup(instance.data, 'html.parser')

#CSSセレクターを使って指定した場所のtextを表示します
#明日の天気
tenki = soup.select_one('#main-column > section:nth-child(1) > div > section.tomorrow-weather > div > div.weather-icon-box > p.weather-telop').text
tenki = 'text=明日の相模原市南区の天気は、' + tenki + '、'
print (tenki)

#明日の気温
kionMAX = soup.select_one('#main-column > section:nth-child(1) > div > section.tomorrow-weather > div > div.weather-icon-box > p.pollen-weather-date-value > span.high-temp').text
kionMIN = soup.select_one('#main-column > section:nth-child(1) > div > section.tomorrow-weather > div > div.weather-icon-box > p.pollen-weather-date-value > span.low-temp').text
kion = '最高気温は、' + kionMAX + '。最低気温は' + kionMIN + '、'
print (kion)

#明日の降水確率
kosui = soup.select_one('#main-column > section:nth-child(1) > div > section.tomorrow-weather > div > div.weather-icon-box > p.pollen-weather-date-value > span.precip').text
kosui = '降水確率は、' + kosui + 'です。'
print (kosui)

#花粉情報
kafun = soup.select_one('#main-column > section:nth-child(1) > div > section.tomorrow-weather > div > div.pollen-icon-box > span').text
kafun = '明日の花粉は、' + kafun + 'です。'
print (kafun)

#======================================================================
#アクセスするURL
url = 'https://weather.yahoo.co.jp/weather/jp/14/4620/14153.html'

#URLにアクセスする 戻り値にはアクセスした結果やHTMLなどが入ったinstanceが帰ってきます
http = urllib3.PoolManager()
instance = http.request('GET', url)

#instanceからHTMLを取り出して、BeautifulSoupで扱えるようにパースします
soup = BeautifulSoup(instance.data, 'html.parser')

#洗濯情報
sentaku = soup.select_one('#main > div.indexList > dl.indexList_item.indexList_item-laundry > dd:nth-child(3) > p.index_text').text
sentaku = 'お洗濯は、' + sentaku + ' 。'
print (sentaku)

#傘情報
kasa = soup.select_one('#main > div.indexList > dl.indexList_item.indexList_item-umbrella > dd:nth-child(3) > p.index_text').text
kasa = '、' + kasa + ' 、'
print (kasa)

#洋服情報
yofuku = soup.select_one('#main > div.indexList > dl.indexList_item.indexList_item-clothing > dd:nth-child(3) > p.index_text').text
yofuku = '服装は、' + yofuku + 'です。以上です。明日も、よろしくお願いいたします。"'
print (yofuku)

内容はほぼ同じで、取得する箇所が違うだけです。

cron実行用のシェルを作成

cronで実行するために、キックするシェルを作ります。
usernameのところは、適宜ご自身の環境に変更ください。


<todayTenki.sh>

#!/bin/bash

#パス通す
export PATH=/home/username/myShell/tenki/tenki/bin:/home/username/.npm-global/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/usr/lib/jvm/java-8-oracle/bin:/usr/lib/jvm/java-8-oracle/db/bin:/usr/lib/jvm/java-8-oracle/jre/bin

#ディレクトリ移動
cd /home/username/myShell/tenki/

#virtualenvの有効化
. /home/username/myShell/tenki/tenki/bin/activate

#python実行
python todayTenki.py > /home/username/Dropbox/IFTTT/Gmail/tenki.txt




<tomorrowTenki.sh>

#!/bin/bash

#パス通す
export PATH=/home/username/myShell/tenki/tenki/bin:/home/username/.npm-global/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/usr/lib/jvm/java-8-oracle/bin:/usr/lib/jvm/java-8-oracle/db/bin:/usr/lib/jvm/java-8-oracle/jre/bin

#ディレクトリ移動
cd /home/username/myShell/tenki/

#virtualenvの有効化
. /home/username/myShell/tenki/tenki/bin/activate

#python実行
python tomorrowTenki.py > /home/username/Dropbox/IFTTT/Gmail/tenki.txt

ポイントは、最後の出力部分で、printの内容をテキストに出力するようにしています。




GoogleHomeで喋らせるシェルの作成

vim /home/username/Dropbox/IFTTT/googleHome.sh



<googleHome.sh>

#!/bin/sh

#ディレクトリ移動
cd /home/username/Dropbox/IFTTT/Gmail

#ファイルを1つ読み込んで、GoogleHomeNotifierで喋らせる。10秒待ってから、ファイルを削除する。
for f in . ; do curl -X POST -d "@$f" http://localhost:8091/google-home-notifier ; rm $f ; sleep 10 ; done

cronの設定

作成したシェルを定期的に起動させるようにします。

crontab -e
#1分毎に監視@Dropboxで新しいテキストファイルが無いか(GoogleHome喋る用)
* * * * * sh /home/username/Dropbox/IFTTT/googleHome.sh

#今日の天気
45 6 * * * sh /home/username/myShell/tenki/todayTenki.sh

#明日の天気
10 20 * * * sh /home/username/myShell/tenki/tomorrowTenki.sh



出力結果は以下のとおりです。
もう少し改善できそうですが、現状できれいに喋ってくれます。

text=おはようございます。今日の相模原市南区の天気は、晴、最高気温は、14℃。最低気温は-1℃、
降水確率は、0%です。 今日の花粉は、多いです。 お洗濯は、洗濯日和になりそう 。 、傘はいりません 、
服装は、コートを着ないと結構寒いです。以上です。今日も元気に頑張りましょう!

終わりに

これで、きれいな日本語で毎朝、毎晩、天気や花粉の情報を話してくれるようになりました。

コメント

タイトルとURLをコピーしました