为什么lxml.html有时会吞下/删除空格而不是保留空格?

时间:2016-03-15 06:23:39

标签: lxml libxml2 lxml.html

考虑到下面的代码,人们可能会合理地期望几乎完全相同的HTML字符串被送入lxml吐出来。

from lxml import html

HTML_TEST_STRING = r"""
<pre>
<em>abc</em>

<em>def</em>

<sub>ghi</sub>

<sub>jkl</sub>

<em>mno</em>

<em>pqr</em>

</pre>
"""

parser = html.HTMLParser( remove_blank_text=False )
doc = html.fromstring( HTML_TEST_STRING, parser=parser )
print( html_out_string )

相反,即使所有内容都包含在<pre>预先格式化的代码块中,并且remove_blank_text标志设置为False也只考虑保留空白内容的 ,但内容的其他部分神秘 。请参阅以下代码的意外输出:

<pre>
<em>abc</em>

<em>def</em>

<sub>ghi</sub><sub>jkl</sub><em>mno</em>

<em>pqr</em>

</pre>

具体来说,每当lxml遇到<sub>标记时,它就会变得很糟糕并且丢失了sub元素之后的“尾部”文本内容即使这样“sub元素”可以说甚至不是一个元素 - 因为它包含在pre元素中。)

1 个答案:

答案 0 :(得分:2)

这种奇怪行为的最可能的催化剂是,像我一样,你在Windows上使用的是Python版本,lxml不会发布二进制包。

在这种情况下,one portion of the lxml website将您指向official unofficial Windows binaries for libxml2,以便[可能通过pip安装脚本]可以构建一个支持您的 Python的新lxml二进制文件版。但问题是它链接到你的二进制文件至少有4年并包含你遇到的错误。

解决此问题的最简单方法是下载然后安装Christoph Gohlke's unofficial binary archive(一个所谓的“wheel”)lxml,它实际上是为您的OS / Python变体而构建的。 (lxml网站的另一部分也推荐这个,但是如果你像我一样,你忽略了这条路径,想要尽可能少地运行非官方的二进制代码。)

(例如pip3 install --upgrade lxml-3.5.0-cp35-none-win32.whl

Golke的软件包是使用更新版本的libxml2构建的,显然已经修复了这个bug,所以如果上面的所有内容都能正常工作,你现在就可以停止浪费时间来咆哮错误的“树”了。 你没有使用lxml错误,并不是lxml不支持在这种情况下保留空白 (因为你可能会想到许多其他SO条目); 只是你不知不觉地使用了一个版本的libxml2,它有一个自那以后修复过的bug。

最近构建的libxml2驱动你的lxml安装,你发布的示例代码的输出将产生你所期望的(一致保留的空格):

<pre>
<em>abc</em>

<em>def</em>

<sub>ghi</sub>

<sub>jkl</sub>

<em>mno</em>

<em>pqr</em>

</pre>