BeautifulSoup抑制lxml解析错误?

时间:2016-09-16 09:11:38

标签: xml beautifulsoup lxml

我使用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架构验证不感兴趣)。

1 个答案:

答案 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 你必须指定你要尝试的回收