Python使用MIMEImage嵌入HTML邮件图片无法显示如何解决
问题描述
使用MIMEImage向HTML格式邮件嵌入图片时,即便参考公开示例复现代码,依然反复出现图片加载失败问题,报错提示为:
The linked image cannot be displayed. The file may have been moved, renamed, or deleted.(链接图片无法显示,文件可能已被移动、重命名或删除)
相关代码片段
HTML嵌入图片代码
<img width=779 height=467 style='width:8.1145in;height:4.8645in' src="cid:image001" alt="HRX Trend">
Python发送邮件代码
msg = MIMEMultipart('alternative') msg['Subject'] = "test for daily email" msg['From'] = me msg['To'] = you fp = open('path\\name.jpeg', 'rb') msgImage = MIMEImage(fp.read()) msgImage.add_header('Content-ID', '<image001>') part2 = MIMEText(html, 'html') msg.attach(part2) msg.attach(msgImage) s = smtplib.SMTP('domain', port) s.sendmail(me, you, msg.as_string()) s.quit()
异常效果截图

问题原因与修复方案
核心错误是使用了错误的MIMEMultipart子类型:
multipart/alternative的设计逻辑是:所有挂载的子部分是同一内容的不同格式版本(比如纯文本版、HTML版),邮件客户端只会选择其中一个它支持的最优版本渲染,其余部分会直接忽略,代码中挂载的图片部分会被客户端跳过,自然HTML里的cid引用找不到对应资源。- 要实现HTML内嵌cid图片,必须使用
multipart/related类型,这个类型专门用来存放主内容(HTML文本)和它关联引用的所有资源(图片、样式等),客户端加载主内容时会自动匹配同个related块内对应cid的资源。
修复后的可运行代码
from email.mime.multipart import MIMEMultipart from email.mime.text import MIMEText from email.mime.image import MIMEImage import smtplib # 核心修改:将alternative替换为related msg = MIMEMultipart('related') msg['Subject'] = "test for daily email" msg['From'] = me msg['To'] = you fp = open('path\\name.jpeg', 'rb') msgImage = MIMEImage(fp.read()) fp.close() # 主动关闭文件句柄,避免资源泄漏 msgImage.add_header('Content-ID', '<image001>') # 新增配置:标记图片为内联资源,避免部分客户端把它识别为单独附件 msgImage.add_header('Content-Disposition', 'inline', filename='name.jpeg') part2 = MIMEText(html, 'html') msg.attach(part2) msg.attach(msgImage) s = smtplib.SMTP('domain', port) s.sendmail(me, you, msg.as_string()) s.quit()
如果需要同时提供纯文本版本兼容不支持HTML的老旧邮件客户端,可以在related外层嵌套一层alternative结构:
# 外层用alternative存放不同格式的邮件版本 msg = MIMEMultipart('alternative') msg['Subject'] = "test for daily email" msg['From'] = me msg['To'] = you # 挂载纯文本版本 text_part = MIMEText("这是纯文本邮件内容", 'plain') msg.attach(text_part) # 内层用related存放HTML内容和关联的图片资源 related_part = MIMEMultipart('related') html_part = MIMEText(html, 'html') related_part.attach(html_part) fp = open('path\\name.jpeg', 'rb') msgImage = MIMEImage(fp.read()) fp.close() msgImage.add_header('Content-ID', '<image001>') msgImage.add_header('Content-Disposition', 'inline', filename='name.jpeg') related_part.attach(msgImage) msg.attach(related_part) # 发送逻辑保持不变 s = smtplib.SMTP('domain', port) s.sendmail(me, you, msg.as_string()) s.quit()
内容的提问来源于stack exchange,提问作者Abe
相关产品推荐
相关产品推荐

