从 Gmail API 解码 MIME 电子邮件 - \r\n 和 3D - Python

Posted

技术标签:

【中文标题】从 Gmail API 解码 MIME 电子邮件 - \\r\\n 和 3D - Python【英文标题】:Decoding MIME email from Gmail API - \r\n and 3D - Python从 Gmail API 解码 MIME 电子邮件 - \r\n 和 3D - Python 【发布时间】:2018-01-14 04:59:44 【问题描述】:

我目前正在使用 Gmail API 在 Python 中读取一些 html 电子邮件。我已经使用以下方法解码了他们的身体:

base64.urlsafe_b64decode

在打印出生成的 HTML 电子邮件后,“\r\n”和“3D”散布在 HTML 周围。我无法删除“\r\n”,因为 \ 和 r 以及 \ 和 n 注册为不同的字符(?),我不确定“3D”来自哪里。

我的解码方式有问题吗?

代码如下:

results = service.users().messages().list(userId='me', q = 'is: unread').execute()

for index in range(len(results['messages'])):
    message = service.users().messages().get(userId='me', id=results['messages'][index]['id'], format='raw').execute()

    msg_str = base64.urlsafe_b64decode(message['raw'].encode('UTF-8'))

    mime_msg = email.message_from_string(str(msg_str))

    print(mime_msg)

    service.users().messages().modify(userId='me', id=results['messages'][index]['id'], body = 'removeLabelIds': ['UNREAD']).execute() # mark message as read

【问题讨论】:

这是一个简短的示例:" 【参考方案1】:

我可能有点晚了。一些提到的解决方案有效。但是为了帮助其他访问这里的人,我想发布这个答案,因为它看起来更干净。

在构建邮件对象时使用policy=email.policy.default。这将删除提到的=3D\r\n 等。

mailobject = email.message_from_string(msg_str,  policy=email.policy.default)

如果在 Python 3.6+ 上,您可以使用 get_bodyget_content 方法。

if mailobject.is_multipart():
    body = mailobject.get_body(('html',))
else:
    body = mailobject.get_body(('plain',))

if body:
    body = body.get_content()

print(body)

上面的代码非常简单,足以满足答案。在这里,我们假设它只是普通的或 html。记得 处理时照顾其他情况 电子邮件。

另一个不相关的提示:

由于这是一个编码问题,因此此答案也适用于其他类似情况。就像尝试使用 AWS Lambda 函数 (Python) 解析推送到 s3 转发的 AWS SES 电子邮件一样。我不得不在这里提到它,因为我在尝试使用它们时也遇到了同样的问题。

在这种情况下这样使用它

s3_file = object_s3['Body'].read()
mailobject = email.message_from_string(s3_file.decode('utf-8'),  policy=email.policy.default)

【讨论】:

【参考方案2】:

如果设置了 str.decode('utf-8'),maksel 的解决方案对我有用。原始代码编码而不是解码字节字符串。

因此,在python 3.7下我们可以替换如下:

msg = msg.replace('\r\n', '').replace('=3D', '=')

请注意,在我的情况下,此解决方案不适用于所有 html 标签。

【讨论】:

【参考方案3】:

我找到了解决方案 - 我停止使用 Python 中的电子邮件库,并将 msg_str 转换为字符串(它是字节类型)。从那里,我只是从字符串中删除了'\r\n',并将'=3D' 替换为'='

【讨论】:

【参考方案4】:

这不是一个很好的解决方案,而是使用类似的东西

for email_part in message.walk(): 
    part_data = email_part.get_payload(decode=True) 

其中 message 是 Python email.message.Message obj。然后也许使用 BeautifulSoup 之类的东西来有效地分析 HTML。 希望对您有所帮助!

【讨论】:

以上是关于从 Gmail API 解码 MIME 电子邮件 - \r\n 和 3D - Python的主要内容,如果未能解决你的问题,请参考以下文章

MIME 标头无法通过 Gmail API

使用 Go 从 Gmail API 解码消息正文

Gmail API 游乐场:发送方法,转换后的 MIME 原始标头在发送时未填充电子邮件字段

Gmail API 在 Javascript 中解码消息

Gmail API 仍然使用从 HTML 自动生成的替代正文部分替换 text/plain 替代正文部分

如何将原始电子邮件 (MIME) 从 AWS SES 转换为 Gmail?