今回は、 Pythonによるスクレイピング&機械学習開発テクニック増補改訂 Scrapy、BeautifulSoup、scik [ クジラ飛行机 ]の第3章を参考にさせていただきながら、urllib.request+BeautifulSoupで、Web上から、XMLファイルをダウンロードして解析後、要素を出力できるようになりました。
Docker上に構築した開発環境で実行しています。
Dockerでの開発環境の構築については、過去記事をご参照ください。
では、振り返っていきたいと思います。
今回は、XMLファイルの例として、横浜市の防災拠点のXMLファイルを使いました。 この、XMLファイルをダウンロードして、解析を行った後、区ごとに防災拠点を出力するコードを作っていきます。 コード全体は以下の通りで、「xml-bousai.py」に保存しました。 from bs4 import BeautifulSoup # ①XMLファイルをダウンロード savename = 'shelter.xml' # ➁BeautifulSoupで解析 #③種類ごとにデータを取得 for i in soup.find_all('locationinformation'): if not (ward in info): #④区(ward)ごとに防災拠点を出力 では、コードを順番に見ていきます。 urllib.request(import時にreqに設定)を使って、防災拠点のXMLファイルのURLからファイルをダウンロードして、「shelter.xml」に保存します。 サーバに負荷をかけないように、ダウンロードしたファイルが存在したら新たにダウンロードしないようにします。 url = 'https://www.city.yokohama.lg.jp/kurashi/bousai-kyukyu-bohan/bousai-saigai/bosai/data/data.files/hinanjo.xml' savename = 'shelter.xml' 保存したXMLファイルを読み込んで、BeautifulSoupでXMLを解析します。 openするときに、encordingで文字コード「utf-8」を指定します。文字コードが違っていると文字化けしてしまうので、ダウンロード元の情報を確認して、適切な文字コードを指定する必要があります。 xml = open(savename, 'r', encoding='utf-8').read() 次に、BeautifulSoupで構文解析用のパーサに'html.parser'を指定して、XMLファイルを解析します。 soup = BeautifulSoup(xml, 'html.parser') では、解析された結果「soup」を使って各タグに囲まれた要素を取得していきます。 今回のXMLファイルの内容は以下の通りです。 find_all()メソッドで、すべての<LocationInformation>タグで囲まれた要素を取得して、それぞれの要素 i から、find()メソッドで<Name>,<Ward>,<Adress>,<Definition>タグに囲まれた要素を取得します。(NameとWardしか使いませんが) ここで注意が必要なのは、解析構文用のパーサに'html.parser'を指定して、HTMLとみなして解析しているので、アルファベットの大文字、小文字の区別がなく、すべて小文字で指定する必要がある点です。 info = {} for i in soup.find_all('locationinformation'): また、取得した結果について、辞書形式の info に、区(word)ごとの名称(name)のリストを格納していきます。 if not (ward in info): 最後に、info.keys()で、infoに格納された区(ward)リストを取得して、区(ward)ごとに、防災拠点の名前(name)を出力していきます。 for ward in info.keys(): 先ほど作成したファイルを実行してみます。 python3 xml-bousai.py 以下の通り、XMLファイルを取得・解析して、区ごとの防災拠点を出力できました! これで、Web上に公開されているXML形式のデータについても、巡回して取得できるようになりました。 このほかにも、JSONやYAMLなどいろいろな形式で公開されているデータがあるので、順次、使えるようになっていきたいです。 次回以降も、Pythonによるスクレイピング&機械学習開発テクニック増補改訂 Scrapy、BeautifulSoup、scik [ クジラ飛行机 ]で、スクレイピングと機械学習開発に取り組んでいきたいと思います。 【過去記事】 2019年8月31日(土)にE資格を受験して、合格しました! E資格対策として勉強の進め方や、参考書などをまとめました。 これから受験される方がいらっしゃいましたらご参考まで。 2019年3月9日(土)にG検定を受験し、見事合格できました! 受験の体験記や勉強法などを別のブログにまとめました。 これから受験される方がいらっしゃいましたらご参考まで。 【E資格対策に使った参考書】 XMLを解析して要素を出力する。
1.全体像
import urllib.request as req
import os.path
url = 'https://www.city.yokohama.lg.jp/kurashi/bousai-kyukyu-bohan/bousai-saigai/bosai/data/data.files/hinanjo.xml'
if not os.path.exists(savename):
req.urlretrieve(url, savename)
xml = open(savename, 'r', encoding='utf-8').read()
soup = BeautifulSoup(xml, 'html.parser')
info = {}
name = i.find('name').string
ward = i.find('ward').string
addr = i.find('address').string
note = i.find('definition').string
info[ward] = []
info[ward].append(name)
for ward in info.keys():
print('+', ward)
for name in info[ward]:
print('| -', name)2.XMLファイルをダウンロード
if not os.path.exists(savename):
req.urlretrieve(url, savename)3. BeautifulSoupで解析
4.種類ごとにデータを取得
name = i.find('name').string
ward = i.find('ward').string
addr = i.find('address').string
note = i.find('definition').string
info[ward] = []
info[ward].append(name)5.区(ward)ごとに防災拠点を出力
print('+', ward)
for name in info[ward]:
print('| -', name)5.コマンドラインから実行してみる。