我想使用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
所以它似乎准确地评估了主题而不是身体,我认为它在解析方法中是正确的吗?问题是我对这些库了解不足以弄清楚如何更改它以便它返回主题和正文。
答案 0 :(得分:8)
对象消息没有正文,您需要解析多个部分,如下所示:
for part in message.walk():
if part.get_content_type():
body = part.get_payload(decode=True)
walk()
函数在深度优先迭代电子邮件的各个部分,您正在寻找具有内容类型的部分。内容类型可以是text/plain
或text/html
,有时一封电子邮件可以包含两者(如果消息content_type
设置为multipart/alternative
)。
答案 1 :(得分: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
会返回IndexError
部分,如果i
超出范围,则会引发TypeError
,或者引发walk()
如果邮件不是多部分。
正如Gustavo Costa De Oliveir指出的那样,您可以使用email.parser
方法按顺序获取零件 - 它会对消息的各个部分进行深度优先遍历。
http://docs.python.org/library/email.message.html#email.message.Message上有{{1}}模块的更多内容。
答案 2 :(得分:2)
它在消息中正确编码的良好返回数据包含一些多语言内容
charset = part.get_content_charset()
content = part.get_payload(decode=True)
content = content.decode(charset).encode('utf-8')
答案 3 :(得分:0)
如果你想使用IMAP4。使用outlook python库,在这里下载:https://github.com/awangga/outlook 从收件箱中检索未读电子邮件:
A
要检索电子邮件元素:
B
答案 4 :(得分:0)
这是我使用python 3新功能解决问题的方法:
import imaplib
import email
mail = imaplib.IMAP4_SSL('imap.gmail.com')
mail.login(username, password)
mail.select(readonly=True) # refresh inbox
status, message_ids = mail.search(None, 'ALL') # get all emails
for message_id in message_ids[0].split(): # returns all message ids
# for every id get the actual email
status, message_data = mail.fetch(message_id, '(RFC822)')
actual_message = email.message_from_bytes(message_data[0][1])
# extract the needed fields
email_date = actual_message["Date"]
subject = actual_message["Subject"]
message_body = get_message_body(actual_message)
由于MIME格式,现在get_message_body
实际上非常棘手。我使用了this answer中建议的功能。
此特定示例适用于Gmail,但是IMAP是标准协议,因此它也应适用于其他电子邮件提供商,可能需要进行少量更改。