如何使用 Python 获取电子邮件的文本内容? [英] How can I get an email message's text content using Python?

查看:97
本文介绍了如何使用 Python 获取电子邮件的文本内容?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

给定 Python 2.6 中的 RFC822 消息,我怎样才能获得正确 文本/纯文本部分?基本上,我想要的算法是这样的:

message = email.message_from_string(raw_message)if has_mime_part(message, "text/plain"):mime_part = get_mime_part(message, "text/plain")text_content = decode_mime_part(mime_part)elif has_mime_part(message, "text/html"):mime_part = get_mime_part(message, "text/html")html = decode_mime_part(mime_part)text_content = render_html_to_plaintext(html)别的:# 倒退text_content = str(message)返回文本内容

在这些东西中,我有 get_mime_parthas_mime_part,但我不太确定如何从 MIME 部分获取解码的文本.我可以使用 get_payload() 获取 encoded 文本,但是如果我尝试使用 get_payload()<的 decode 参数/code> 方法(参见文档)在 text/plain 部分调用时出现错误:

<块引用>

文件/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/email/message.py",第 189 行,在 get_payload 中raise TypeError('预期列表,得到 %s' % type(self._payload))类型错误:预期列表,得到 

此外,我不知道如何将 HTML 尽可能地呈现为文本.

解决方案

在多部分电子邮件中,email.message.Message.get_payload() 返回一个列表,其中每个部分都有一个项目.最简单的方法是遍历消息并获取每个部分的有效负载:

导入邮件msg = email.message_from_string(raw_message)对于 msg.walk() 的一部分:# 每个部分是一个非多部分或另一个多部分消息# 包含更多部分... 消息组织得像一棵树如果 part.get_content_type() == 'text/plain':print part.get_payload() # 打印原始文本

对于一个非多部分的消息,不需要做所有的遍历.您可以直接使用 get_payload(),而不管 content_type.

msg = email.message_from_string(raw_message)msg.get_payload()

如果内容被编码,则需要将None作为第一个参数传递给get_payload(),然后是True(解码标志是第二个参数).例如,假设我的电子邮件包含一个 MS Word 文档附件:

msg = email.message_from_string(raw_message)对于 msg.walk() 的一部分:如果 part.get_content_type() == 'application/msword':name = part.get_param('name') 或 'MyDoc.doc'f = 打开(名称,'wb')f.write(part.get_payload(None, True)) # 你需要 None 作为第一个参数# 因为 part.is_multipart()# 是假的f.close()

至于获得 HTML 部分的合理纯文本近似值,我发现 html2text 效果非常好.

Given an RFC822 message in Python 2.6, how can I get the right text/plain content part? Basically, the algorithm I want is this:

message = email.message_from_string(raw_message)
if has_mime_part(message, "text/plain"):
    mime_part = get_mime_part(message, "text/plain")
    text_content = decode_mime_part(mime_part)
elif has_mime_part(message, "text/html"):
    mime_part = get_mime_part(message, "text/html")
    html = decode_mime_part(mime_part)
    text_content = render_html_to_plaintext(html)
else:
    # fallback
    text_content = str(message)
return text_content

Of these things, I have get_mime_part and has_mime_part down pat, but I'm not quite sure how to get the decoded text from the MIME part. I can get the encoded text using get_payload(), but if I try to use the decode parameter of the get_payload() method (see the doc) I get an error when I call it on the text/plain part:

File "/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/
email/message.py", line 189, in get_payload
    raise TypeError('Expected list, got %s' % type(self._payload))
TypeError: Expected list, got <type 'str'>

In addition, I don't know how to take HTML and render it to text as closely as possible.

解决方案

In a multipart e-mail, email.message.Message.get_payload() returns a list with one item for each part. The easiest way is to walk the message and get the payload on each part:

import email
msg = email.message_from_string(raw_message)
for part in msg.walk():
    # each part is a either non-multipart, or another multipart message
    # that contains further parts... Message is organized like a tree
    if part.get_content_type() == 'text/plain':
        print part.get_payload() # prints the raw text

For a non-multipart message, no need to do all the walking. You can go straight to get_payload(), regardless of content_type.

msg = email.message_from_string(raw_message)
msg.get_payload()

If the content is encoded, you need to pass None as the first parameter to get_payload(), followed by True (the decode flag is the second parameter). For example, suppose that my e-mail contains an MS Word document attachment:

msg = email.message_from_string(raw_message)
for part in msg.walk():
    if part.get_content_type() == 'application/msword':
        name = part.get_param('name') or 'MyDoc.doc'
        f = open(name, 'wb')
        f.write(part.get_payload(None, True)) # You need None as the first param
                                              # because part.is_multipart() 
                                              # is False
        f.close()

As for getting a reasonable plain-text approximation of an HTML part, I've found that html2text works pretty darn well.

这篇关于如何使用 Python 获取电子邮件的文本内容?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆