使用Python发送带内嵌图片的邮件时Outlook客户端不显示图片怎么办
问题修复方案
核心问题原因
- MIME结构不符合Outlook解析规范:你当前使用
MIMEMultipart('alternative')作为根容器,该类型仅支持纯文本/HTML两种格式备选,无法兼容「内嵌资源+附件」的复合结构,Gmail对不规范结构容错性高可正常解析,Outlook严格遵循MIME标准因此无法匹配cid对应的图片 - 字段拼写错误:代码中
Content-Decomposition应为Content-Disposition,octate-stream应为octet-stream,错误的头字段导致Outlook无法识别资源类型 - 同文件重复附加冲突:同一张
figure.png同时作为内嵌资源和附件附加,未做标识区分时Outlook会优先识别为附件,导致HTML中的cid引用匹配失败 - 缺失依赖导入:原代码未导入
MIMEBase和encoders模块,运行会抛出导入错误
修复后完整代码
from pretty_html_table import build_table from email.mime.image import MIMEImage from email.mime.multipart import MIMEMultipart from email.mime.text import MIMEText from email.mime.base import MIMEBase from email import encoders import smtplib # 根容器使用mixed类型,支持同时存放正文、内嵌资源、附件 message = MIMEMultipart('mixed') message['Subject'] = f"Data for {last_date.date()}" message['From'] = sender message['To'] = receiver # 构建可选格式容器,存放纯文本/HTML备选内容 alt_part = MIMEMultipart('alternative') message.attach(alt_part) # 构建内嵌资源容器,存放HTML和对应的内嵌图片 related_part = MIMEMultipart('related') alt_part.attach(related_part) # 构建HTML表格 output_table = build_table(table_for_email, "blue_light") html_content = MIMEText( f'''<html> <head></head> <body> <p>Hello!</p> <p>Please check out the new data.</p> {output_table} <!-- 可按需添加宽高属性,进一步提升Outlook兼容性 --> <img src="cid:plots" alt="数据图表"> </body> </html> ''', "html" ) related_part.attach(html_content) # 附加内嵌图片,标记为inline类型 image = MIMEImage(open('figure.png', 'rb').read()) image.add_header('Content-ID', '<plots>') image.add_header('Content-Disposition', 'inline', filename='figure.png') related_part.attach(image) # 附加附件,修正拼写错误 attach_file_name = 'figure.png' attach_file = open(attach_file_name, 'rb') payload = MIMEBase('application', 'octet-stream') payload.set_payload(attach_file.read()) encoders.encode_base64(payload) payload.add_header('Content-Disposition', 'attachment', filename=attach_file_name) message.attach(payload) msg_body = message.as_string() server = smtplib.SMTP_SSL(mail_server) server.login(sender, password) server.sendmail(from_addr=sender, to_addrs=receiver, msg=msg_body) server.quit()
内容的提问来源于stack exchange,提问作者Lasha Dolenjashvili
相关产品推荐
相关产品推荐

