python: デフォルト機能でXMLを解析する

Python 3.9.6 で確認。

Pythonにデフォルトで備わっている xml.etree.ElementTree を用いることで簡易的なXML解析が可能。名前が長いので、公式ドキュメントでもエイリアスを使用している。

準備

必要なライブラリを import するには以下。

import xml.etree.ElementTree as ET

ファイルから読み出すなら

tree = ET.parse('test_data.xml')
root = tree.getroot()

あるいは文字列から読みだすなら

root = ET.fromstring(test_data_str)

という形でアクセスできる。

具体例

具体的な利用例を見てみる。例えば、Yahooニュースの主要トピックRSSから主要なニュースを取り出し、表示してみる。

URLへのアクセスに requests を利用している。 pip install requests で導入可能。

import xml.etree.ElementTree as ET
import requests

res = requests.get('https://news.yahoo.co.jp/rss/topics/top-picks.xml')
# res.contentにデータが格納されている。
# データはUTF-8としてdecodeする必要がある。
root = ET.fromstring(res.content.decode('utf-8'))
items = root.findall('./channel/item')
for item in items:
  title = item.find('title').text
  print(f'{title}')

findall により、指定した XPath に該当する要素をすべて取り出すことができる。XPathは、 簡単に使う分にはXMLの木構造をディレクトリ構造のような文字列で表したもの、と思えば差し支えない。

YahooのRSSでは <rss> (これが上記プログラム中の root )という要素の下に <channel> があり、その下に各ニューストピックが複数の <item> として存在するので "./channel/item" を findall することでニュースの要素一覧が取れる。

そのあと、各記事の題名を取りたいので、題名を示す子要素を find により XPath 指定で取り出している。 find は 1つだけの要素を返す。また、 text はそのタグに挟まれた文字列を返す。

名前空間のある時

Google のRSSなどで見かけたのだが、名前空間が定義されている場合がある。名前空間が定義されている場合には辞書型で名前空間とエイリアスの一覧を定義したものを事前に用意しておき、 findfindall の引数として渡してあげる必要がある。参考

コメント

このブログの人気の投稿

gnuplot: グラフの色を変更する

[Linux] rsyncで進捗を確認する

gnuplotで縦線を引きたい