如何将MIME生成的含HTML模板及图片的邮件保存至磁盘并后续发送?
解决方案:拆分邮件生成、保存审核与发送流程
我来帮你搞定这个需求!咱们把邮件生成、本地保存审核、后续发送这几个环节拆分开,这样既方便你审核邮件内容,又能灵活控制发送时机,具体实现步骤如下:
一、生成带HTML模板和内嵌图片的邮件并保存到磁盘
首先我们先构建完整的邮件对象(包含HTML正文和内嵌图片),然后把它序列化保存到本地文件,这样你可以随时打开审核内容和显示效果。
代码实现(Python 3兼容版)
from email.mime.multipart import MIMEMultipart from email.mime.text import MIMEText from email.mime.image import MIMEImage import os # 1. 创建邮件容器,指定为'related'类型以支持内嵌资源 msg = MIMEMultipart('related') msg['Subject'] = "你的邮件主题" msg['From'] = "sender@example.com" msg['To'] = "recipient@example.com" # 2. 编写HTML模板,用cid引用内嵌图片(cid要和后续图片的Content-ID对应) html_content = """ <html> <body> <p>这是带内嵌图片的HTML邮件示例内容</p> <img src="cid:my_unique_image_cid" alt="邮件内嵌图片"> </body> </html> """ # 将HTML内容添加到邮件 msg.attach(MIMEText(html_content, 'html', 'utf-8')) # 3. 嵌入图片到邮件(替换为你的实际图片路径) image_path = r'C:\MyDocuments\my_image.png' with open(image_path, 'rb') as img_file: img = MIMEImage(img_file.read()) # 设置Content-ID,和HTML里的cid对应 img.add_header('Content-ID', '<my_unique_image_cid>') # 标记为内嵌资源,避免显示为可下载附件 img.add_header('Content-Disposition', 'inline', filename=os.path.basename(image_path)) msg.attach(img) # 4. 保存邮件到磁盘(建议按收件人/主题命名,方便批量审核) save_dir = r'C:\MyDocuments\saved_emails' save_path = os.path.join(save_dir, f"email_to_{msg['To'].replace('@', '_')}.eml") # 自动创建保存目录(如果不存在) os.makedirs(save_dir, exist_ok=True) with open(save_path, 'wb') as f: f.write(msg.as_bytes()) print(f"邮件已成功保存到本地:{save_path}")
关键说明
- 用
MIMEMultipart('related')类型才能正确支持HTML内嵌图片,避免图片显示为附件。 cid是内嵌资源的唯一标识,HTML里的src必须和图片的Content-ID完全匹配(注意尖括号)。- 保存时用
msg.as_bytes()序列化邮件对象,生成标准的.eml格式文件,可直接用邮件客户端打开预览。
二、读取已审核的邮件并发送
等你审核完所有保存的邮件后,就可以用单独的脚本批量读取并发送了:
代码实现
import smtplib from email import policy from email.parser import BytesParser import os # 批量发送的话,可以遍历保存目录下的所有.eml文件 saved_emails_dir = r'C:\MyDocuments\saved_emails' email_files = [f for f in os.listdir(saved_emails_dir) if f.endswith('.eml')] # 配置SMTP服务器信息 smtp_server = "smtp.example.com" smtp_port = 587 smtp_username = "sender@example.com" smtp_password = "your_smtp_password" try: # 建立SMTP连接 with smtplib.SMTP(smtp_server, smtp_port) as server: server.starttls() # 启用TLS加密,保障传输安全 server.login(smtp_username, smtp_password) for email_file in email_files: file_path = os.path.join(saved_emails_dir, email_file) # 读取本地邮件文件 with open(file_path, 'rb') as f: msg = BytesParser(policy=policy.default).parse(f) # 发送邮件,直接使用邮件对象里的发件人、收件人信息 server.send_message(msg) print(f"已发送邮件:{email_file}") print("所有邮件发送完成!") except Exception as e: print(f"发送过程中出现错误:{str(e)}")
关键说明
- 用
BytesParser配合policy.default可以正确解析标准.eml文件,保留所有原始邮件头和内容。 send_message()方法会自动读取邮件对象中的From、To、Subject等信息,无需手动指定。- 批量发送时遍历保存目录即可,适合处理多封邮件的场景。
实用小技巧
- 审核方式:直接用Outlook、Thunderbird等邮件客户端打开
.eml文件,就能预览邮件的实际显示效果,确保HTML格式和内嵌图片都正常。 - 命名规范:保存邮件时可以用
收件人邮箱_主题.eml的格式命名,方便快速定位和审核。 - 路径注意:Windows系统下路径要使用原始字符串(加
r前缀)或者双反斜杠,避免转义字符导致的路径错误。
内容的提问来源于stack exchange,提问作者sprogissd
相关产品推荐
相关产品推荐

