Python 2.7 - 从电子邮件消息文件中提取 Zip

标签 python email zip email-attachments

我需要检索 .zip 存档,检索 .zip 中的文件并提取其数据。 .zip 存档附加到电子邮件文件;我没有使用邮件协议(protocol)来访问邮箱。我能够解析消息...

...
from email.parser import Parser
...
for fileName in os.listdir(mailDir):
    ...
    message = Parser().parse(open(mailDir + '/' + fileName, 'r'))
    ...
    for part in message.walk():
        if part.get_content_type() == 'application/octet-stream':

当我第一次开始编写此代码时,我正在针对附有 .csv 的电子邮件进行测试,访问附件和提取数据没有问题,但现在我正在处理带有 .zip 的电子邮件(包含以前使用的 .csv)我被卡住了。添加...

import zipfile

...但似乎我需要实际将附加的 .zip 保存到文件系统才能使用 zipfile。我宁愿不这样做并且认为(希望)我可以简单地使用...

zipfile.ZipFile(the_base64_string_from_message, 'r')

但是失败了。如何在不在文件系统中创建 .zip 存档的情况下访问存档?此外,也许我什至不应该使用电子邮件模块(只使用它以便我可以轻松找到附件)???

最佳答案

您可能正在寻找的是 StringIO 模块,它包装一个字符串以提供文件接口(interface)。此外,您需要从 base64 解码电子邮件附件有效负载,以便处理正确的字节。这是将附件解压缩到当前工作目录的示例:

import email
import zipfile
from cStringIO import StringIO
import base64

with open('some_email_with_zip.eml', 'r') as f:
    m = email.message_from_file(f)

for part in m.walk():
    # You might also check to see if the content-type for your zip files is
    # application/zip instead of application/octet-stream
    if part.get_content_type() == 'application/zip':
        zip_bytes = base64.b64decode(part.get_payload())
        file_wrapper = StringIO(zip_bytes)
        if zipfile.is_zipfile(file_wrapper):
            with zipfile.ZipFile(file_wrapper, 'r') as zf:
                zf.extractall()

如果你想为解压文件指定一个不同于当前目录的路径,你可以将其指定为 extractall() 的参数:

zf.extractall('/path/for/unzipped/files')

关于Python 2.7 - 从电子邮件消息文件中提取 Zip,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19504985/

相关文章:

python - 更改多级字典值的更多 pythonic 方法

php - symfony1 swift 邮件程序 gmail - 连接被拒绝

c# - 无法发送给收件人 : c# exception

Gradle Zip 完整的父项目

javascript - 使用归档器创建内存中的 .zip,然后将此文件发送到 Node 服务器上的 koa 客户端

python - 通过条件在 pandas csv 文件中创建新列

C++ I/O 和 Python

python - Selenium "Unable to find a matching set of capabilities"尽管驱动程序位于/usr/local/bin

linux - 仅查看过去 24 小时的电子邮件日志

c++ - 使用 Qt qUnCompress 函数解压缩文件