lxml html5parserは、namespaceHTMLElements=False
渡したオプションを無視するようです。私が与えたすべての要素を、(予想される) void 名前空間ではなく、HTML 名前空間に入れます。
問題を再現する簡単なケースを次に示します。
echo "<p>" | python -c "from sys import stdin; \
from lxml.html import html5parser as h5, tostring; \
print tostring(h5.parse(stdin, h5.HTMLParser(namespaceHTMLElements=False)))"
その出力は次のとおりです。
<html:html xmlns:html="http://www.w3.org/1999/xhtml"><html:head></html:head><html:body><html:p>
</html:p></html:body></html:html>
ご覧のとおり、html
要素とそこにある他のすべての要素は、HTML 名前空間にあります。
予想される出力は、代わりに次のようになります。
<html><head></head><body><p>
</p></body></html>
これnamespaceHTMLElements
は html5lib オプションであり、lxml が直接処理するネイティブの lxml オプションではありません。lxml は、html5lib を呼び出して、そのオプションを html5lib に渡して、html5lib が期待どおりに使用できるようにすることになっています。
2016-02-17 更新
lxml html5parser を取得して を尊重する方法をまだ見つけていませんnamespaceHTMLElements
。しかし、明確にするために、代わりに次のように html5lib を直接呼び出すこともできます。
echo "<p>" | python -c "from sys import stdin; \
import html5lib; from lxml import html; \
doc = html5lib.parse(stdin, treebuilder='lxml', namespaceHTMLElements=False); \
print html.tostring(doc)"
詳細
私がすでに知っているいくつかのこと:
- html5lib は、要素を HTML 名前空間に配置する必要があるという要件を
html
含め、HTML 仕様の要件に完全に準拠しています— html5lib はこれを行います - ただし、html5lib は、デフォルトの「要素を HTML 名前空間に
namespaceHTMLElements=False
配置する」動作をオーバーライドするオプションを提供します。html
- html5lib を (lxml ではなく) 直接使用してそれに渡す
namespaceHTMLElements=False
と、すべてが期待どおりに機能しhtml
ます。要素は void 名前空間に入ります。 いくつかのprintfをhtml5libソースにハッキングすると、次のことがわかります。
- lxmlは実際に
namespaceHTMLElements=False
期待どおりに html5lib を呼び出しています - しかし、lxml は html5lib を 2 回呼び出しているようです。
namespaceHTMLElements
namespaceHTMLElements=False
- lxmlは実際に
原因がどこにあるのかについての結論
上記のことから、lxml と html5lib の間のインターフェースに問題があることは明らかです。lxml が html5lib を 2 回呼び出している理由はわかりませんが、何らかの理由で、XHTMLParser
実際に要求していることを実行する前に、最初に独自の新しいインスタンスを作成しようとするためだと思います。独自のインスタンスHTMLParser
。
したがって、html5lib に対して 2 つの呼び出しを行うという事実により、html5lib は、最初の呼び出しの結果のデフォルトの動作を一種の「ロックイン」し、2 回目の呼び出しで検出されたディレクティブnamespaceHTMLElements=True
を無視するようになる可能性があります。namespaceHTMLElements=False
おそらく、そのように 2 つの呼び出しを行うことで、lxml は html5lib のいくつかの仮定を破っているか、実際には html5lib API を設計上意図されていない方法で誤用しています。
あるいは、原因は lxml が html5lib に対して 2 つの別々の呼び出しを行った結果ではなく、html5lib インターフェイスの使用方法に別の問題がある可能性があります。
とにかく、他の誰かがこの問題に遭遇して回避策を持っているかどうか、または少なくともなぜそれが起こっているのかについての洞察を持っているかどうかについて、他の人から聞くことに興味があります.