BeautifulSoup:适当添加空格,去掉不必要的空格

5 投票
3 回答
3879 浏览
提问于 2025-04-18 18:37

这个示例的Python程序:

document='''<p>This is <i>something</i>, it happens
               in <b>real</b> life</p>'''
from bs4 import BeautifulSoup
soup = BeautifulSoup(document)
print(soup.prettify())

输出了以下内容:

<html>
 <body>
  <p>
   This is
   <i>
    something
   </i>
   , it happens
               in
   <b>
    real
   </b>
   life
  </p>
 </body>
</html>

这不对,因为它在每个开始和结束标签前后都加了空格,比如说,</i>,之间就不应该有空格。我希望它能:

  1. 在没有空格的地方不添加空格(即使是在块级标签周围,如果它们在CSS中设置为display:inline,也可能会出现问题)。

  2. 把所有的空格合并成一个空格,除了可能需要换行的地方。

像这样:

<html>
 <body>
  <p>This is
   <i>something</i>,
   it happens in
   <b>real</b> life</p>
 </body>
</html>

BeautifulSoup能做到吗?有没有其他推荐的HTML解析器可以处理这个问题?

3 个回答

0

正如之前的评论和thebjorn所说,BeautifulSoup对“漂亮的HTML”的定义是每个标签都单独占一行。不过,为了处理你在空格方面遇到的一些问题,比如<br>标签等,你可以先把它们合并成一行,像这样:

from bs4 import BeautifulSoup

document = """<p>This is <i>something</i>, it happens
               in <b>real</b> life</p>"""

document_stripped = " ".join(l.strip() for l in document.split("\n"))

soup = BeautifulSoup(document_stripped).prettify()

print(soup)

这样输出的结果是:

<html>
 <body>
  <p>
   This is
   <i>
    something
   </i>
   , it happens in
   <b>
    real
   </b>
   life
  </p>
 </body>
</html>
2

Beautiful Soup的.prettify()方法是用来把每个标签单独放在一行上显示的(你可以在这里查看详细信息:http://www.crummy.com/software/BeautifulSoup/bs4/doc/index.html#pretty-printing)。如果你想要其他格式的输出,那就需要自己动手,通过遍历解析树来实现。

4

因为 .prettify 这个功能会把每个标签放在单独的一行,所以它不太适合用在生产环境中;我觉得它只适合用来调试时查看输出。你可以直接把你的内容转换成字符串,使用 str 这个内置函数。

你想要的是在你的树结构中改变字符串的内容;你可以写一个函数,找到所有包含两个或更多空白字符的元素(可以用预先编译好的正则表达式),然后替换它们的内容。

顺便说一下,如果你这样写你的例子,Python 就可以避免插入不必要的空白字符:

document = ('<p>This is <i>something</i>, it happens '
            'in <b>real</b> life</p>')

这样你就有了两个字面量,它们会被隐式地连接在一起。

撰写回答