You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用BeautifulSoup仅缩进HTML代码而不添加额外换行?

如何用Python仅给HTML添加缩进而不额外换行?

我有一段HTML代码:

<html>
<body>
<p>Some post</p>
<p>Another post</p>
</body>
</html>

用BeautifulSoup的soup.prettify()方法格式化时,会自动给标签内部添加额外换行,输出结果如下:

<html>
 <body>
  <p>
   Some post
  </p>
  <p>
   Another post
  </p>
 </body>
</html>

我想要的是仅添加缩进、不额外拆分标签内容的效果(类似Sublime Text的「Reindent」功能),最终输出应该是这样:

<html>
<body>
    <p>Some post</p>
    <p>Another post</p>
</body>
</html>

请问Python里能实现这个需求吗?


当然可以实现,这里提供两种实用思路:

方法一:自定义遍历BeautifulSoup节点生成代码

通过递归遍历HTML节点,根据层级添加缩进,同时保持标签和内容在同一行:

from bs4 import BeautifulSoup

def reindent_html(html, indent_size=4):
    soup = BeautifulSoup(html, 'html.parser')
    indent = ' ' * indent_size
    result = []
    
    def traverse(node, depth=0):
        # 处理文本节点,跳过空白内容
        if node.name is None:
            text = node.strip()
            if text:
                result.append(text)
            return
        
        # 写入开始标签
        result.append(f"{indent * depth}<{node.name}>")
        children = list(node.children)
        if children:
            # 子节点仅为文本时,直接拼接在标签后
            if len(children) == 1 and children[0].name is None:
                result.append(children[0].strip())
            else:
                result.append('\n')
                for child in children:
                    traverse(child, depth + 1)
                result.append(f"{indent * depth}")
        # 写入结束标签
        result.append(f"</{node.name}>\n")
    
    traverse(soup.html)
    # 整理输出,去除多余空白和换行
    final = ''.join(result).strip()
    final = final.replace('</html>', '\n</html>')
    return final

# 测试代码
original_html = """<html>
<body>
<p>Some post</p>
<p>Another post</p>
</body>
</html>"""

print(reindent_html(original_html))

运行后输出完全符合预期。

方法二:借助html5lib自定义序列化规则

利用html5lib的序列化能力,通过参数控制输出格式:

from bs4 import BeautifulSoup
from html5lib.serializer import serialize

def reindent_html_v2(html, indent_size=4):
    soup = BeautifulSoup(html, 'html5lib')
    # 配置序列化参数,禁止标签内换行并设置缩进
    options = {
        'indent': indent_size,
        'newline': '\n',
        'strip_whitespace': True,
        'inject_meta_charset': False
    }
    serialized = serialize(soup, **options)
    return serialized.strip()

# 测试代码
print(reindent_html_v2(original_html))

使用前需要先安装依赖:

pip install html5lib

内容的提问来源于stack exchange,提问作者220284

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.24 21:54:17