2

treebuilderをhtml5lib使用してHTML コンテンツを解析しようとしています。lxml注:requestsライブラリを使用してコンテンツを取得していますが、コンテンツは HTML5 です (XHTML で試してみました - 同じ結果)。

HTML ソースを単純に出力すると、問題ないように見えます。

response = requests.get(url)
return response.text

戻り値

<html xmlns:foo="http://www.example.com/ns/foo">

しかし、実際に html5lib で解析すると、奇妙なことが起こります。

tree = html5lib.parse(response.text, treebuilder = 'lxml', namespaceHTMLElements = True)
html = tree.getroot()
return lxml.etree.tostring(html, pretty_print = False)

戻り値

<html:html xmlns:html="http://www.w3.org/1999/xhtml" xmlnsU0003Afoo="http://www.example.com/ns/foo">

ことに注意してくださいxmlnsU0003Afoo

また、辞書には名前空間html.nsmapは含まれず、.foohtml

何が起こっているのか、どうすればこれを修正できるのか、誰かが知っていますか?

後で編集:

これは予想される動作のようです:

使用されている XML API が要素と属性のローカル名に使用できる文字を制限している場合、ツールはすべての要素と属性のローカル名 [...] を、許可されていない文字を置き換えることによって、許可されている名前のセットにマップすることがあります。大文字の U と文字の Unicode コードの 6 桁ではサポートされていません [...] - HTML DOM を情報セットに強制する

4

1 に答える 1

2

いくつかの観察:

from lxml import etree

tree = etree.fromstring(resp_text)
print etree.tostring(tree, pretty_print=True)

html5libそれは、間抜けなxmlnsU0003Afooエラーの有無にかかわらず、あなたが望むことをしているようです。私が使用したテスト HTML では、適切な出力 (フォロー) が得られtree.nsmap'foo'.

<html xmlns:foo="http://www.example.com/ns/foo">
    <head>
        <title>yo</title>
    </head>
    <body>
        <p>test</p>
    </body>
</html>

または、 pure を使用したい場合html5libは、付属の をそのまま使用できますsimpletree

tree = html5lib.parse(resp_text, namespaceHTMLElements=True)
print tree.toxml()

xmlnsこれでアトリビュートが台無しになるわけではありませんが、simpletree残念ながら のようなより強力なElementTree機能が欠けていますxpath()

于 2012-09-03T21:38:58.570 に答える