気象庁から情報を取得して東京23区の気象警報をSlackに通知する


どーも、おはこんばんちわ!

これはZapier Advent Calendar 2019 5日目の記事です。

今回は、

  • 23区の気象警報をいち早く察知したい!
  • サードパーティのAPIではなく、より確からしい情報を参照したい!

という要望のもと、ちょっとしたZapをつくったので紹介させてもらいます。

こんなのをSlackに流してます

Zapの全体像

気象情報の取得には気象庁提供のデータを使い、フィルタリングしたりPythonでうまいことパースしたりしてSlackに通知します。

Zapの詳細

フィードを取得してフィルタリングする

今回は、随時更新されるフィード
http://www.data.jma.go.jp/developer/xml/feed/extra.xml
を使います。

参照:気象庁 | 気象庁防災情報XMLフォーマット形式電文(PULL型)

ただ、このままだと災害情報以外にもいろんなものが含まれているのでフィルタリングします。
ここではタイトルが「気象特別警報・警報・注意報」の場合のみ次ステップに移行させています。

Pythonでデータを加工する

ZapierではJavaScriptかPythonのコードを実行できるんですが、xmlのパースにはPythonを使ったほうが良さそうだった(というかJavaScriptでは厳しそう)ので初めて書いてみました。

from xml.etree import ElementTree
response = requests.get(input_data['url'])
response.encoding = 'utf-8'
root = ElementTree.fromstring(response.text)

output = {'text': ''}
for item in root.findall('./{http://xml.kishou.go.jp/jmaxml1/body/meteorology1/}Body/{http://xml.kishou.go.jp/jmaxml1/body/meteorology1/}Warning/{http://xml.kishou.go.jp/jmaxml1/body/meteorology1/}Item'):
  code = item.find('./{http://xml.kishou.go.jp/jmaxml1/body/meteorology1/}Area/{http://xml.kishou.go.jp/jmaxml1/body/meteorology1/}Code')
  if code.text == '130011' or code.text == '130012':
    area_name = item.find('./{http://xml.kishou.go.jp/jmaxml1/body/meteorology1/}Area/{http://xml.kishou.go.jp/jmaxml1/body/meteorology1/}Name')
    list = []
    for kind in item.findall('./{http://xml.kishou.go.jp/jmaxml1/body/meteorology1/}Kind'):
      kind_text = ''
      kind_name = kind.find('./{http://xml.kishou.go.jp/jmaxml1/body/meteorology1/}Name')
      if kind_name is None:
        continue
      if not '警報' in kind_name.text:
        continue
      kind_text += kind_name.text + ':'
      kind_status = kind.find('./{http://xml.kishou.go.jp/jmaxml1/body/meteorology1/}Status')
      kind_text += kind_status.text
      list.append(kind_text)
    if not list:
      continue
    text = '【' + area_name.text + '】' + '、'.join(list)
    print(text)
    output['text'] = output['text'] + text + "\n"

やってることは、

  • 23区の情報だけ処理する
    • 地域コードが130011130012
  • 警報情報だけ処理する
  • slack投稿用に整形したものをtextにぶちこむ

です。Pythonというよりはxmlのnamespaceに結構苦戦しました。。

さらにフィルタリング

textが存在するか」でフィルタリングします。
(該当する情報がない場合はtextが空になるため)

Slackに投稿する

あとはそのtextを所定のチャネルに投稿すればOKです。

以上です

参考