Python发送带zip附件邮件 收件后压缩包损坏无法打开
问题根因
ZIP属于二进制格式文件,代码核心错误是打开附件时使用了默认文本读取模式,还指定了CP866编码:
- 文本模式下Python会按照指定编码把文件原始二进制流转为字符串,遇到编码表不匹配的字节会自动做转义、替换处理,直接破坏ZIP的文件结构
- 读取得到的字符串传入
MIMEApplication时,模块会再次将字符串编码为字节,两次转码会彻底损坏压缩包原始数据,这就是解压时报格式未知/损坏的直接原因,和邮件传输环节的编码设置无关。
修复方案
- 读取压缩包、图片、Office文档等所有非文本类附件时,必须用二进制只读模式
rb打开,不要传encoding参数——该参数仅对文本文件读取生效,二进制模式下传入反而会触发参数错误。 - 给附件补充标准的
Content-Disposition头,避免部分邮件客户端识别附件异常、文件名乱码。 - 邮件发送完成后调用
quit()关闭SMTP连接,释放资源。
修复后可直接运行的代码
from email.mime.multipart import MIMEMultipart from email.mime.application import MIMEApplication import smtplib def send_mail(): sender = '*****@mail.ru' password = '*************' smtp_obj = smtplib.SMTP('smtp.mail.ru', 587) smtp_obj.starttls() msg = MIMEMultipart() msg['Subject'] = 'Data from Experiment' msg['From'] = sender msg['To'] = sender # 二进制模式读取zip文件,移除encoding参数 with open(r'C:\Users\Admin\Desktop\Python\Python + SQL\Send_email\arch\arch.zip', 'rb') as file: attach_part = MIMEApplication(file.read()) # 补充附件头,指定邮件中展示的文件名 attach_part.add_header('Content-Disposition', 'attachment', filename='arch.zip') msg.attach(attach_part) smtp_obj.login(sender, password) smtp_obj.sendmail(sender, sender, msg.as_string()) # 关闭SMTP连接 smtp_obj.quit() send_mail()
按上述修改后重新发送的附件,用WinRAR、7-zip打开不会再出现压缩包损坏报错。
内容的提问来源于stack exchange,提问作者Almas
相关产品推荐
相关产品推荐

