読者です 読者をやめる 読者になる 読者になる

lxmlメモ帳

Python XML

以前、lingrでlxmlをdisっている人を見たとき、その人のペースに巻き込まれて、lxmlってそういうもんだと思い込んでしまいました。
ただ、最近lxmlを使い始めて、なかなかちゃんとしていることが分かってきたので、メモを書き溜めて行こうと思います。というか、オフィシャルなドキュメントの写経に近いのですが。

文字列からElementオブジェクトを生成する

etree.fromstringを使う。

from lxml import etree
el = etree.fromstring("<html><body>spam</body></html>")

整形式XMLでない場合

etree.parseの第二引数にetree.HTMLParser()を指定。

from lxml import etree
el = etree.fromstring("<html><body>spam</html>", etree.HTMParser())

UTF-8エンコードされたXML(風の文字列)

無理やり文字コードを変換するやり方ではなく、XML宣言を補ってやるとよい。

# -*- coding: Shift_JIS -*-
from lxml import etree
content = "<html>スパム</html>"
el = etree.fromstring('<?xml version="1.0" encoding="Shift_JIS"?>' + content)

Elementオブジェクトから(XML)文字列を生成する

etree.tostringを使う。ただし、encodingを指定しないとasciiで出力される。また、encodingを指定したいが、XML宣言は省略したいという場合は、xml_declaration=Falseを指定する。

>>> from lxml import etree
>>> el = etree.fromstring("""<?xml version="1.0" encoding="Shift_JIS"?><html>スパム</html>""")
>>> print etree.tostring(el, pretty_print=True)
<html>&#12473;&#12497;&#12512;</html>
>>> print etree.tostring(el, encoding="Shift_JIS", xml_declaration=False, pretty_print=True)
'<html>スパム</html>'

XPathを使う

xpathメソッドでOK。これが超便利。「空前のXPathブーム」に乗り遅れない!(もう乗り遅れているかもしれない。)

>>> from lxml import etree
>>> el = etree.fromstring("""<?xml version="1.0" encoding="Shift_JIS"?>
<html><body><span>スパム</span></body></html>""")
>>> el.xpath('//span/text()')
[u'\u30b9\u30d1\u30e0']

ノードのテキスト要素だけを取り出す

例えば、

<html>
  spam<br />
  ham<br />
  egg<br />
</html>

から、spam, egg, hamだけを取り出したい場合、itertext()を使うとよい。

>>> from lxml import etree
>>> el = etree.fromstring("""<html>spam<br />egg<br />ham<br /></html>""")
>>> list(x for x in el.itertext())
['spam', 'egg', 'ham']

このメソッドを知らなくてだいぶ時間をロスした!
あるいは、XPathを使う方法もよいかもしれない。

>>> el.xpath('//text()')
['spam', 'egg', 'ham']