🌊

Pythonで気象庁の津波情報(XML電文)をパースする

2023/05/02に公開

津波情報のXMLをパースする

気象庁のサイトには気象庁防災情報XMLフォーマット形式電文が公開されていて、一般の人でも取得することができる。
ここでは気象全般の情報、地震津波火山情報なども提供されている。

そこで、Pythonを使ってXML電文をパースしてみた。

実際のXML電文の構造

2022年1月トンガ噴火に伴う地球規模の津波発生により奄美大島、トカラ列島に津波警報が発表されたときの実際の電文が以下のサイトでアーカイブされている。

http://agora.ex.nii.ac.jp/cgi-bin/cps/report_xml.pl?id=20220115151519_0_VTSE41_010000

実際にパースしてみる

準備

Pythonにはxmlを読み込むためのライブラリがある。
それをimportする。

import xml.etree.ElementTree as ET

今回はファイルからパースを行う。
とりあえずXMLのrootを取得する

tree = ET.parse(FilePath)
root = tree.getroot()

津波情報をパース

気象庁のXML電文(津波)は

root>Body>Tunami>Forecast>Item

の中に実際の情報が入っている。

<Item>
    <Area>
        <Name>奄美群島・トカラ列島</Name>
        <Code>772</Code>
    </Area>
    <Category>
        <Kind>
            <Name>津波警報</Name>
            <Code>51</Code>
        </Kind>
        <LastKind>
            <Name>津波予報(若干の海面変動)</Name>
            <Code>71</Code>
        </LastKind>
    </Category>
(中略)
    <MaxHeight>
        <jmx_eb:TsunamiHeight type="津波の高さ" unit="m" description="3m">3</jmx_eb:TsunamiHeight>
        <Revise>更新</Revise>
    </MaxHeight>
</Item>

Itemは繰り返し要素になっていて、エリア別にItemが追加されている。

エリアを取得

津波情報が発表されているエリア情報は

root>Body>Tunami>Forecast>Item>Area>Name

の中にあるので、これをパースする。

エリア取得コード

 #XMLのルート取得
        #ルート取得
        tree = ET.parse(FilePath)
        root = tree.getroot()
        #津波警報・注意報の対象エリア抽出
        tsunamiWarningAreaList =[] #地域リスト
        #NameSpace
        ns ="{http://xml.kishou.go.jp/jmaxml1/body/seismology1/}"
        #エリア取得
        for area in root.findall(ns + "Body/"+
                              ns + "Tsunami/"+
                              ns + "Forecast/"+
                              ns + "Item/"+
                              ns + "Area/"+
                              ns + "Name"):
            tsunamiWarningAreaList.append(area.text)
            print(area.text)

Itemが繰り返し要素なので、findall()を使って全要素取得する。
テキストはhoge.textで取得できる。
tsunamiWarningAreaListに結果を追加し、全要素積み込む。

また、各タグ名の前にNameSpaceを追加する必要がある。これに気づくのに3日ぐらいかかった。

実行結果

奄美群島・トカラ列島
北海道太平洋沿岸東部
北海道太平洋沿岸中部
北海道太平洋沿岸西部
青森県日本海沿岸
青森県太平洋沿岸
・・・(略)

津波情報が発表されているエリアを取得できた。

警報種別を取得

津波情報の警報種別を取得する。上記と同様に

root>Body>Tunami>Forecast>Item>Category>Kind>Name

の中にあるので、これをパースする。

 #XMLのルート取得
        #ルート取得
        tree = ET.parse(FilePath)
        root = tree.getroot()

        tsunami_LevelList = [] #地域別警報種別

        #NameSpace
        ns ="{http://xml.kishou.go.jp/jmaxml1/body/seismology1/}"
        #エリア取得
        #エリア別警報種別取得
        for kind in root.findall(ns + "Body/"+
                              ns + "Tsunami/"+
                              ns + "Forecast/"+
                              ns + "Item/"+
                              ns + "Category/"+
                              ns + "Kind/"+
                              ns + "Name"):
            tsunami_LevelList.append(kind.text)

実行結果

津波警報
津波注意報
津波注意報
津波注意報
津波注意報
津波注意報
津波注意報
・・・(略)

津波情報の警報種別を取得できた。

実際のコード

以上のコードを整理してXML電文をパースして津波情報を取得するプログラムを作った。

https://gist.github.com/yhstvhd/4be4252eaa5f47e0f622c97ed9593594

実行結果

■■津波情報■■ 津波警報 今すぐ高台へ避難  【津波警報】奄美群島・トカラ列島【津波注意報】北海道太平洋沿岸東部【津波注意報】北海道太平洋沿岸中部【津波注意報】北海道太平洋沿岸西部【津波注意報】青森県日本海沿岸【津波注意報】青森県太平洋沿岸【津波注意報】岩手県【津波注意報】宮城県【津波注意報】福島県【津波注意報】茨城県【津波注意報】千葉県九十九里・外房【津波注意報】千葉県内房【津波注意報】伊豆諸島【津波注意報】小笠原諸島【津波注意報】相模湾・三浦半島【津波注意報】静岡県【津波注意報】愛知県外海【津波注意報】伊勢・三河湾【津波注意報】三重県南部【津波注意報】和歌山県【津波注意報】徳島県【津波注意報】高知県【津波注意報】宮崎県【津波注意報】鹿児島県東部【津波注意報】種子島・屋久島地方【津波注意報】沖縄本島地方【津波注意報】大東島地方【津波注意報】宮古島・八重山地方【津波予報(若干の海面変動)】東京湾内湾【津波予報(若干の海面変動)】大分県豊後水道沿岸【津波予報(若干の海面変動)】鹿児島県西部  今すぐ高台へ避難

あとがき

かなり前から作っていたが、難しかった...。

参考サイト

https://qiita.com/yoho/items/d2d59f52bb3d7f04001b

Discussion