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

使用Beautiful Soup 4渲染inline自闭和元素 转换img为Confluence宏问题

问题根因

BeautifulSoup 默认的 HTML 解析与渲染规则仅将 W3C 标准定义的原生空元素(如 <img>、<br>、<input> 等)识别为自闭合标签。<ri:attachment> 是 Confluence 自定义命名空间标签,不在默认自闭合标签列表内,因此渲染时会被拆分为独立的开标签和闭标签。

解决方案

两步调整即可实现预期输出:

  1. 直接构造 Tag 对象替代字符串解析,避免解析阶段丢失自闭合属性
  2. 自定义 HTML 渲染器,将 <ri:attachment> 加入自闭合标签列表

完整修改后代码

import os
from bs4 import BeautifulSoup
from bs4.formatter import HTMLFormatter

# 自定义渲染器,添加Confluence自闭合标签
class ConfluenceHTMLFormatter(HTMLFormatter):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.self_closing_tags.add("ri:attachment")

def transform_img_to_confluence(soup):
    def get_image_tag(image_name):
        # 直接构造标签对象,稳定性高于字符串解析
        ac_image = soup.new_tag("ac:image", **{
            "ac:align": "center",
            "ac:layout": "center"
        })
        ri_attachment = soup.new_tag("ri:attachment", **{
            "ri:filename": image_name,
            "ri:version-at-save": "1"
        })
        # 显式标记为可自闭合元素
        ri_attachment.can_be_empty_element = True
        ac_image.append("\n")
        ac_image.append(ri_attachment)
        ac_image.append("\n")
        return ac_image

    for img in soup.find_all('img'):
        path = img['src']
        image_name = os.path.basename(path)
        image_tag = get_image_tag(image_name)
        img.replace_with(image_tag)

# 调用逻辑
html_string = '''
<p>
<img src="path/to/file.jpg" />
</p>
'''
soup = BeautifulSoup(html_string, "html.parser")
transform_img_to_confluence(soup)

# 用自定义渲染器输出,指定缩进为4空格
formatter = ConfluenceHTMLFormatter(indent=4)
print(soup.decode(formatter=formatter))

输出结果

<p>
    <ac:image ac:align="center" ac:layout="center">
        <ri:attachment ri:filename="file.jpg" ri:version-at-save="1" />
    </ac:image>
</p>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 18:45:04