Help us understand the problem. What is going on with this article?

気象庁防災XMLのPull型提供(Atom Feed)について

最初に要点:

  • 更新監視は HTTP If-Modified-Since を使って効率的に取得しましょう。
  • 更新監視を毎分起動するならば、毎分20秒から始めるといいことあるかも。

2019-09-27追加情報があります(品質について): https://qiita.com/e_toyoda/items/2942903d406ed96c6bed

はじめに

気象庁防災情報XML形式によるデータ公開は、2012年12月17日から始まった WebSub プロトコル(旧称PubSubHubub)による PUSH 型提供に加えて、2017年3月からは Atom Feed により HTTPS GET だけで構築できる PULL 型提供が行われています。

WebSub と異なり、利用者側で HTTP サーバを立ち上げて情報セキュリティリスクを背負い込む必要はありません。利用者機器は24時間稼働していなくても大丈夫です。通信遅延や情報抜けは問題ないように調整しました(近く報告します)。お試しください。

フィード一覧

名称 高頻度フィード 長期フィード 内容
定時 regular.xml regular_l.xml 気象に関する情報のうち、天気概況など定時に発表されるもの
随時 extra.xml extra_l.xml 気象に関する情報のうち、警報・注意報など随時発表されるもの
地震火山 eqvol.xml eqvol_l.xml 地震、火山に関する情報
その他 other.xml other_l.xml 上記3種類のいずれにも属さないもの

HTTPS にしてもいいです。

高頻度・長期フィード2種類の使い分け

  • 通常は高頻度フィードを使います。
    • 高頻度フィードは毎分更新されており、少なくとも直近10分間の更新情報が記載されています。
  • 長期フィードは、1時間に1回更新されており、直近数日間の更新情報が記載されています。
    • これは(10分以上の)長時間にわたって止まっていた利用システムを最新状況に追随するために設けられています。たとえば利用者側システムが平日昼間保守になっていて、金曜夜に障害停止したシステムを月曜日に復旧するような場合を想定して、長時間の更新情報を提供することにしています。
    • ファイルが大きいので、常時ウォッチするとしんどいです。

フィードの監視

フィードの URL に繰り返し HTTP GET 要求をすれば、Atom Feed 形式のファイルが取れるわけですが、ただ単に wget url で取得するのはちょっと待ってください。

  • wget コマンドであれば、 -N オプションで、既存ファイルより新しい場合にだけダウンロードが行われます。
  • curl コマンドであれば、 -z オプションで、既存ファイルより新しい場合にだけダウンロードが行われます。

これらは内部で If-Modified-Since ヘッダを付けて条件付き HTTP 要求を行い、ファイルが更新されていた場合にだけダウンロードするものです。みなさんのシステムの負荷軽減にもなりますし、正直言うと気象庁の経費的にも助かります。どうかご協力ください。

更新タイミング

気象庁として保証するわけではありませんが、経験上、フィードのファイルは毎分20秒頃に新しいものが見えるようになるようです。フィード取得プログラムを Linux の cron で毎分起動しているならば、先頭に sleep 20; を入れてください。それだけで1分早くデータが取れるようになります。

20より小さい数字を指定すると僕より秒単位で早く取れると思いましたか? 数秒早く要求しすぎると、古いレスポンスが返ってきてしまいます。その後60秒間はあなたのお使いのプロバイダの近くの CDN キャッシュサーバが古い応答を返し続けますから、たぶんお得にはなりません。

Atom フィードの解析

Atom フィードは RFC 4287 https://tools.ietf.org/html/rfc4287 で規定されています。もちろん大真面目にやっていただいていいんですが、気象庁として保証するわけではありませんが、要は

  • ファイルの中から「<link type="application/xml" href="http://www.data.jma.go.jp/略/なんとか.xml"/>」となっている所を全部抽出
  • 初めて見る URL があったらダウンロードする

という雑なロジックでも動きます。なぜかというと次のように作られているからです。

  • 個々の電文についてUUIDを割り当ててURLを生成
  • たとえ同一内容でも複数回受信したら別URLとなるので、 <updated> タグをチェックして更新されていたら再取得する必要はない

(なぜ電文のファイル名にUUIDみたいな意味不明なものを使っているかというと、ズバリ意味不明なのがミソで、通番や電文種別などで予測できるファイル名にすると、皆さん1秒でも早くほしいのでダメ元で取りに来られるので、404エラーログだけでディスクフルになってしまいかねないからです。申し訳ありませんが、迅速取得に王道はありません。AtomフィードからURLを取得して電文本体を取るようにしてください。)

最低限の取得スクリプト例

  • わかりやすいようにシェルスクリプトです。長時間試験していません。
  • 電文は /tmp (環境変数 $outdir で変更可能) に吐き出されます。
  • 電文が取得済みかどうかは、ファイルがそこにあることでチェックしています。
    • 当然ながら放置すると膨大なファイル数になります
    • この方法では、たとえ古いファイルを消してもディレクトリファイルが巨大化したり嫌なことになるので、真面目にはDBMSか何か使って、取得結果の電文数が増えていっても困らないようにしてください。言いましたからね
  • 毎分cronで起動するのが念頭にあり、先頭に20秒sleepが入れてあります。
  • SSL証明書ディレクトリ /etc/ssl/certs ($ca で変更可能) があればHTTPSを使います。これにより偽サイトからデータを食わされる心配は減じるでしょう。
#!/bin/sh
PATH=/bin:/usr/bin

: ${ca:='/etc/ssl/certs/'}
: ${outdir:=/tmp}
: ${magic:=20}
: ${feeds:='regular extra eqvol other'}

cd $outdir
if test -d $ca; then
  scheme=https
  caflag="--ca-directory=${ca}"
else
  scheme=http
  caflag=''
fi
server="${scheme}://www.data.jma.go.jp/developer/xml/feed"

sleep ${magic}

if test -f url.txt; then
  echo url.txt exists
  exit 0
fi
trap "rm -f url.txt" 0

for feed in ${feeds}
do
  feedurl="${server}/${feed}.xml"
  wget -qN ${caflag} ${feedurl}
  : > url.txt
  sed -n '/<link type="app/{s/.*href="//; s/".*//; p}' ${feed}.xml | while read url
  do
    base=`basename ${url}`
    if test ! -f $base; then
      echo $url >> url.txt
    fi
  done
  wget -qi url.txt
  : use data here
done

なお、このファイルを含め、実験に使っている取得ファイルを
https://github.com/etoyoda/feedfollow
に置いておきます。

e_toyoda
※発信は自らが所属する組織の見解を示すものではありません。
http://twitter.com/e_toyoda
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
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  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
ユーザーは見つかりませんでした