Python uses the poplib module and the smtplib module to send and receive emails.
Poplib module receives emails
The python poplib module is used to receive mails from pop3. It can also be said that it is the first step in mail processing.
The POP3 protocol is not complex. It also uses a Q & A method. If you send a command to the server, the server will reply to a message. The pop3 command code is as follows:
Command poplib method parameter status description Guest USER user username recognized username. If this command is successful with the following pass command, it will lead to status conversion PASS _ password recognized USER password APOP apop Name, digest recognizes that Digest is the MD5 message Digest; STAT stat None processes the request server to send back mailbox statistics, such as the total number of mails and Total Bytes UIDL uidl [Msg #] unique identifier for processing the Returned mail, each identifier of a POP3 session will be the unique LIST [Msg #] Number of returned mails processed and the size of each email RETR retr [Msg #] to process and return all emails identified by Parameters the text DELE dele [Msg #] processing server marks the email marked as deleted by the parameter, the quit command executes RSET rset None to process all emails marked as deleted by the server, this command is used to undo the DELE command TOP [Msg #]. The processing server will return the first n lines of content of the email identified by the parameter, n must be a positive integer NOOP noop None. The server returns a positive response to the ---------------------------------------------------------------------------------------------- QUIT quit None update.
The poplib of python also provides corresponding methods for these commands, which have been marked in the second column above. The process of receiving emails is generally:
1. Connect to the pop3 server (poplib. POP3. _ init __)
2. Send the user name and password for verification (poplib. POP3.user poplib. POP3.pass _)
3. obtain the information about the email (poplib. POP3.stat)
4. receive email (poplib. POP3.retr)
5. Delete the email (poplib. POP3.dele)
6. Exit (poplib. POP3.quit)
Note that the method used in the brackets above is used to complete this operation. In actual code, it cannot be written like that. It should be to create poplib. POP3 object. Then, call the method of this object. For example:
poplib.POP3.quit
It should be understood
a = poplib.POP3(host)a.quit()
Let's take a look at the actual code:
#-*-Encoding: gb2312-*-import OS, sys, stringimport poplib # pop3 server address host = "pop3.163.com" # username = "xxxxxx@163.com" # password = "xxxxxxx" # create a pop3 object, at this time, the server has actually been connected to pp = poplib. POP3 (host) # Set the debugging mode to view the interaction information pp with the server. set_debuglevel (1) # Send the user name pp to the server. user (username) # Send the password pp to the server. pass _ (password) # Get The Mail Information on the server. The return result is a list. The first item is a total of multiple emails, and the second item is the total number of bytes ret = pp. stat () print ret # You need to retrieve the headers of all letters. The letter id starts from 1. For I in range (1, ret [0] + 1): # retrieve the letter header. Note: The number of rows specified by top is based on the mail header. That is to say, when 0 rows are taken, # actually returns the header information. If 1 row is taken, it actually returns one more row besides the header information. Mlist = pp. top (I, 0) print 'line: ', len (mlist [1]) # list the mail Information on the server. This will output the id and size for each mail. Unlike stat, the total statistical information ret = pp is output. list () print ret # obtain the complete information of the first email. In the returned value, the complete information is stored in the down [1] list by row. Down [0] is the returned status information down = pp. retr (1) print 'Lines: ', len (down) # Output Message for line in down [1]: print line # exit pp. quit ()
In some places, there is a secure email, which is actually ssl encryption for pop3. In this way, poplib can be processed, but POP3_SSL is used instead of POP3. Their methods are the same. Therefore, ssl is supported in the above Code. Replace the line for creating a pop3 object with the following:
pp = poplib.POP3_SSL(host)
Smtplib: Use python to send SSL/TLS Security emails
Python's smtplib provides a convenient way to send emails. It encapsulates the smtp protocol.
The basic commands for smtp protocol include:
- HELO identifies a user to the server
- MAIL initialize mail Transmission MAIL from:
- RCPT identifies a single email recipient. It is often behind the MAIL command and can have multiple rcpt:
- After one or more RCPT commands, DATA indicates that all Email recipients have been identified and DATA transmission is initialized to end.
- VRFY is used to verify whether the specified user or email address exists. This command is often disabled by the server for security reasons.
- EXPN verifies whether the specified mailbox list exists and expands the mailbox list.
- HELP query commands supported by the server
- No NOOP operation, the server should respond OK
- QUIT end session
- RSET resets the session and the current transmission is canceled.
- Mail from specifies the sender address
- Recipient address specified by RCPT
Generally, smtp session has two ways, one is direct mail delivery, that is to say, for example, you want to mail to the zzz@163.com, then directly connect to the 163.com mail server, the mail to the zzz@163.com; the other is the verification of the mail, the process is, for example, you want to mail to the zzz@163.com, You do not directly cast to 163.com, but through their own in sina.com another mailbox to send. In this case, we need to first connect to the smtp server of sina.com, then authenticate it, and then send the mail to 163.com to sina.com. sina.com will help you send the mail to 163.com.
The command process in the first method is basically like this:
1. helo
2. mail from
3. rcpt
4. data
5. quit
However, the first sending method is generally restricted, that is, the email recipient specified by rcpt to must exist on this server, otherwise it will not be received. First look at the Code:
#-*-Encoding: gb2312-*-import OS, sys, stringimport smtplib # mail server address mailserver = "smtp.163.com" # mail from address from_addr = "asfgysg@zxsdf.com" # rcpt to ADDRESS to_addr = "zhaoweikid@163.com" # mail content during smtp sessions msg = "test mail" svr = smtplib. SMTP (mailserver) # Set it to debug mode, that is, the svr will be output during the session. set_debuglevel (1) # export md ("HELO server") # mail from, sender svr.doc md ("mail from: <% s>" % from_addr) # rcpt, the receiver svr.doc md ("rcpt to: <% s>" % to_addr) # datacommand TO start and send the DATA svr.doc md ("DATA") # send the body DATA svr. send (msg) # For example. as the end mark of text sending, send is used, so getreply is used to obtain the returned information svr. send (". ") svr. getreply () # End of sending and exit svr. quit ()
Note that 163.com has the anti-spam function. The above method may not be able to pass the Anti-Spam system detection. Therefore, it is generally not recommended for individuals to send such messages.
The second type is a bit different:
1. ehlo
2. auth login
3. mail from
4. rcpt
5. data
6. quit
Compared with the first one, there is an additional authentication process, namely the auth login process.
#-*-Encoding: gb2312-*-import OS, sys, stringimport smtplibimport base64 # mail server address mailserver = "smtp.163.com" # mail username = "xxxxxx@163.com" # password = "xxxxxxx" # mail from address from_addr = "xxxxxx@163.com" during smtp sessions" # rcpt to ADDRESS to_addr = "yyyyyy@163.com" # mail content msg = "my test mail" svr = smtplib. SMTP (mailserver) # Set it to debug mode, that is, the svr will be output during the session. set_debuglevel (1) # export md ("EHLO server") # auth login command svr.doc md ("auth login") # The sending username, Which is base64-encoded and sent using send, therefore, use getreply to obtain the returned information svr. send (base64.encodestring (username) svr. getreply () # Send the svr password. send (base64.encodestring (password) svr. getreply () # mail from, sender svr.doc md ("mail from: <% s>" % from_addr) # rcpt to, recipient svr.doc md ("rcpt: <% s> "% to_addr) # datacommand to start sending DATA svr.doc md (" DATA ") # Send body DATA svr. send (msg) # For example. this is the end mark of the message sending. send (". ") svr. getreply () # End of sending and exit svr. quit ()
The above is the most common situation, but it cannot be ignored that many enterprise emails currently support secure mail, that is, emails sent through SSL. How can this problem be solved? SMTP supports SSL Secure Mail in two ways. The old one is to enable port 465 to receive ssl mail, another update method is to add a starttls command on the smtp of the standard port 25 to support it.
Let's take a look at the first method:
#-*-Encoding: gb2312-*-import OS, sys, string, socketimport smtplibclass SMTP_SSL (smtplib. SMTP): def _ init _ (self, host = '', port = 465, local_hostname = None, key = None, cert = None): self. cert = cert self. key = key smtplib. SMTP. _ init _ (self, host, port, local_hostname) def connect (self, host = 'localhost', port = 465): if not port and (host. find (':') = host. rfind (':'): I = host. rfind (':') if I> = 0: host, port = host [: I], host [I + 1:] try: port = int (port) handle T ValueError: raise socket. error, & quot; nonnumeric port & quot; if not port: port = 654 if self. debuglevel> 0: print> stderr, 'connect: ', (host, port) msg = "getaddrinfo returns an empty list" self. sock = None for res in socket. getaddrinfo (host, port, 0, socket. SOCK_STREAM): af, socktype, proto, canonname, sa = res try: self. sock = socket. socket (af, socktype, proto) if self. debuglevel> 0: print> stderr, 'connect: ', (host, port) self. sock. connect (sa) # newly added ssl connection sslobj = socket. ssl (self. sock, self. key, self. cert) Certificate t socket. error, msg: if self. debuglevel> 0: print> stderr, 'connect fail: ', (host, port) if self. sock: self. sock. close () self. sock = None continue break if not self. sock: raise socket. error, msg # Set ssl self. sock = smtplib. SSLFakeSocket (self. sock, sslobj) self. file = smtplib. SSLFakeFile (sslobj); (code, msg) = self. getreply () if self. debuglevel> 0: print> stderr, "connect:", msg return (code, msg) if _ name _ = '_ main __': smtp = SMTP_SSL ('2017. 168.2.10 ') smtp. set_debuglevel (1) smtp. sendmail ("zzz@xxx.com", "zhaowei@zhaowei.com", "xxxxxxxxxxxxxxxxx") smtp. quit ()
Here I derived a new SMTP_SSL class from the original smtplib. SMTP, which is dedicated to handling ssl connections. The 192.168.2.10 I tested here is my own test server.
The second is the newly added starttls command. This method is very simple. It is called smtplib. starttls () in smtplib (). Of course, not all email systems support secure mail, which needs to be confirmed from the return value of ehlo. If starttls exists, it indicates support. Compared with the second method for sending a common mail, you only need to add a new line of code:
#-*-Encoding: gb2312-*-import OS, sys, stringimport smtplibimport base64 # mail server address mailserver = "smtp.163.com" # mail username = "xxxxxx@163.com" # password = "xxxxxxx" # mail from address from_addr = "xxxxxx@163.com" during smtp sessions" # rcpt to ADDRESS to_addr = "yyyyyy@163.com" # mail content msg = "my test mail" svr = smtplib. SMTP (mailserver) # Set it to debug mode, that is, the svr will be output during the session. set_debuglevel (1) # ehlo command. The docmd method includes obtaining the information returned by the other server. With the security mail, the starttlsprompt svr.doc md ("EHLO server") svr. starttls () # <------ this line is the newly added code that supports Secure Mail! # Auth login command svr.doc md ("auth login") # The sending username, Which is base64-encoded and sent using send. Therefore, use getreply to obtain the returned information svr. send (base64.encodestring (username) svr. getreply () # Send the svr password. send (base64.encodestring (password) svr. getreply () # mail from, sender svr.doc md ("mail from: <% s>" % from_addr) # rcpt to, recipient svr.doc md ("rcpt: <% s> "% to_addr) # datacommand to start sending DATA svr.doc md (" DATA ") # Send body DATA svr. send (msg) # For example. this is the end mark of the message sending. send (". ") svr. getreply () # End of sending and exit svr. quit ()
Note: I did not judge the return value for the convenience of the above Code. Strictly speaking, we should judge the Returned Code. In smtp protocol, only 2xx or 3xx codes can be returned to continue the next step, errors occur when 4xx or 5xx is returned.