简体   繁体   中英

How to receive mail using python

I would like to receive email using python. So far I have been able to get the subject but not the body. Here is the code I have been using:

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()

My issue is that when I run this code it properly returns the Subject but not the body. So if I send an email with the subject "Tester" and the body "This is a test message" it looks like this in IDLE.

>>>>Tester >>>>None

So it appears to be accurately assessing the subject but not the body, I think it is in the parsing method right? The issue is that I don't know enough about these libraries to figure out how to change it so that it returns both a subject and a body.

The object message does not have a body, you will need to parse the multiple parts, like this:

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

The walk() function iterates depth-first through the parts of the email, and you are looking for the parts that have a content-type. The content types can be either text/plain or text/html , and sometimes one e-mail can contain both (if the message content_type is set to multipart/alternative ).

The email parser returns an email.message.Message object, which does not contain a body key, as you'll see if you run

print message.keys()

What you want is the get_payload() method:

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

But this gets complicated when it comes to multi-part messages; get_payload() returns a list of parts, each of which is a Message object. You can get a particular part of the multipart message by using get_payload(i) , which returns the i th part, raises an IndexError if i is out of range, or raises a TypeError if the message is not multipart.

As Gustavo Costa De Oliveir points out, you can use the walk() method to get the parts in order -- it does a depth-first traversal of the parts and subparts of the message.

There's more about the email.parser module at http://docs.python.org/library/email.message.html#email.message.Message .

it also good return data in correct encoding in message contains some multilingual content


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

Here is how I solved the problem using python 3 new capabilities:

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)

Now get_message_body is actually pretty tricky due to MIME format. I used the function suggested in this answer .

This particular example works with Gmail, but IMAP is a standard protocol, so it should work for other email providers as well, possibly with minor changes.

if u want to use IMAP4. Use outlook python library, download here: https://github.com/awangga/outlook to retrieve unread email from your inbox:

import outlook
mail = outlook.Outlook()
mail.login('emailaccount@live.com','yourpassword')
mail.inbox()
print mail.unread()

to retrive email element:

print mail.mailbody()
print mail.mailsubject()
print mail.mailfrom()
print mail.mailto()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM