通过电子邮件发送的 Zip 在第一次尝试时无效
Posted
技术标签:
【中文标题】通过电子邮件发送的 Zip 在第一次尝试时无效【英文标题】:Zip sent via email is invalid on first attempt 【发布时间】:2015-09-09 11:07:24 【问题描述】:我尝试创建一个包含来自特定目录(和子目录)的所有文件的 zip 存档并通过邮件发送:
#Create archive containing all files from directory "reports/"
zipf = zipfile.ZipFile('reports.zip', 'w')
for root, dirs, files in os.walk('reports/'):
for file in files:
zipf.write(os.path.join(root, file))
#Create email
msg = MIMEMultipart()
msg["From"] = emailfrom
msg["To"] = emailto
msg["Subject"] = "Monatliche Reports - Verrechnung an Kunden"
#Attach report.zip to email
fp = open(fileToSend, "rb")
attachment = MIMEBase('application', 'zip')
attachment.set_payload(fp.read())
fp.close()
encoders.encode_base64(attachment)
attachment.add_header("Content-Disposition", "attachment",
filename=fileToSend)
msg.attach(attachment)
#Send email via localhost smtp-server
server = smtplib.SMTP("localhost")
server.sendmail(emailfrom, emailto, msg.as_string())
server.quit()
脚本似乎有效。我收到了包含所有文件的附加 zip 存档的邮件。脚本执行时有两种可能的情况:
案例 1:在执行脚本之前已经有一个 zip 存档,名为 report.zip(上次运行的旧文件)
案例2:执行脚本前没有zip压缩包。
如果情况 1 一切正常。旧的替换为新生成的,然后将通过电子邮件发送。
在案例 2 中,report.zip 生成并通过电子邮件发送,但它是无效的。如果我尝试使用 7zip(或 Windows 板载工具)在 Windows 上打开它,它只会说“存档无效”。我发现只有通过电子邮件发送的 report.zip 被破坏了。如果我通过电子邮件手动发送案例 2 中生成的 report.zip,我可以将其解压缩并使用这些文件。
我是一个 python 新手,老实说,要达到我现在的位置已经够难了,但是解决这个问题让我很头疼。谁能解释一下我做错了什么?
【问题讨论】:
【参考方案1】:您需要在添加文件后关闭 zip 文件以确保存档完整。
https://docs.python.org/2/library/zipfile.html#zipfile.ZipFile.close
最好使用with
声明:
with zipfile.ZipFile('reports.zip', 'w') as zipf:
for root, dirs, files in os.walk('reports/'):
for file in files:
zipf.write(os.path.join(root, file))
详情 据我了解。
第一次运行:
zipfile 创建文件描述符(在内存占位符中)和包清单(要添加的文件) zipfile.write() 将文件压缩到文件描述符中,并将文件添加到清单中 msg.attach() 文件尚未刷新,因此内存中的位置没有任何内容。 --结束脚本文件描述符清理将文件描述符刷新到磁盘。 (reports.zip 存在但不完整/无效)第二次运行:
zipfile 创建一个 fd 和 manifest zipfile.write() 将文件压缩到 fd 并将文件添加到清单中 msg.attach() 文件上次刷新但仍不完整附加无效文件。【讨论】:
Thx 这确实解决了问题,但我仍然对它在我的代码的第二次尝试中起作用感到困惑。为什么存档在第 2 次运行时要关闭,而在第一次尝试时保持打开状态? 因为当脚本完成时解释器会关闭文件。在第二次尝试时,它将获得(部分)文件。 zip 文件在第一遍结束时仍处于打开状态并准备好接收更多文件,这将是一个不完整的包。 所以第一次尝试它是一个不完整的包,因为当脚本完成执行时文件仍然打开?我看不出尝试 2 的区别。发生的情况完全相同,文件在脚本完成时也是打开的。非常感谢您的解释。【参考方案2】:试试这个:
import yagmail
me = 'me@gmail.com'
yag = yagmail.SMTP(emailfrom, 'mypassword')
yag.send(emailto, "Monatliche Reports - Verrechnung an Kunden", 'reports.zip')
您可能必须使用 pip install yagmail
安装 yagmail
免责声明:我是 yagmail 的开发者,该软件包试图让发送电子邮件(带或不带附件)变得容易。
【讨论】:
看起来很有趣,我会试一试。谢谢你的提示以上是关于通过电子邮件发送的 Zip 在第一次尝试时无效的主要内容,如果未能解决你的问题,请参考以下文章
无法通过 nodemailer 发送电子邮件 |发件人“电子邮件 id@gmail.com>”无效