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

Python向Roundcube发送多图内嵌邮件仅显示1张图问题求解

问题诊断

代码出现仅显示1张内嵌图、其余变成异常附件的问题,核心是两个MIME配置错误:

  • 所有图片的Content-ID头全部设置为相同的<image>,CID是邮件内资源的唯一标识,重复后客户端只能匹配到第一个资源,剩余图片无法和正文的cid引用建立映射
  • 遍历图片的循环中,每次都新建独立的HTML格式MIMEText节点追加到multipart/alternative容器中,不符合MIME规范:该容器下仅允许挂载1份纯文本正文、1份HTML正文,重复追加的HTML节点会被Roundcube识别为无效附件,显示为名称异常的courriel html
修复代码

调整逻辑:提前拼接包含所有图片引用的完整HTML正文,为每张图片分配全局唯一的CID,再统一挂载MIME节点,修正后的可运行代码如下:

from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.image import MIMEImage
import os
import smtplib

# 基础发信配置
strFrom = 'x@x.com'
strTo = 'x@x.com'
dest = "/home/user/Bureau/photos/"

# 初始化MIME根容器
msgRoot = MIMEMultipart('related')
msgRoot['Subject'] = 'test message'
msgRoot['From'] = strFrom
msgRoot['To'] = strTo
msgRoot.preamble = 'This is a multi-part message in MIME format.'

# 初始化alternative容器,挂载纯文本/HTML两种正文
msgAlternative = MIMEMultipart('alternative')
msgRoot.attach(msgAlternative)
msgText = MIMEText('This is the alternative plain text message.')
msgAlternative.attach(msgText)

# 遍历目录下的图片文件,生成唯一CID和对应HTML标签
html_content = ""
dirmail = [f for f in os.listdir(dest) if f.lower().endswith(('.jpg', '.jpeg', '.png'))]
print(f'(mail.py): 待嵌入图片数量{len(dirmail)}')

for idx, filename in enumerate(dirmail):
    # 为每张图片生成唯一CID,避免重复
    cid = f"image_{idx}"
    # 把图片引用拼到统一的HTML正文中
    html_content += f'<img src="cid:{cid}"><br>'
    # 读取图片二进制内容,绑定对应CID
    file_path = os.path.join(dest, filename)
    with open(file_path, 'rb') as fp:
        msgImage = MIMEImage(fp.read(), _subtype='jpg')
    msgImage.add_header('Content-ID', f'<{cid}>')
    # 图片统一挂载到related根容器下
    msgRoot.attach(msgImage)
    # 读取完成后再删除文件,避免读文件前删除导致报错
    os.remove(file_path)
    print(f"remove {filename}")

# 把拼接完成的完整HTML正文只挂载一次到alternative容器
msgHtml = MIMEText(html_content, 'html')
msgAlternative.attach(msgHtml)

# SMTP发信逻辑
session = smtplib.SMTP('x', x) 
session.starttls()
session.login("x", "x")
session.sendmail(strFrom, strTo, msgRoot.as_string())
session.quit()
print('Mail Sent')
关键调整点
  • 每张图片使用image_序号生成唯一CID,和HTML中img标签的cid引用一一对应
  • 所有img标签统一拼接为一个完整的HTML字符串,仅生成一次MIMEText节点挂载,避免重复节点被识别为附件
  • 调整文件删除时机:读取完文件内容、挂载完MIME节点后再执行删除,避免文件操作异常导致读文件失败
  • 增加文件后缀过滤,避免读取目录下非图片文件导致的解析错误

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 10:39:20