如何使用Python接收邮件

11 投票
5 回答
40199 浏览
提问于 2025-04-16 11:17

我想用Python接收邮件。目前我能获取到邮件的主题,但获取不到邮件的内容。以下是我使用的代码:

import poplib
from email import parser
pop_conn = poplib.POP3_SSL('pop.gmail.com')
pop_conn.user('myusername')
pop_conn.pass_('mypassword')
#Get messages from server:
messages = [pop_conn.retr(i) for i in range(1, len(pop_conn.list()[1]) + 1)]
# Concat message pieces:
messages = ["\n".join(mssg[1]) for mssg in messages]
#Parse message intom an email object:
messages = [parser.Parser().parsestr(mssg) for mssg in messages]
for message in messages:
    print message['subject']
    print message['body']
pop_conn.quit()

我的问题是,当我运行这段代码时,它能正确返回主题,但无法返回内容。所以如果我发送一封主题为“Tester”,内容为“这是一个测试消息”的邮件,在IDLE中显示的结果是这样的:

>>>>Tester >>>>None

看起来它能准确识别主题,但内容却没有,我觉得问题出在解析的方法上,对吧?问题是我对这些库了解得不够,不知道该如何修改代码才能同时返回主题和内容。

5 个回答

1

在消息中包含一些多语言内容时,正确的编码返回数据也是很重要的。


charset = part.get_content_charset()
content = part.get_payload(decode=True)
content = content.decode(charset).encode('utf-8')

5

这个邮件解析器会返回一个 email.message.Message 对象,但这个对象里没有 body 这个键,如果你运行

print message.keys()

你会发现这一点。你需要使用 get_payload() 方法:

for message in messages:
    print message['subject']
    print message.get_payload()
pop_conn.quit()

不过,当邮件是多部分的时候,这就变得复杂了;get_payload() 会返回一个部分的列表,每个部分都是一个 Message 对象。你可以通过 get_payload(i) 来获取多部分邮件中的特定部分,这样会返回第 i 个部分。如果 i 超出了范围,它会抛出一个 IndexError 错误;如果邮件不是多部分的,它会抛出一个 TypeError 错误。

正如 Gustavo Costa De Oliveir 指出的,你可以使用 walk() 方法按顺序获取这些部分——它会对邮件的部分和子部分进行深度优先遍历。

关于 email.parser 模块的更多信息,可以查看 http://docs.python.org/library/email.message.html#email.message.Message

8

这个对象消息没有主体内容,你需要解析多个部分,像这样:

for part in message.walk():
    if part.get_content_type():
        body = part.get_payload(decode=True)

walk() 函数会深度优先地遍历电子邮件的各个部分,你需要寻找那些有内容类型的部分。内容类型可以是 text/plain(纯文本)或者 text/html(HTML格式),有时候一封邮件可能同时包含这两种类型(如果消息的 content_type 设置为 multipart/alternative)。

撰写回答