xml.etree
がない¶
Python で XML を扱う有名なライブラリの一つに ElementTree
があります。 ElementTree
が Python 2.5 で標準ライブラリに
取り込まれたときに xml.etree
という名前に変わりました。
xml.etree
(または ElementTree
) を使う場合、
実装やバージョンの違いによってモジュール名が異なるため、
様々な環境でも動くように最大限考慮すると
モジュールのインポートは非常に複雑になります。
try:
# lxml.etree
from lxml import etree
except ImportError:
try:
try:
# cElementTree on Python 2.5+
import xml.etree.cElementTree as etree
except ImportError:
# ElementTree on Python 2.5+
import xml.etree.ElementTree as etree
except ImportError:
try:
# cElementTree
import cElementTree as etree
except ImportError:
# ElementTree
import elementtree.ElementTree as etree
まず最初に lxml がインストールされているかどうかを
チェックしています。
lxml
は高速で使いやすい XML ライブラリで、
ElementTree と互換性のある API を持っています。
そのため lxml
がインストールされている環境ではそれを使います。
ElementTree
には、動作がより高速な C 拡張版の cElementTree
があります。
標準ライブラリにもそれに対応して xml.etree.ElementTree
と
xml.etree.cElementTree
という 2 種類のモジュールがあります
(Python 3 では xml.etree.cElementTree
が廃止されるそうです)。
これらを順にインポートできるかどうか試していき、最初に見つかった
ライブラリを使用します。
ただ、ここまでやるのは一部の本当に広く使われるソフトウェアだけで、
普段はそこまで気にすることは稀です。
個人的には、常に lxml
を使えば良いと思います。
これだけだと Python 2.4 で xml.etree
がなくても別に困らない、
という結論で終わってしまうので、 XML (と関連して HTML) を
パースする場合の tips を書いてお茶を濁します。
1) xml.dom.pulldom
は使える¶
XML を処理する方式には DOM と SAX の2種類ありますが、このライブラリは その両方の良いところを合わせたようなものです。 SAX イベントの途中で現在のノードから下の DOM ツリーを構築することが可能で、 XML から一部の情報を取り出す処理を簡単に書くことができます。
pulldom を使う例:
from xml.dom import pulldom
doc = pulldom.parse('items.xml')
for event, node in doc:
if event == pulldom.START_ELEMENT and node.tagName == 'item':
if int(node.getAttribute('price')) > 50:
doc.expandNode(node)
print(node.toxml())
xml.dom.pulldom
は Python 2.4 の標準ライブラリに含まれています。
2) BeautifulSoup
は使える¶
タグが閉じられていないような壊れた HTML は、純粋な XML パーザや SGML パーザではうまく扱えません。 BeautifulSoup は、 ウェブブラウザと同じようにヒューリスティックを使用して 壊れた HTML も可能な限り修復してくれるので、 インターネットからダウンロードした大量の HTML をパースするような場合に 非常に重宝します。
さらに lxml.html
と BeautifulSoup
を組み合わせて使うための
lxml.html.soupparser
というモジュールもあります。
HTML のスクレイピングをする場合に、これと後述する cssselect()
を
使うのが最強の組み合わせだと思います。
3) lxml.html
の cssselect()
は使える¶
ElementTree
では XPath を使って DOM ツリーの中から特定のノードを
検索することができますが、 lxml.html
の場合は XPath の代わりに
CSS でも検索ができます。内部では CSS を XPath に変換しているだけですが、
使ってみるととても使いやすいのでお勧めです。