毎朝自動で降水確率を教えてくれるプログラムを作りました

こんにちは
この度初めてイチからプログラミングをしてみました

毎朝7:30、その日の6時間ごとの降水確率をmacOSの通知機能で教えてくれるプログラムです
うまくいってテンションがかなりHighなのでこの感動を忘れぬようブログに掲載したいと思います

コード

import requests, xml.etree.ElementTree as ET, os

# XMLをwebから取得
def get_xml():
    r = requests.get('https://www.drk7.jp/weather/xml/08.xml')
    r.encoding = r.apparent_encoding
    return r.text

a = get_xml()
# XMLから降水確率を取得
def get_rainfallchance():
    root = ET.fromstring(a) #パース
    area = root.findall(".//area[@id]")  #北部と南部
    south = area[1] #南部エリアのノード
    info = south.findall('.//info[@date]') #南部の7日分
    today = info[0] #南部の今日の分のノード
    period = today.findall('.//period[@hour]') #南部の今日の降水確率(6時間毎)
    return period

#取得した降水確率をテキスト化してリストにappend
rain = get_rainfallchance()
ch = []
for i in rain:
    ch.append(i.text)
    
#通知センターに表示
os.system("osascript -e 'display notification\"{0[0]}%     {0[1]}%     {0[2]}%     {0[3]}%\" with title \"今日の降水確率\"subtitle\"00-06  07~12  13-18  19-24\"'".format(ch))

これを実行すると以下のように通知が出てきます

こんなかんじ

使わせて頂いた気象情報のデータ

今回は、以下のブログ様にて気象庁の気象情報をXML化したものを配布していたので、ありがたく使わせていただきました

気象庁の天気予報情報を XML で配信 - drk7jp

当該XMLは以下のような情報が入っています
(私は茨城県の南部在住のため茨城県XMLを使いました)
f:id:Atc:20180626194353j:plain
茨城の中に南部北部
南部の中に7日分の気象情報
各日毎に、風速気温等が入っています
当該XMLは毎朝6時頃に更新されるらしいので、私が取得すべき情報は当日分の6時間ごとの降水確率となります
つまりコレ↓

<Response [200]>
<?xml version="1.0" encoding="UTF-8"?>
<weatherforecast>
<title>weather forecast xml</title>
<link>http://www.drk7.jp/weather/xml/08.xml</link>

中略

</area>
    <area id="南部">
    <geo>
        <long>140.1714</long>
        <lat>36.1234</lat>
    </geo>
    
    <info date="2018/06/26"> ←操作日
        <weather>くもり</weather>
        <img>http://www.drk7.jp/MT/images/MTWeather/200.gif</img>
        <weather_detail>南西の風 のち 南の風 海上 では 南の風 やや強く くもり 所により 霧</weather_detail>
        <wave>波 1.5メートル のち 2メートル</wave>
        <temperature unit="摂氏">
        <range centigrade="max">31</range>
        <range centigrade="min">19</range>
        </temperature>
        <rainfallchance unit="%">
        <period hour="00-06">0</period> ←コレ
        <period hour="06-12">0</period> ←コレ
        <period hour="12-18">0</period> ←コレ
        <period hour="18-24">10</period> ←コレ
        </rainfallchance>
    </info>

コレを取得して、後はうまい具合お知らせしてくれるようにすればOK

各コードの解説

import requests, xml.etree.ElementTree as ET, os

3つのモジュールを呼び出しています
requestsはwebから情報を取得できるモジュール
osは使用してるos依存の機能をpython越しで使えるモジュール
xml.etree.ElementTreeXMLファイルやテキストを解析して辞書型的なノリで扱えるようにするモジュール

# XMLをwebから取得
def get_xml():
    r = requests.get('https://www.drk7.jp/weather/xml/08.xml')
    r.encoding = r.apparent_encoding
    return r.text

関数get_xml()を定義してます
requestsモジュールで先程のXMLの情報を取得してます
そのままテキスト化したら文字化けしたので、.apparent_encodingエンコーディングしてます
テキスト化されたxmlを返します
requestsについては以下のとおり学びました

atc.hateblo.jp


a = get_xml()
# XMLから降水確率を取得
def get_rainfallchance():
    root = ET.fromstring(a) #パース
    area = root.findall(".//area[@id]")  #北部と南部
    south = area[1] #南部エリアのノード
    info = south.findall('.//info[@date]') #南部の7日分
    today = info[0] #南部の今日の分のノード
    period = today.findall('.//period[@hour]') #南部の今日の降水確率(6時間毎)
    return period

テキスト化したXMLを変数aに入れ、新たに定義した関数の中でaをパースして辞書型的なノリで使えるようにしてます
ここらへんのコードゴッチャゴチャですが、初めてなのでしゃーないしゃーない
その後、公式ドキュメント20.5.2.2. サポートされている XPath 構文にある方法で、今日の降水確率にジリジリ迫ってきています
そして南部の今日の降水確率が格納された変数periodを返してます

#取得した降水確率をテキスト化してリストにappend
rain = get_rainfallchance()
ch = []
for i in rain:
    ch.append(i.text)

取得した今日の降水確率をテキスト化してリストに入れています

#通知センターに表示
os.system("osascript -e 'display notification\"{0[0]}%     {0[1]}%     {0[2]}%     {0[3]}%\" with title \"今日の降水確率\"subtitle\"00-06  07~12  13-18  19-24\"'".format(ch))

ここが最高にテキトーで草生えるコードです、すき間だらけでダサみが深い
os.system()の引数にAppleScriptdisplay notificationコマンドを入れてmacOSの通知センターに通知を出してます
タイトルに今日の降水確率の文字列、サブタイトルに時間帯、メインに降水確率を出力しているのですが、いい具合に時間帯の下に降水確率が来るように調整していたらすきっ歯になりました
プログラミング初心者って感じがして愛おしい😍
なお、os.system()については以下のとおり学んでます

atc.hateblo.jp

後は定期的に実行する

作成したpythonファイルを定期的に実行させたいと思い調べたところ、cronという言葉がでてきました

cronとは? Wikipedia

デーモン(Deamon)と呼ばれるUnix系OSにおいてバックグラウンドで動作するプロセスのうち、コマンドを定期実行するもの。crontabというファイルに定期実行するものの一覧を記録している。

何ができる?

コマンドやファイルなどを定期的に実行させることができる
使い方については以下を参考にしました

qiita.com

実践

  • 編集開始
$ crontab -e

まだ設定していないので何もないっすね
どうやらviエディタとかいう画面らしいっすね
f:id:Atc:20180626185210p:plain

  • 設定方法は以下の通りするらしい
(分)(時)(日)(月)(曜日) 実行するファイルの絶対パス

毎朝7:30なので以下の通り設定
cronは実行される度/var/mail/にメールが溜まっていくらしいので、メールが来ないようにも設定

MAILTO=''
30 7 * * *  python3 /Users/○○○/python/weather_pop/weather_pop.py
  • ちょっと詰まったところ
    ターミナルで上記コマンドを打ち終えたところ、どうやって設定を保存するのかわからなくなってしまった...
    viエディタはaで入力モード、escでコマンドモードに移る
    コマンドモードで:wとすることで保存
    :qとすることでviエディタが終了となる
    以下を参考にしました

https://oxynotes.com/?p=3844

cron 設定 macでいくら調べても保存方法が出てこないので頭を抱えていたのですが、常識なんですね...

おわりに

毎朝降水確率を教えてくれるようになりました
これで安心して布団を干せます. はじめてイチから作ってみましたが、学ぶ度自分の目標に近づく感覚が楽しかったです
次は何作ろ


追記 crontabの設定 2018/06/27

本日7時30分wktkしていたのですが実行されなかったのでMAILTOの設定を消してもう一度7:35に実行させ、ログを取得したところ/bin/sh: python3: command not foundとでていました
パスが通っていないところにpython3があるっぽいので、crontabにフルパスでpython3の在り処を指定してあげたら実行されました ↓参考

ja.stackoverflow.com

30 7 * * * /Users/○○○/.pyenv/shims/python3 /Users/○○○/python/weather_pop/weather_pop.py

なお、python3の在り処は下記コマンドで取得可

$ which python3