SMTP is used to send mail, if you want to receive mail?
The message is to write a MUA as a client, from the MDA to get the mail to the user's computer or mobile phone. The most commonly used protocol for receiving mail is the POP protocol, the current version number is 3, commonly known as POP3.
Python has a built-in poplib module that implements the POP3 protocol, which can be used to receive mail directly.
Note that the POP3 protocol does not charge an already readable message itself, but rather the original text of the message, which resembles the SMTP protocol, and that SMTP sends a large piece of text that is encoded.
To make the text you receive POP3 a readable message, you also need to use the various classes provided by the email module to parse the original text into a readable mail object.
So, there are two steps to receiving the message:
The first step: use Poplib to download the original text of the message to the local;
Part Two: Resolve the original text by email and revert to the message object.
Download mail via POP3
The POP3 protocol itself is simple, let's take the following code as an example, and we'll get the latest email content:
Import poplib# Enter email address, password and POP3 server address: email = raw_input (' email: ') password = raw_input (' Password: ') Pop3_server = Raw_input (' POP3 server: ') # connected to POP3 server: Server = poplib. POP3 (pop3_server) # can turn debug info on or off: # server.set_debuglevel (1) # Optional: Print welcome text for POP3 Server: Print (Server.getwelcome ()) # Identity authentication: Server.user (email) server.pass_ (password) # stat () returns the number of messages and space occupied: print (' Messages:%s. Size:%s '% Server.stat ()) # list () Returns the number of all messages: resp, mails, octets = Server.list () # can view the returned list similar to [' 1 82923 ', ' 2 2184 ', ...] Print (mails) # Get the latest message, note that the index number starts at 1: "index = len (mails) RESP, lines, octets = SERVER.RETR (index) # lines stores each line of the original text of the message, # You can get the original text for the entire message: Msg_content = ' \ r \ n '. Join (lines) # resolves the message later: msg = Parser (). PARSESTR (msg_content) # You can delete messages directly from the server based on the message index number: # Server.dele (Index) # Close connection: Server.quit ()
Using POP3 to get mail is very simple, to get all the mail, only need to cycle through the use of RETR () to each email content to be able to. The real trouble is to parse the original content of the message into a readable mail object.
Parsing messages
The process of parsing the message is the opposite of constructing the message in the previous section, so import the necessary modules first:
Import emailfrom email.parser import parserfrom email.header import decode_headerfrom email.utils import parseaddr
Only one line of code is needed to parse the message content into a message object:
msg = Parser (). PARSESTR (Msg_content)
However, the message object itself may be a Mimemultipart object that contains nested other Mimebase objects, which may be nested more than one level.
So we're going to print out the hierarchy of the message object recursively:
# Indent for indent display: Def print_info (msg, indent=0): if indent = = 0: # message from, to, subject exists on the root object: for header in [' From ', ' To ', ' Subject ': value = Msg.get (header, ') if Value:if header== ' Subject ': # The Subject string needs to be decoded: Value = DECODE_STR (value) Else: # needs to decode email address: hdr, addr = parseaddr (value) NA me = Decode_str (HDR) value = U '%s <%s> '% (name, addr) print ('%s%s:%s '% (' * indent, header, value ) if (Msg.is_multipart ()): # If the Mail object is a Mimemultipart, # get_payload () returns a list that contains all the sub-objects: Parts = Msg.get_payload () For N, part in enumerate (parts): Print ('%spart%s '% (' * indent, N)) print ('%s--------------------'% (' * indent) # recursively print each sub-object: Print_info (part, indent + 1) Else: # The Mail object is not a Mimemultipart, # based on Content_Type judgment : Content_Type = Msg.get_content_type () If content_type== ' Text/plain ' or content_type== ' text/html ': # Plain text or HTML inside Capacity: Content = Msg.geT_payload (decode=true) # to detect text encoding: CharSet = Guess_charset (msg) If charset:content = Content.decode ( CharSet) Print ('%stext:%s '% (' * indent, content + ' ... ')) Else: # is not text and is handled as an attachment: print ('%sattachment: %s '% (' * indent, Content_Type))
e-mail subject or email contains the names are encoded STR, to normal display, it must be decode:
def decode_str (s): value, CharSet = Decode_header (s) [0] if charset: value = Value.decode (CharSet) return value
Decode_header () returns a list because a field such as CC or BCC may contain multiple mail addresses, so there are multiple elements that can be parsed. The above code we stole a lazy, only take the first element.
The content of the text message is also STR and the encoding needs to be detected, otherwise non-UTF-8 encoded messages will not display properly:
def guess_charset (msg): # First gets the encoding from the MSG object: charset = Msg.get_charset () If charset is None: # If it is not available, Then get from the Content-type field: content_type = msg.get (' Content-type ', '). Lower () pos = content_type.find (' charset= ') if POS >= 0: charset = Content_type[pos + 8:].strip () return charset
Put the above code together so we can try to get an email. Send an e-mail to your email address, then use your browser to log in to the mailbox, see if the message received, if you receive, we will use the Python program to receive it locally:
Run the program with the following results:
+ok Welcome to Coremail Mail Pop3 Server (163coms[...]) messages:126. Size:27228317from:test
to:python enthusiast
Subject: Collect mail with POP3 part 0--------------------part 0- ------------------- Text:python can use the POP3 to receive mail ... Part 1-------------------- Text:python can use POP3 to receive mail .... Part 1--------------------attachment:application/octet-stream
We can see from the structure of the printing that this message is a mimemultipart, it contains two parts: the first part is a Mimemultipart, the second part is an attachment. The embedded Mimemultipart is a alternative type that contains a plain-text formatted Mimetext and an HTML-formatted mimetext.
Summary
Using Python's Poplib module to collect messages in two steps: The first step is to use the POP3 protocol to get mail to the local, the second step is to use the email module to resolve the original message to a Message object, and then, in the appropriate form to display the contents of the message to the user.