34
57

More than 1 year has passed since last update.

気象庁のAPIを使って気温を取得する。

Last updated at Posted at 2021-04-11

気象庁のWebサイトがリニューアルしたのでWebスクレイピングが出来ず気温が取得できない。

2021年2月16日、気象庁発表より引用:

気象庁ホームページを2月24日13時よりリニューアルします。様々な防災気象情報が一つのページで見やすく確認できるようになるほか、スマートフォンでも見やすくなります。
https://www.jma.go.jp/jma/press/2102/16a/20210216_jmahp_renewal.html

このリニューアルにより、気象庁がアメダス情報を「表形式」(HTML的にはtableタグ)として表示していたデータが無くなり、Webスクレイピングで読み取れなくなりました。

参考までに、今まで表示されていた情報を画像ですが貼っておきます。
SnapCrab_NoName_2020-3-2_23-59-7_No-00.jpg

私はかなり以前より、気象庁のWebサイトから地元の気温を抜き出して自宅Zabbixにデータを貯めていたので、何かしらの対処が必要となりました。
そこで、色々調べてみると非公式のようではありますが、気象庁がAPIを公開(アクセス可能な状態)にしているようでした。
それを使って、埼玉県熊谷市の気象情報を取得するPythonスクリプトを書いてみました。

outside_tmp.py
# -*- coding: utf-8 -*-

# 注意点:
# 例えば12:00にデータが更新される場合、12:00にAPIを叩くとレスポンスjsonが不足している場合がある。
# そのため、crontabなどにより、5分~15分sleepしてから取得した方が良さそう。

import requests
import datetime
import sys

def main():
    # 現在の時刻を取得
    now_raw = datetime.datetime.now()
    now = now_raw.strftime('%Y%m%d%H')

    # エンドポイントに最新時刻のurlを組み込み
    # jsonのファイル名:YYYYMMDDHH0000.json
    url = "https://www.jma.go.jp/bosai/amedas/data/map/" + now + "0000.json"
    header = {"content-type": "application/json"}
    # 正しいjsonが返って来た場合のみ処理し、正しくないjsonの場合はエラーとする。
    try:
      response = requests.get(url, headers=header)
      data = response.json()

      # 熊谷のコード(43056)の各種情報をjsonから取得する
      temperature = data["43056"]["temp"] # 気温
      pressure = data["43056"]["pressure"] # 気圧
      humidity = data["43056"]["humidity"] # 湿度
      visibility = data["43056"]["visibility"] # 視程(単位不明)
      windDirection = data["43056"]["windDirection"] # 風16方位
      wind = data["43056"]["wind"] # 風速(m/s)

      # 各データを/tmp/配下に格納する
      with open('/tmp/temperature', mode='w') as f:
        f.write(str(temperature[0]))

      with open('/tmp/pressure', mode='w') as f:
        f.write(str(pressure[0]))

      with open('/tmp/humidity', mode='w') as f:
        f.write(str(humidity[0]))

      with open('/tmp/visibility', mode='w') as f:
        f.write(str(visibility[0]))

      with open('/tmp/windDirection', mode='w') as f:
        f.write(str(windDirection[0]))

      with open('/tmp/wind', mode='w') as f:
        f.write(str(wind[0]))

    except KeyError:
      pass

if __name__ == '__main__':
   main()

スクリプト内の「43056」は熊谷のコードです。エリアコードの取得方法はjsonを追うかググれば見つかりますので、そちらをご活用ください。
一つ引っかかった点として、jsonのファイル名が変動するところです。

https://www.jma.go.jp/bosai/amedas/data/map/20210411050000.json

上記では20210411050000.jsonが以下のように分割されます。
2021年04月11日05時 + 0000

最後の0000は、分・秒と推測されます。今後は毎分・毎秒単位でデータの更新があるのかもしれません。

今のところ特にtokenなどは無いようなのですが、上記を参考にされる方は節度を守った上でのアクセスをご考慮ください。
上記スクリプトは実行結果をファイルに書き出すだけのスクリプトです。書き出したファイルをzabbixに読み込ませています。

# crontab -l
15 */1 * * * /usr/bin/python3 /usr/local/src/weather/outside_weather.py > /dev/null 2>&1

このスクリプトを各n時間15分に取得しています。1:15 -> 2:15 -> 3:15 ...
※1:00などピッタリの時間だと、更新漏れが発生する可能性があるため15分後ろ倒しにしてます。

Zabbixでの取れ方

こんな感じになっています。
SnapCrab_NoName_2021-4-11_20-18-40_No-00.jpg

まとめ

  • この情報は気象庁より公式的にアナウンスされていないため、APIの仕様が突然変わる可能性があります。
  • APIは正式に気象庁から外部へ公開されたものではありません。業務で利用する場合は気象庁へお問い合わせください。
  • Python初心者なので、コードにツッコミがあればガンガンお願いします。ファイル書き出しのところ、もう少し綺麗に出来そうな気がします…。

追記(2023/07/08)

2023/07/08現在でも上記スクリプトで情報が取得出来ています。また、熊谷市のデータは1hごとに更新されています。

34
57
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
34
57