鉴于原始电子邮件没有 "Body"标签或任何东西,Python : How to parse the Body from a raw email ,

标签 python email python-2.7 mod-wsgi wsgi

似乎很容易得到

From
To
Subject

等通过

import email
b = email.message_from_string(a)
bbb = b['from']
ccc = b['to']

假设 "a" 是看起来像这样的原始电子邮件字符串。

a = """From root@a1.local.tld Thu Jul 25 19:28:59 2013
Received: from a1.local.tld (localhost [127.0.0.1])
    by a1.local.tld (8.14.4/8.14.4) with ESMTP id r6Q2SxeQ003866
    for <ooo@a1.local.tld>; Thu, 25 Jul 2013 19:28:59 -0700
Received: (from root@localhost)
    by a1.local.tld (8.14.4/8.14.4/Submit) id r6Q2Sxbh003865;
    Thu, 25 Jul 2013 19:28:59 -0700
From: root@a1.local.tld
Subject: oooooooooooooooo
To: ooo@a1.local.tld
Cc: 
X-Originating-IP: 192.168.15.127
X-Mailer: Webmin 1.420
Message-Id: <1374805739.3861@a1>
Date: Thu, 25 Jul 2013 19:28:59 -0700 (PDT)
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary="bound1374805739"

This is a multi-part message in MIME format.

--bound1374805739
Content-Type: text/plain
Content-Transfer-Encoding: 7bit

ooooooooooooooooooooooooooooooooooooooooooooooo
ooooooooooooooooooooooooooooooooooooooooooooooo
ooooooooooooooooooooooooooooooooooooooooooooooo

--bound1374805739--"""

问题

如何通过 python 获取这封邮件的Body

到目前为止,这是我知道的唯一代码,但我还没有测试它。

if email.is_multipart():
    for part in email.get_payload():
        print part.get_payload()
else:
    print email.get_payload()

这是正确的方法吗?

或者也许有一些更简单的东西,比如......

import email
b = email.message_from_string(a)
bbb = b['body']

?

最佳答案

为了获得高度肯定,您使用实际的电子邮件正文(但仍有可能您没有解析正确的部分),您必须跳过附件,并专注于纯文本或 html 部分(取决于您的需要) 进行进一步处理。

由于前面提到的附件可以而且经常是 text/plain 或 text/html 部分,这个非防弹示例通过检查 content-disposition header 来跳过这些:

b = email.message_from_string(a)
body = ""

if b.is_multipart():
    for part in b.walk():
        ctype = part.get_content_type()
        cdispo = str(part.get('Content-Disposition'))

        # skip any text/plain (txt) attachments
        if ctype == 'text/plain' and 'attachment' not in cdispo:
            body = part.get_payload(decode=True)  # decode
            break
# not multipart - i.e. plain text, no attachments, keeping fingers crossed
else:
    body = b.get_payload(decode=True)

顺便说一句,walk() 对 mime 部分进行了出色的迭代,而 get_payload(decode=True) 为您完成了解码 base64 等的繁琐工作。

一些背景 - 正如我所暗示的,MIME 电子邮件的美妙世界存在许多“错误地”查找邮件正文的陷阱。 在最简单的情况下,它位于唯一的“文本/纯文本”部分中,get_payload() 非常诱人,但我们并不生活在一个简单的世界中——它通常被多部分/替代、相关、混合等内容所包围。维基百科对其进行了严格的描述 - MIME ,但考虑到以下所有这些情况都是有效且常见的,因此必须全面考虑安全网:

非常常见 - 与普通编辑器(Gmail、Outlook)发送带附件的格式化文本差不多:

multipart/mixed
 |
 +- multipart/related
 |   |
 |   +- multipart/alternative
 |   |   |
 |   |   +- text/plain
 |   |   +- text/html
 |   |      
 |   +- image/png
 |
 +-- application/msexcel

相对简单 - 只是替代表示:

multipart/alternative
 |
 +- text/plain
 +- text/html

不管好坏,这个结构也是有效的:

multipart/alternative
 |
 +- text/plain
 +- multipart/related
      |
      +- text/html
      +- image/jpeg

希望这会有所帮助。

附:我的观点是不要轻易接近电子邮件 - 当你最不期待的时候它会咬人:)

关于鉴于原始电子邮件没有 "Body"标签或任何东西,Python : How to parse the Body from a raw email ,,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17874360/

相关文章:

python - Pandas 时间序列索引 -- re

主题或消息中带有特殊字符的电子邮件的 PHP Mail header

C# -- 在 Outlook 中读取来自非默认帐户的电子邮件

jquery - 如何使用 JQuery 加密电子邮件地址

Python:在数据框中按小时选择行

python - 从 python 2.7 中的包导入名称、子模块或子包的优先级是什么?

python - 如何在ZODB中设置缓存大小?

python - 在特定时间为 Django/Python 调用方法?

python - 使用自定义管道进行交叉验证 scikit-learn

python - python 中 __truediv__ 的运算符重载