如何防止美丽汤4在<html><body>汤中添加额外的标签?



在BeautifulSoup 3之前的版本中,我可以采用任何HTML块并以这种方式获得字符串表示:

from BeautifulSoup import BeautifulSoup
soup3 = BeautifulSoup('<div><b>soup 3</b></div>')
print unicode(soup3)
    '<div><b>soup</b></div>'

然而,对于BeautifulSoup4,相同的操作创建了额外的标签:

from bs4 import BeautifulSoup
soup4 = BeautifulSoup('<div><b>soup 4</b></div>')
print unicode(soup4)
    '<html><body><div><b>soup 4</b></div></body></html>'
     ^^^^^^^^^^^^                        ^^^^^^^^^^^^^^ 

我不需要外部 <html><body>..</body></html> 标签,BS4正在添加。我看过BS4文档,也在类中搜索,但找不到任何设置来抑制输出中的额外标签。我该怎么做呢?降级到v3不是一个选择,因为BS3中使用的SGML解析器不如BS4中可用的lxmlhtml5lib解析器。

如果你想让你的代码在每个人的机器上工作,不管他们安装了哪个解析器,等等(在libxml2 2.9 vs. 2.8上构建的相同的lxml版本的行为非常不同,stdlib html.parser在2.7.2和2.7.3之间有一些根本性的变化,…),你几乎需要处理所有合法的结果。

如果你知道你有一个片段,像这样的代码会给你那个片段:

soup4 = BeautifulSoup('<div><b>soup 4</b></div>')
if soup4.body:
    return soup4.body.next
elif soup4.html:
    return soup4.html.next
else:
    return soup4

当然,如果你知道你的片段是一个单一的div,它甚至更容易,但它不容易想到一个用例,你会知道:

soup4 = BeautifulSoup('<div><b>soup 4</b></div>')
return soup4.div

如果你想知道为什么会发生这种情况:

BeautifulSoup用于解析HTML文档。HTML片段不是有效的文档。它非常接近文档,但这还不足以保证您将得到您所提供的内容。

解析器之间的差异说明:

HTML解析器之间也存在差异。如果给Beautiful Soup一个格式完美的HTML文档,这些差异就无关紧要了。一个解析器会比另一个更快,但它们都会给你一个看起来和原始HTML文档一模一样的数据结构。

但是如果文档不是完美的格式,不同的解析器将给出不同的结果。

所以,虽然没有记录这个确切的差异,但它只是一个特殊情况

正如在旧的BeautifulStoneSoup文档中所指出的:

BeautifulSoup类充满了类似web浏览器的启发式方法,用于猜测HTML作者的意图。但是XML没有固定的标记集,所以这些启发式方法不适用。所以BeautifulSoup不能很好地处理XML。

使用BeautifulStoneSoup类解析XML文档。这是一个通用类,不需要任何XML方言的专门知识,只有关于标签嵌套的非常简单的规则…

在BeautifulSoup4文档中:

不再有用于解析XML的BeautifulStoneSoup类。要解析XML,需要将"XML"作为第二个参数传递给BeautifulSoup构造函数。出于同样的原因,BeautifulSoup构造函数不再识别isHTML参数。

也许这会得到你想要的。

最新更新