プログラミング素人のはてなブログ

技術屋の末端。プログラミングも電気回路も専門外です。 コードに間違いなど見つけられたら、気軽にコメントください。 VC#、python3、ラズパイ始めました。

今年も水不足が起きないか心配になる季節がやってきたのでダムの貯水率をつぶやくbotを作った

f:id:s51517765:20180729213935p:plain
7月も例年通り「例年に無い」暑さでしたね。
暑くなってくると、「水不足になるんじゃないか?」と心配になります。
節水制限ですめばまぁいいとしても、断水になんてなったら…。

私のなかでは1994年(平成6年)の時の水不足が印象的です。
平成6年渇水 - Wikipedia

現在のダムの貯水状況は各種HPで確認できて、東京(関東)の状況は東京都水道局のHPで確認できます。
www.waterworks.metro.tokyo.jp

そこで、貯水状況を取得してTweetするbotを作ってみました。
今回はBeautifulsoupを使うことで表組を取得し、ダイジェストとして3水系(利根川、荒川、 多摩川)の合計貯水率tweetします。

beautifulsoupのインストールは以下でできます。

$ pip3 install beautifulsoup4

東京都水道局のHPでは3水系にわかれて表組(table)になっています。
表組は、Chromeの右クリックから「検証」を使うとtbl-c2というクラスになっていることが分かります。
Beautifulsoupでは表組も取得できます。

tables = html.findAll("table", {"class": "tbl-c2"})

取得するデータは、以上合計前年同日量前々年同日量の「貯水率(%)」となります。
3水系(利根川、荒川、 多摩川)あるので、3x3のlistとしてデータを取得します。
listはデータがない状態として、”-”で初期化した3x3のlistを作ります。

dam_list=["-" ,"-" ,"-" ],["-" ,"-" ,"-" ],["-" ,"-" ,"-" ]

表組(table)のなかのセルは"td"というタグで取得できます。

rows = table.findAll("td")

何番目のセル、という形で指定してもいいですが、もしダムが増えても使えるようにしようと思います。
そのためには、以上合計の次にある100以下の数値、前年同日量の次にある100以下の数値、前々年同日量の次にある100以下の数値、を取得すれば実現できます。

ここで出てくるのが正規表現です。
貯水率は100未満(100もあるのかな?あるとしても起きる可能性はきわめて低いので無視しても実質的には問題ないはず)で、少数点以下1桁の数値です。
これを正規表現で表現すると↓になります。

per = re.match('[0-9]{2}\.[0-9]{1}', row.text).group(0)

[0-9]{2}は0~9の数字が連続して2つ、\.はバックスラッシュでエスケープしたピリオド、[0-9]{1}は0~9の数字が1つです。
これで、99.9以下の少数が表現できます。
取得した数字をlistに格納していきます。
該当が見つからなければ、Noneとなり、このときはlistへの格納をしないようにすると、初期化したままの”-”になります。

これを、一つの文字列にします。
twitterでは"\n"の改行コードを入力すれば改行を使うことができます。
これを利用して、簡単な表組をTweetすることができます。
(ちなみに、初期のTwitterには改行はなかったですよね。)

    text="今日のダム貯水率(%)【東京都水道局エリア】""\n"
    text+="             今日   前年   前々年""\n"
    text+="利根川水系   "+dam_list[0][0]+"   "+dam_list[0][1]+"   "+dam_list[0][2]+"\n"
    text+="荒川水系     "+dam_list[1][0]+"   "+dam_list[1][1]+"   "+dam_list[1][2]+"\n"
    text+="多摩川水系   "+dam_list[2][0]+"   "+dam_list[2][1]+"   "+dam_list[2][2]+"\n"

これをtweepyでtweetします。

コード全体

from bs4 import BeautifulSoup

def dam_tokyo():
    print("ダム beautiflsoup")
    url="https://www.waterworks.metro.tokyo.jp/suigen/suigen.html"
    html = urllib.request.urlopen(url)
    html = BeautifulSoup(html, "html.parser")

    tables = html.findAll("table", {"class": "tbl-c2"})

    #"利根川  荒川   多摩川"
    dam_list=["-" ,"-" ,"-" ],["-" ,"-" ,"-" ],["-" ,"-" ,"-" ]
    i = 0

    for table in tables:
        rows = table.findAll("td")
        zennen = False
        zen2nen = False
        today=False
        for row in rows:
            try:
                if row.text=="以上合計":
                    today=True
                if row.text=="前年同日量":
                    zennen=True
                if row.text=="前々年同日量":
                    zen2nen = True
                if zen2nen==True:
                    per = re.match('[0-9]{2}\.[0-9]{1}', row.text).group(0)
                    if per!=None:
                        print("前々年同日量")
                        print(per)
                        dam_list[i][2]=per
                elif zennen==True :
                    per = re.match('[0-9]{2}\.[0-9]{1}', row.text).group(0)
                    if per!=None:
                        print("前年同日量")
                        print(per)
                        dam_list[i][1] = per
                elif today==True:
                    per = re.match('[0-9]{2}\.[0-9]{1}', row.text).group(0)
                    if per!=None:
                        print("今日")
                        print(per)
                        dam_list[i][0] = per
            except:
                pass
        i += 1
    print(dam_list)
    print("-----")

    text="今日のダム貯水率(%)【東京都水道局エリア】""\n"
    text+="             今日   前年   前々年""\n"
    text+="利根川水系   "+dam_list[0][0]+"   "+dam_list[0][1]+"   "+dam_list[0][2]+"\n"
    text+="荒川水系     "+dam_list[1][0]+"   "+dam_list[1][1]+"   "+dam_list[1][2]+"\n"
    text+="多摩川水系   "+dam_list[2][0]+"   "+dam_list[2][1]+"   "+dam_list[2][2]+"\n"
    text+="詳しくは→ https://www.waterworks.metro.tokyo.jp/suigen/suigen.html"
    print(text)

    api.update_status(text) #tweepyでtweet

関連記事

s51517765.hatenadiary.jp
s51517765.hatenadiary.jp