渋谷ほととぎす通信

完全趣味でやってるUnityメモ。説明できないところを説明できるようにするための個人ブログ。昨日の自分より少しでも大きくなれるように。。。 ※所属団体とは一切関係がありません

横浜市避難施設XMLをPythonでパースする


前回記事からの続きです。
最低限の機械学習の知識を手に入れるため勉強中。

本書全7章中3章目に入りました。
様々なデータ形式をパースするというテーマのチャプターっぽいです。
初回はXML。

横浜市総務局 防災関連データから、横浜市避難施設のXMLを使わせてもらいます。

【今回の処理フロー】

  1. 避難施設XMLをローカルにダウンロード
  2. ダウンロードしたXMLをBeautifulSoupでパース
  3. BeautifulSoupから指定要素を取り出す

1. 避難施設XMLをローカルにダウンロード

urllib.request.urlretrieve("URL", "保存するファイル名")

urlretrieveメソッドを使ってファイルをダウンロードします。

2. ダウンロードしたXMLをBeautifulSoupでパース

xml = open("保存するファイル名", "r", encoding="utf-8").read()
soup = BeautifulSoup(xml, 'html.parser')

open関数でダウンロードしたxmlをメモリに乗せ、BeautifulSoupでxmlをパースします。

3. BeautifulSoupから指定要素を取り出す

今回ダウンロードしたxmlは以下のような構造になっています。

<Shelter>
  <Name>生麦小学校</Name>
  <Ward>鶴見区</Ward>
  <Address>生麦四丁目15番1号</Address>
  <Notes>被災した住民の避難生活の場所、情報受伝達、備蓄機能を備えた拠点です。</Notes>
</Shelter>
<Shelter>
  <Name>豊岡小学校</Name>
  <Ward>鶴見区</Ward>
  <Address>豊岡町27番地1</Address>
  <Notes>被災した住民の避難生活の場所、情報受伝達、備蓄機能を備えた拠点です。</Notes>
</Shelter>
・・・


以下のように複数要素あるshelterfind_all関数で配列取得し、単一要素はfind関数を使います。

info = {}
for obj in soup.find_all("shelter"):
    name = obj.find('name').string
    ward = obj.find('ward').string
    if not (ward in info):
        info[ward] = []
    info[ward].append(name)


最後に今回のサンプルコードです。


このコードを実行すると以下のように出力されます。

+ 鶴見区
| - 生麦小学校
| - 豊岡小学校
| - 鶴見小学校
| - 潮田小学校
| - 下野谷小学校
| - 市場小学校
| - 平安小学校
| - 末吉小学校
| - 上末吉小学校


BeautifulSoupを使うとxmlパースは簡単ですね。

最後に

XML、JSON、YAML、csv、Excel辺りのパースをこの3章ではパースするそうです。次回まとめてやります。