This article describes in detail how to use Python to send SMTP emails, including adding images and other files to emails! If you need it, refer to SMTP as the Mail sending protocol. Python has built-in support for SMTP, which can send plain text emails, HTML emails, and emails with attachments.
Python supports two SMTP modules: smtplib and email. email is responsible for constructing emails, while smtplib is responsible for sending emails.
First, we construct the simplest plain text mail:
from email.mime.text import MIMETextmsg = MIMEText('hello, send by Python...', 'plain', 'utf-8')
Note that when constructing a MIMEText object, the first parameter is the mail body, the second parameter is the MIME subtype, the input 'plain ', and the final MIME is 'text/plain ', at last, we must use UTF-8 encoding to ensure multi-language compatibility.
Then, send it via SMTP:
# Enter the Email address and password from_addr = raw_input ('From: ') Password = raw_input ('password:') # enter the SMTP server address: smtp_server = raw_input ('smtp server: ') # enter the recipient address: to_addr = raw_input ('to:') import smtplibserver = smtplib. SMTP (smtp_server, 25) # The default SMTP port is 25server. set_debuglevel (1) server. login (from_addr, password) server. sendmail (from_addr, [to_addr], msg. as_string () server. quit ()
We can use set_debuglevel (1) to print all the information that interacts with the SMTP server. SMTP is a simple text command and response. The login () method is used to log on to the SMTP server. The sendmail () method is used to send an email. because it can be sent to multiple people at a time, a list is input. The Mail body is a str, as_string () convert the MIMEText object to str.
If everything goes well, you can receive the Email we just sent in the recipient's mailbox:
Observe carefully and find the following problems:
- The email has no subject;
- The recipient name is not displayed as a friendly name, such as Mr Green. ;
- The system prompts that the email is not in the recipient.
This is because the message subject, how to display the sender, recipient, and other information is not sent to the MTA through SMTP protocol, but is included in the text sent to the MTA, we must add From, To, and Subject To MIMEText, which is a complete email:
#-*-Coding: UTF-8-*-from email import encodersfrom email. header import Headerfrom email. mime. text import MIMETextfrom email. utils import parseaddr, formataddrimport smtplibdef _ format_addr (s): name, addr = parseaddr (s) return formataddr (\ Header (name, 'utf-8 '). encode (), \ addr. encode ('utf-8') if isinstance (addr, unicode) else addr) from_addr = raw_input ('From: ') password = raw_input ('password: ') To_addr = raw_input (' To: ') smtp_server = raw_input ('smtp server:') msg = MIMEText ('Hello, send by Python... ', 'plain', 'utf-8') msg ['from'] = _ format_addr (u'python enthusiast <% s> '% from_addr) msg ['to'] = _ format_addr (u'administrator <% s> '% to_addr) msg ['subobject'] = Header (u' greetings from SMTP ...... ', 'Utf-8 '). encode () server = smtplib. SMTP (smtp_server, 25) server. set_debuglevel (1) server. login (from_addr, password) server. sendmail (from_addr, [to_addr], msg. as_string () server. quit ()
We have compiled a function _ format_addr () to format an email address. Note that the name cannot be passed in simply, because if the name contains Chinese characters, it must be encoded using the Header object.
Msg ['to'] receives strings instead of lists. if multiple email addresses exist, separate them with commas.
After sending the email again, you can see the correct title, sender, and recipient in the recipient's email:
The recipient name you see may not be our input administrator, because many email service providers will automatically replace the recipient name with the user registration name when displaying the email, however, the display of other recipient names is not affected.
If you view the original Email content, you can see the following encoded Email header:
From: =?utf-8?b?UHl0aG9u54ix5aW96ICF?=
To: =?utf-8?b?566h55CG5ZGY?=
Subject: =?utf-8?b?5p2l6IeqU01UUOeahOmXruWAmeKApuKApg==?=
This is the text encoded by the Header object, including UTF-8 encoding information and Base64 encoding text. If we manually construct such encoded text, it is obviously complicated.
Send HTML mail
What if we want to send HTML emails instead of plain text files? The method is very simple. when constructing a MIMEText object, pass the HTML string and change the second parameter from plain to html:
msg = MIMEText('Hello' + 'send by Python...
' + '', 'html', 'utf-8')
Send the email again, and you will see the email displayed in HTML:
Send attachment
What should I do if I add an attachment to my Email? Emails with attachments can be considered as emails that contain several parts: Text and attachments. Therefore, a MIMEMultipart object can be constructed to represent the email itself, and a MIMEText can be added to it as the Mail body, add the MIMEBase object indicating the attachment to it:
# Email object: msg = MIMEMultipart () msg ['from'] = _ format_addr (u'python enthusiast <% s> '% from_addr) msg ['to'] = _ format_addr (u'administrator <% s> '% to_addr) msg ['subobject'] = Header (u' greetings from SMTP ...... ', 'Utf-8 '). encode () # The Mail body is MIMEText: msg. attach (MIMEText ('send with file... ', 'plain', 'utf-8') # Add a MIMEBase to read an image from the local device: with open ('/Users/michael/Downloads/test.png', 'RB') as f: # set the MIME and file name of the attachment. here is the png type: mime = MIMEBase ('image', 'PNG ', filename='test.png') # add the necessary header information: mime. add_header ('content-disposition', 'attachment ', filename='test.png') mime. add_header ('content-id', '<0>') mime. add_header ('x-Attachment-id', '0') # read the content of the Attachment: mime. set_payload (f. read () # encoded in Base64: encoders. encode_base64 (mime) # add to MIMEMultipart: msg. attach (mime)
Then, follow the normal sending process to send the msg (note that the type has changed to MIMEMultipart), and you will receive the following email with an attachment:
Send Image
How can I embed an image into the body of the email? Can I link an image address directly to an HTML email? The answer is that most email service providers automatically block images with external links because they do not know whether these links direct to malicious websites.
To embed an image into the body of the email, we only need to add the email as an attachment by sending the attachment, and then reference src = "cid: 0 "to embed the attachment as an image. If there are multiple images, numbers them in sequence, and then reference different CIDs: x.
Change the MIMEText code added to MIMEMultipart from plain to html, and then reference the image in the appropriate position:
msg.attach(MIMEText('Hello' + '' + '', 'html', 'utf-8'))
After sending the email again, you can see the effect of embedding the image directly into the body of the email:
Both HTML and Plain formats are supported.
If we send HTML mail, the recipient can normally browse the Mail content through a browser or software such as Outlook, but what if the recipient's device is too old to view HTML mail?
The method is to append a plain text message while sending the HTML message. if the recipient cannot view the HTML-format email, the system can automatically downgrade to view the plain text email.
You can use MIMEMultipart to combine an HTML and Plain. Note that the subtype is alternative:
Msg = MIMEMultipart ('alternative ') msg ['from'] =... msg ['to'] =... msg ['subobject'] =... msg. attach (MIMEText ('hello', 'plain ', 'utf-8') msg. attach (MIMEText ('Hello', 'HTML', 'utf-8') # send the msg object normally...
Encrypted SMTP
When the standard port 25 is used to connect to the SMTP server, plaintext transmission is used, and the whole process of sending emails may be eavesdropped. To send emails more securely, you can encrypt the SMTP session. In fact, you must first create an SSL secure connection and then use the SMTP protocol to send emails.
Some email service providers, such as Gmail, must provide the SMTP service for encrypted transmission. Let's take a look at how to send emails through Secure SMTP provided by Gmail.
You must know that the SMTP port of Gmail is 587. Therefore, modify the code as follows:
Smtp_server = 'smtp .gmail.com 'smtp _ port = 587 server = smtplib. SMTP (smtp_server, smtp_port) server. starttls () # The remaining code is exactly the same as the previous one: server. set_debuglevel (1 )...
You only need to call the starttls () method immediately after creating an SMTP object to create a secure connection. The subsequent code is exactly the same as the previous email sending code.
If you cannot connect to the SMTP server of Gmail due to network problems, please believe that our code is correct. you need to make necessary adjustments to your network settings.
Summary
Using Python's smtplib to send emails is very simple. as long as you have mastered the construction methods of various mail types and correctly set the mail header, you can send emails smoothly.
Constructing a mail object is a mescript object. if a MIMEText object is constructed, it indicates a text mail object. if a MIMEImage object is constructed, it indicates an image as an attachment, to combine multiple objects, use the MIMEMultipart object, and the MIMEBase can represent any object. Their inheritance relationships are as follows:
The code is as follows:
Message
+-MIMEBase
+-MIMEMultipart
+-MIMENonMultipart
+-MIMEMessage
+-MIMEText
+-MIMEImage
This nested relationship can be used to construct emails that are intended to be complex. You can use the email. mime document to view the packages and detailed usage.
Source code reference:
Https://github.com/michaelliao/learn-python/tree/master/email