通过电子邮件发送的 Zip 在第一次尝试时无效

Zip sent via email is invalid on first attempt

我尝试创建一个包含特定目录(和子目录)中所有文件的 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 存档。执行脚本时有两种可能的情况:

情况一:执行脚本前已有一个zip压缩包,名称为report.zip(上次运行的旧压缩包)

情况二:执行脚本前没有压缩包

情况 1 一切正常。旧的被新生成的替换,然后通过电子邮件发送。

在情况 2 中生成 report.zip 并通过电子邮件发送,但它无效。如果我尝试使用 7zip(或 windows 板载工具)在 Windows 上打开它,它只会显示 "the archive is invalid"。我发现只有通过电子邮件发送的 report.zip 损坏了。如果我通过电子邮件手动发送案例 2 中生成的 report.zip,我可以将其解压缩并使用这些文件。

我是一个 python 新手,老实说,很难达到我现在的水平,但解决这个问题让我很头疼。谁能解释我做错了什么?

您需要在添加文件后关闭 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))    

详情 据我了解。

第 1 运行

  • zipfile 创建一个文件描述符(在内存占位符中)和一个包清单(要添加的文件)
  • zipfile.write() 将文件压缩到文件描述符中并将文件添加到清单中
  • msg.attach() 文件尚未刷新,因此内存中的位置没有任何内容。
  • --结束脚本文件描述符清理将文件描述符刷新到磁盘。 ( reports.zip 存在但是 incomplete/invalid )

第二个运行

  • zipfile 创建一个 fd 和清单
  • zipfile.write() 将文件压缩到fd并将文件添加到manifest
  • msg.attach() 文件上次已刷新但仍不完整附加无效文件

试试这个:

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 的开发者,该软件包试图简化发送电子邮件(带或不带附件)的过程。