14
Help us understand the problem. What are the problem?

More than 1 year has passed since last update.

Organization

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

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

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

今回は、

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

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

こんなのをSlackに流してます :point_down:
image.png

Zapの全体像

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

image.png

Zapの詳細

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

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

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

image.png

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

Pythonでデータを加工する

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

image.png

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が空になるため)
image.png

Slackに投稿する

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

以上です :hugging:

参考

Register as a new user and use Qiita more conveniently

  1. You can follow users and tags
  2. you can stock useful information
  3. You can make editorial suggestions for articles
What you can do with signing up
14
Help us understand the problem. What are the problem?