考虑到下面的代码,人们可能会合理地期望几乎完全相同的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
元素中。)
答案 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>