首页 文章

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

提问于
浏览
16

这个问题在这里已有答案:

在3之前的BeautifulSoup版本中,我可以使用任何一块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>'
     ^^^^^^^^^^^^                        ^^^^^^^^^^^^^^

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

2 回答

  • 1

    如果你想让你的代码在每个人的机器上工作,无论他们安装了哪些解析器等等(基于 libxml2 2.9和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 ,那么's even easier—but it'就不那么容易想到你知道的用例了:

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

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

    BeautifulSoup 用于解析HTML文档 . HTML片段不是有效文档 . 它非常接近文档,但是's not good enough to guarantee that you'将完全取回您提供的文档 .

    正如Differences between parsers所说:

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

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

  • 7

    正如旧_371471中所述:

    BeautifulSoup类充满了类似Web浏览器的启发式方法,用于划分HTML作者的意图 . 但XML没有固定的标记集,因此这些启发式方法不适用 . 所以BeautifulSoup不能很好地做XML . 使用BeautifulStoneSoup类来解析XML文档 . 它是一个通用类,没有任何XML方言的特殊知识和关于标记嵌套的非常简单的规则......

    并在BeautifulSoup4 docs

    不再有用于解析XML的BeautifulStoneSoup类 . 要解析XML,您将传入“xml”作为BeautifulSoup构造函数的第二个参数 . 出于同样的原因,BeautifulSoup构造函数不再识别isHTML参数 .

    也许这会产生你想要的东西 .

相关问题