Python's Smtplib provides a convenient way to send e-mail. It is a simple encapsulation of the SMTP protocol.
The basic commands for the SMTP protocol include:
HELO identify the user identity to the server
Mail initiate message transfer mail from:
RCPT identifies a single recipient of the message; often after the mail command, there can be multiple RCPT to:
Data after a single or multiple RCPT command indicates that all message recipients have identified and initialized the data transfer to. End
VRFY is used to verify that the specified user/mailbox exists or that the server often prohibits this command for security reasons
EXPN Verify that a given mailbox list exists, and that the expanded mailbox list is often disabled
Help query server What commands are supported
NOOP no action, server should respond OK
QUIT End Session
RSET reset session, current transfer canceled
Mail from specify Sender address
RCPT to specified recipient address
General SMTP session There are two ways, one is direct mail delivery, that is, for example, you want to send e-mail to zzz@163.com, then directly connected to the 163.com mail server, the letter to zzz@163.com; The other is the verification of the post, its process is, for example, you want to send e-mail to zzz@163.com, you are not directly to 163.com, but through their own in Sina.com another mailbox to send. This will be connected to the Sina.com SMTP server, and then certified, and then sent to the 163.com letter to the Sina.com, Sina.com can help you deliver the letter to 163.com.
The first method of command flow is basically this:
1. Helo
2. Mail from
3. RCPT TO
4. Data
5. Quit
But the first way to send a general limit, that is RCPT to specify the recipient of this message must exist on this server, otherwise it will not receive. First look at the code:
Copy Code code as follows:
#-*-encoding:gb2312-*-
Import OS, sys, string
Import Smtplib
# Mail server address
MailServer = "Smtp.163.com"
# Mail from address during an SMTP session
FROM_ADDR = "Asfgysg@zxsdf.com"
# RCPT to address during SMTP session
TO_ADDR = "Zhaoweikid@163.com"
# Letter Content
msg = "Test Mail"
SVR = Smtplib. SMTP (MailServer)
# set to debug mode, that is, there will be output information during the session
Svr.set_debuglevel (1)
# helo command, the DoCmd method includes getting the opposing server return information
Svr.docmd ("HELO server")
# Mail from, send mail sender
Svr.docmd ("MAIL from: <%s>"% from_addr)
# RCPT TO, mail receiver
Svr.docmd ("RCPT to: <%s>"% to_addr)
# Data command, start sending
Svr.docmd ("DATA")
# Send Body Data
Svr.send (msg)
# like A. As the body sends the end of the tag, sent with send, so use getreply to get the return information
Svr.send (".")
Svr.getreply ()
# Send End, exit
Svr.quit ()
Note that the 163.com has anti-spam features, and the above method of posting the message does not necessarily pass the anti-spam system detection. Therefore, it is generally not recommended for individuals to send.
The second kind is different:
1.ehlo
2.auth Login
3.mail from
4.RCPT to
5.data
6.quit
Compared with the first one, a more authentication process, is AUTH login this process.
Copy Code code as follows:
#-*-encoding:gb2312-*-
Import OS, sys, string
Import Smtplib
Import Base64
# Mail server address
MailServer = "Smtp.163.com"
# Mail User name
Username = "Xxxxxx@163.com"
# password
Password = "xxxxxxx"
# Mail from address during an SMTP session
FROM_ADDR = "Xxxxxx@163.com"
# RCPT to address during SMTP session
TO_ADDR = "Yyyyyy@163.com"
# Letter Content
msg = "My Test Mail"
SVR = Smtplib. SMTP (MailServer)
# set to debug mode, that is, there will be output information during the session
Svr.set_debuglevel (1)
# EHLO command, the DoCmd method includes getting the opposing server return information
Svr.docmd ("EHLO server")
# Auth Login Command
Svr.docmd ("AUTH LOGIN")
# Send user name, is Base64 encoded, sent with send, so to use getreply get return information
Svr.send (base64.encodestring (username))
Svr.getreply ()
# Send Password
Svr.send (base64.encodestring (password))
Svr.getreply ()
# Mail from, send mail sender
Svr.docmd ("MAIL from: <%s>"% from_addr)
# RCPT TO, mail receiver
Svr.docmd ("RCPT to: <%s>"% to_addr)
# Data command, start sending
Svr.docmd ("DATA")
# Send Body Data
Svr.send (msg)
# like A. The tag that ends as the body is sent
Svr.send (".")
Svr.getreply ()
# Send End, exit
Svr.quit ()
The above is the most common situation, but can not be ignored is now a lot of corporate mail is to support secure mail, is sent through the SSL mail, this How to send? SMTP has two options for SSL-secured mail, one that is dedicated to opening a 465 port to receive SSL mail, and the other is to add a STARTTLS command to the standard 25 port SMTP.
Look at the first way to do this:
Copy Code code as follows:
#-*-encoding:gb2312-*-
Import OS, sys, string, socket
Import Smtplib
Class 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)
Except ValueError:
Raise Socket.error, "nonnumeric port"
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 Create SSL connection
Sslobj = Socket.ssl (Self.sock, Self.key, Self.cert)
Except 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 (' 192.168.2.10 ')
Smtp.set_debuglevel (1)
Smtp.sendmail ("zzz@xxx.com", "zhaowei@zhaowei.com", "xxxxxxxxxxxxxxxxx")
Smtp.quit ()
Here I am from the original smtplib. SMTP derives a new Smtp_ssl class that specializes in processing SSL connections. The 192.168.2.10 I tested here is my own test server.
The second is the new STARTTLS command, which is very simple, Smtplib has this method, called Smtplib.starttls (). Of course, not all mail systems support secure mail, this needs to be confirmed from the EHLO return value, if there is STARTTLS, to support. The second way to send a regular message is to add a new line of code:
Copy Code code as follows:
#-*-encoding:gb2312-*-
Import OS, sys, string
Import Smtplib
Import Base64
# Mail server address
MailServer = "Smtp.163.com"
# Mail User name
Username = "Xxxxxx@163.com"
# password
Password = "xxxxxxx"
# Mail from address during an SMTP session
FROM_ADDR = "Xxxxxx@163.com"
# RCPT to address during SMTP session
TO_ADDR = "Yyyyyy@163.com"
# Letter Content
msg = "My Test Mail"
SVR = Smtplib. SMTP (MailServer)
# set to debug mode, that is, there will be output information during the session
Svr.set_debuglevel (1)
# EHLO command, the DoCmd method includes obtaining the return information of the opposing server, and if a secure message is supported, there is a STARTTLS hint in the return value.
Svr.docmd ("EHLO server")
Svr.starttls () # <------This is the newly added code to support secure mail!
# Auth Login Command
Svr.docmd ("AUTH LOGIN")
# Send user name, is Base64 encoded, sent with send, so to use getreply get return information
Svr.send (base64.encodestring (username))
Svr.getreply ()
# Send Password
Svr.send (base64.encodestring (password))
Svr.getreply ()
# Mail from, send mail sender
Svr.docmd ("MAIL from: <%s>"% from_addr)
# RCPT TO, mail receiver
Svr.docmd ("RCPT to: <%s>"% to_addr)
# Data command, start sending
Svr.docmd ("DATA")
# Send Body Data
Svr.send (msg)
# like A. The tag that ends as the body is sent
Svr.send (".")
Svr.getreply ()
# Send End, exit
Svr.quit ()
Note: The above code for convenience I have not judged the return value, strictly speaking, should be judged by the return of the Code, in the SMTP protocol, only the return code is 2XX or 3xx to continue the next step, return 4xx or 5xx, are wrong.