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

ccp*_*zza 16 python beautifulsoup

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

from BeautifulSoup import BeautifulSoup
soup3 = BeautifulSoup('<div><b>soup 3</b></div>')
print unicode(soup3)
    '<div><b>soup</b></div>'
Run Code Online (Sandbox Code Playgroud)

但是使用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>'
     ^^^^^^^^^^^^                        ^^^^^^^^^^^^^^ 
Run Code Online (Sandbox Code Playgroud)

我不需要<html><body>..</body></html>BS4添加的外部标签.我查看了BS4文档并在类中搜索但是找不到任何设置来抑制输出中的额外标记.我该怎么做?降级到V3是不是一种选择,因为在BS3中使用的SGML解析器不近的一样好lxmlhtml5lib可用以BS4解析器.

aba*_*ert 8

如果你想让你的代码在每个人的机器上运行,无论他们安装了哪些解析器等等(lxml基于libxml22.9和2.8 的相同版本的行为非常不同,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
Run Code Online (Sandbox Code Playgroud)

当然,如果你知道你的片段是单一的div,那就更容易了 - 但是想到你知道的用例并不容易:

soup4 = BeautifulSoup('<div><b>soup 4</b></div>')
return soup4.div
Run Code Online (Sandbox Code Playgroud)

如果你想知道为什么会这样:

BeautifulSoup用于解析HTML文档.HTML片段不是有效文档.它非常接近文档,但这并不足以保证您能够准确地获得您提供的文档.

由于解析器之间的差异说:

HTML解析器之间也存在差异.如果你给Beautiful Soup一个完美形成的HTML文档,这些差异并不重要.一个解析器会比另一个解析器更快,但它们都会为您提供一个看起来与原始HTML文档完全相同的数据结构.

但是如果文档没有完美形成,不同的解析器会给出不同的结果.

因此,虽然没有记录这种确切的差异,但它只是一个特殊情况.