我使用lxml处理BeautifulSoup来解析和导航XML文件。
我注意到了奇怪的行为。当读取格式错误的XML文件(例如截断的文档或缺少结束标记)时,Beautifulsoup会抑制lxml解析器抛出的异常。
示例:
from bs4 import BeautifulSoup
soup = BeautifulSoup("<foo><bar>trololo<", "xml") # this will work
甚至可以调用find()并导航这样破碎的XML树......
让我们尝试使用纯lxml读取完全相同的格式错误的文档:
from lxml import etree
root = etree.fromstring("<foo><bar>trololo<") # will throw XMLSyntaxError
这是为什么?我知道BeautifulSoup本身没有进行任何解析,它只是围绕lxml(或其他解析器)的包装器库。但是,如果XML格式错误,我对实际获取错误很感兴趣,例如:关闭标签丢失了。我只想要基本的XML语法验证(对XSD架构验证不感兴趣)。
答案 0 :(得分:3)
如果要复制行为,可以设置 recover = True 传递解析器:
from lxml import etree
root = etree.fromstring("<foo><bar>trololo<",parser=etree.XMLParser(recover=True)) # will throw XMLSyntaxError
print(etree.tostring(root))
输出:
<foo><bar>trololo</bar></foo>
如果您查看构建器目录中的 bs4 源代码,您将看到_lxml.py
并在其中:
def default_parser(self, encoding):
# This can either return a parser object or a class, which
# will be instantiated with default arguments.
if self._default_parser is not None:
return self._default_parser
return etree.XMLParser(
target=self, strip_cdata=False, recover=True, encoding=encoding)
lxml的 HTMLParser 默认设置它,以便它可以处理损坏的html,使用 xml 你必须指定你要尝试的回收