Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
13
Help us understand the problem. What is going on with this article?
@paranishian

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

More than 1 year has passed since last update.

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

これは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:

参考

13
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
paranishian
フリーランスのエンジニアです。がんばってます。
admin-guild
「Webサービスの運営に必要なあらゆる知見」を共有できる場として作られた、運営者のためのコミュニティです。

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
13
Help us understand the problem. What is going on with this article?