发送邮件

#SMTP是发送邮件的协议,Python内置对SMTP支持,可以发送纯文本邮件、HTML邮件以及带附件的邮件。本节腾讯企业邮箱的服务为例进行介绍。学习本节内容时,可以自己开通对应的邮箱服务,各个邮件服务公司有介绍邮箱服务的开通方法,参照这些开通方法开通即可。如果安装了邮箱服务,就可以使用自己的邮箱服务器进行学习。
 
1、SMTP发送邮件
#Python对SMTP的支持有smtplib和email两个模块,email负责构造邮件,smtplib负责发送邮件。
#简单邮件传输协议(Simple Mail Transfer Protocol,SMTP)是从源地址到目的地址传送邮件的规则,由该协议控制信件的中转方式。
#Python的smtplib提供了一种很方便的途径发送电子邮件,对SMTP协议进行了简单的封装。
#Python创建SMTP对象的语法如下:
1 smtpObj=smtplib.SMTP([host[,port[,local_hostname]]])
#语法中各个参数说明如下:
#host:SMTP服务器主机。可以指定主机的IP地址或域名(如www.baidu.com),是可选参数。
#port:如果提供了host参数,就需要指定SMTP服务使用的端口号。一般情况下SMTP的端口号为25.
#local_hostname:如果SMTP在本机主机上,只需要指定服务器地址为localhost即可。
#如果创建SMTP对象时提供了host和port两个参数,在初始化时会自动调用connect方法连接服务器。
#PythonSMTP对象使用sendmail方法发送邮件的语法如下:
1 SMTP.sendmail(from_addr,to_addrs,msg[,mail_options,rcpt_options])
#语法中各个参数说明如下:
#from_addr:邮件发送者的地址。
#to_adds:字符串列表,邮件发送地址。
#msg:发送消息。
#msg是字符串,表示邮件内容。我们知道邮件一般由标题、发信人、收件人、邮件内容、附件等构成,发送邮件时,要注意msg的格式。这个格式就是SMTP协议中定义的格式。
#SMTP类中提供了下表所示的一下常用方法。
方法
描述
set_debuglevel(level)
设置是否为调试模式。默认为False,即非调试模式,
表示不输出任何调试信息
connect([host[,port]])
连接到指定的SMTP服务器。参数分别表示SMTP主机和端口
docmd(cmd,[,argstring])
向SMTP服务器发送指令。可选参数argstring表示指令的参数
helo([hostname])
向服务器确认身份。相当于告诉SMTP服务器“我是谁”
has_extn(name)
判断指定名称在服务器邮件列表中是否存在,
出于安全考虑。SMTP服务器往往屏蔽该指令
verify(address)
判断指定邮件地址是否在服务器中存在。
出于安全考虑,SMTP服务器往往屏蔽该指令
login(use,password)
登陆SMTP服务器。现在几乎所有SMTP服务器都必须验证
用户信息合法后才允许发送邮件
quit()
断开与SMTP服务器的连接,相当于发送quit指令
#普通文本邮件发送的实现关键要将MIMEText中的_subtype设置为plain。首先导入smtplib和mimetext。创建smtplib.smtp实例,连接邮件SMTP服务器,登陆后发送,具体代码如下:
 1 #! /usr/bin/python3
 2 #-*-coding:UTF-8-*-
 3 #Email
 4 
 5 import smtplib
 6 from email.mime.text import MIMEText
 7 from email.header import Header
 8 sender='from@qq.com'  #发件人
 9 pwd='xxxxxxx'            #邮箱密码
10 receivers=['xxxxxxxxx@qq.com']   #收件人
11 
12 message=MIMEText('This is test','plain','utf-8')   #邮件文本
13 message['From']=Header('测试邮件','utf-8')  #邮件主题
14 message['To']=Header('测试收件人') #邮件收件人显示名称
15 
16 subject='Python email test'
17 message['Subject']=Header(subject,'utf-8')
18 
19 try:
20     smtpObj=smtplib.SMTP_SSL("smtp.exmail.qq.com",465)
21     smtpObj.login(sender,pwd)
22     smtpObj.sendmail(sender,receivers,message.as_string())
23     print("邮件发送成功")
24 except smtplib.SMTPException as e:
25     print("Error:无法发送邮件.Case:%s"%e)
#我们使用3个引号设置邮件信息。标准邮件需要3个头部信息:From、To和Subject。每个信息直接使用空行分割。
#我们通过实例化smtplib模块的SMTP_SSL对象smtpObj连接SMTP访问,并使用sendermail方法发送信息。
#执行以上程序,如果你开通了非本地邮件服务,就会输出:
1 D:Pythonworkspacedatatime20180210>python Email.py
2 邮件发送成功
#如果本地主机安装了sendmail服务,发送邮件的代码可以更改为:
 1 #! /usr/bin/python3
 2 #-*-coding:UTF-8-*-
 3 #localhost_email
 4 
 5 import smtplib
 6 from email.mime.text import MIMEText
 7 from email.header import Header
 8 
 9 sender='xxxxxx@xxxxxx.com'
10 receviers=['xxxxxxx@qq.com']
11 
12 message=MIMEText('Thi is test mail','plain','utf-8')
13 message['From']=Header('测试邮件','utf-8')
14 message['To']=Header('测试收件','utf-8')
15 
16 subject='Python test mail'
17 message['Subject']=Header(subject,'utf-8')
18 
19 try:
20     smtpObj=smtplib.SMTP('localhost')
21     smtpObj.sendermail(sender,receviers,message.as_string())
22     print('邮件发送成功')
23 except smtplib.SMTPException as e:
24     print('Error:无法发送邮件.Case:'%e)
#不需要客户端授权密码、SSL连接和登陆服务。
 
2、发送HTML格式邮件
#如果我们要发送的是HTML邮件,而不是普通的纯文本文件怎么办?方法很简单,在构造MIMEText对象时把HTML字符串传进去,再把第二个参数由plain变为html就可以了。代码实现如下:
 1 #! /usr/bin/python3
 2 #-*-coding:UTF-8-*-
 3 #HTML_Email
 4 
 5 import smtplib
 6 from email.mime.text import MIMEText
 7 from email.header import Header
 8 
 9 sender='xxxxxx@xxxxxx.com'
10 pwd='xxxxx'
11 receivers=['xxxxxxxxxx@qq.com']
12 
13 mail_msg="""
14 <p>Python test mail..</p>
15 <p><a href="http://www.cnblogs.com/DLHe/">这是一个链接</a></p>
16 """
17 
18 message=MIMEText(mail_msg,'html','utf-8')
19 message['From']=Header('test mail','utf-8')
20 message['To']=Header('test','utf-8')
21 subject="Python test mail"
22 message['Subject']=Header(subject,'utf-8')
23 
24 try:
25     smtpObj=smtplib.SMTP_SSL('smtp.exmail.qq.com',465)
26     smtpObj.login(sender,pwd)
27     smtpObj.sendmail(sender,receivers,message.as_string())
28     print('邮件发送成功')
29 except smtplib.SMTPException as e:
30     print('Error:无法发送邮件.Case:%s'%e)
#执行以上程序,如果你开通了非本地服务,就会输出:
1 D:Pythonworkspace>python HTML_Email.py
2 邮件发送成功
3、发送带附件的邮件
#如果Email中要添加附件怎么办?
#带附件的邮件可以看作包含文本和各个附件,可以构造一个MIMEMultipart对象代表邮件本身,然后往里面添加一个MIMEText作为邮件正文,再添加表示附件的MIMEBase对象即可。代码实现如下:
 1 #! /usr/bin/python3
 2 #-*-coding:UTF-8-*-
 3 
 4 
 5 import smtplib
 6 from email.mime.text import MIMEText
 7 from email.mime.multipart import MIMEMultipart
 8 from email.header import Header
 9 
10 sender='xxxx@xxx.com'
11 pwd='xxxxxx'
12 receviers=['xxxxxxxxxxxxxx@qq.com']
13 
14 message=MIMEMultipart()
15 message['From']=Header('test mail','utf-8')
16 message['To']=Header('test','utf-8')
17 subject='Python mail test'
18 message['Subject']=Header(subject,'utf-8')
19 message.attach(MIMEText('This is a mail test','plain','utf-8'))
20 
21 att1=MIMEText(open('test.txt','rb').read(),'base64','utf-8')
22 att1['Content-Type']='application/octet-stream'
23 att1['Content-Disposition']='attachment;filname="test.txt"'
24 message.attach(att1)
25 
26 att2=MIMEText(open('runoob.txt','rb').read(),'base64','utf-8')
27 att2['Content-Type']='application/octet-stream'
28 att2['Content-Disposition']='attachment;filname="runoob.txt'
29 message.attach(att2)
30 
31 try:
32     smtpObj=smtplib.SMTP_SSL('smtp.exmail.qq.com',465)
33     smtpObj.login(sender,pwd)
34     smtpObj.sendmail(sender,receviers,message.as_string())
35     print('邮件发送成功')
36 except smtplib.SMTPException as e:
37     print('Error:无法发送邮件.Case:%s'%e)
#执行结果如下:
1 D:Pythonworkspace>python MIMEMultipart.py
2 邮件发送成功
#如果本地主机安装了sendmail服务,就不需要客户端授权密码、SSL连接和登陆服务,直接使用smtplib模块的SMTP对象连接本地访问即可。
 
4、发送图片
#如果要把一个图片嵌入邮件正文,怎么做呢?是否可以直接在HTML邮件中链接图片地址?
#大部分邮件服务商都会自动屏蔽带有外链的图片,因为不知道这些链接是否指向恶意网址。
#要把图片嵌入邮件正文,我们只需要按照发送附件的方式把邮件作为附件添加进去,然后在HTML中通过引用src="cid:0"把附件作为图片嵌入。如果有多张图片,就需要给他们一次编号,然后引用不用的cid:x。
 1 #! /usr/bin/python3
 2 #-*-coding:UTF-8-*-
 3 #src
 4 
 5 import smtplib
 6 from email.mime.image import MIMEImage
 7 from email.mime.multipart import MIMEMultipart
 8 from email.mime.text import MIMEText
 9 from email.header import Header
10 
11 sender='xxxxx@xxxxxx.com'
12 pwd='bxxxxxxx'
13 receivers=['xxxxxxxx@qq.com']
14 
15 msgRoot=MIMEMultipart('related')
16 msgRoot['From']=Header('test mail','utf-8')
17 msgRoot['To']=Header('test','utf-8')
18 subject='Python test mail'
19 msgRoot['Subject']=Header(subject,'utf-8')
20 
21 msgAlternative=MIMEMultipart('alternative')
22 msgRoot.attach(msgAlternative)
23 
24 mail_msg="""
25 <p>Python test mail...</p>
26 <p><a href="http://www.python.org">Python官方网站</a></p>
27 <p>图片演示:</p>
28 <p><img src="cid:image1"></p>
29 """
30 
31 msgAlternative.attach(MIMEText(mail_msg,'html','utf-8'))
32 
33 #指定图片为当前目录
34 fp=open('test.png','rb')
35 msgImage=MIMEImage(fp.read())
36 fp.close()
37 
38 #定义图片ID,在HTML文本中引用
39 msgImage.add_header('Content-ID','<image1>')
40 msgRoot.attach(msgImage)
41 
42 try:
43     #使用非本地服务器,需要建立ssl连接
44     smtpObj=smtplib.SMTP_SSL("smtp.exmail.qq.com",465)
45     smtpObj.login(sender,pwd)
46     smtpObj.sendmail(sender,receivers,msgRoot.as_string())
47     print("邮件发送成功")
48 except smtplib.SMTPException as e:
49     print('Error:无法发送邮件.Case:%s'%e)
#执行以上程序,如果有开通了非本地服务,就会输出:
1 D:Pythonworkspacedatatime20180211>python src.py
2 邮件发送成功
#如果本地主机安装了sendmail服务,就不需要客户端授权密码、SSL连接和登陆服务,直接使用smtplib模块的SMTP对象连接本地访问即可。
 
5、同时支持HTML和Plain格式
#如果我们发送HTML邮件,收件人通过浏览器或Outlook之类的软件就可以正常浏览邮件内容。如果收件人使用的设备太古老,查看不了HTML邮件怎么办呢?
#办法实在发送HTML的同时附件一个纯文本,如果收件人无法查看HTML格式的邮件,就可以自动降级查看纯文本邮件。
#利用MIMEMultipart可以组合一个HTML和Plain,注意指定是subtype是alternative。使用代码格式如下:
 1 #! /usr/bin/python3
 2 #-*-coding:UTF-8-*-
 3 #HTML_PLAIN
 4 
 5 import smtplib
 6 from email.mime.image import MIMEImage
 7 from email.mime.multipart import MIMEMultipart
 8 from email.mime.text import MIMEText
 9 from email.header import Header
10 
11 sender='xxxxx@xxxxx.com'
12 pwd='xxxxxx'
13 receivers=['xxxxx@qq.com']
14 
15 msgRoot=MIMEMultipart('related')
16 msgRoot['From']=Header('test mail','utf-8')
17 msgRoot['To']=Header('TEST','utf-8')
18 subject='Python test mail'
19 msgRoot['Subject']=Header(subject,'utf-8')
20 
21 msgAlternative=MIMEMultipart('alternative')
22 msgRoot.attach(msgAlternative)
23 
24 msgAlternative.attach(MIMEText('hello','plain','utf-8'))
25 mail_msg='<html><body><h1>hello</h1></body></html>'
26 msgAlternative.attach(MIMEText(mail_msg,'html','utf-8'))
27 
28 #指定图片为当前目录
29 fp=open('test.png','rb')
30 msgImage=MIMEImage(fp.read())
31 fp.close()
32 
33 #定义图片ID,在HTML文本中引用
34 msgImage.add_header('Content-ID','<image1>')
35 msgRoot.attach(msgImage)
36 
37 try:
38     smtpObj=smtplib.SMTP_SSL("smtp.exmail.qq.com",465)
39     smtpObj.login(sender,pwd)
40     smtpObj.sendmail(sender,receivers,msgRoot.as_string())
41     print('邮件发送成功')
42 except smtplib.SMTPException as e:
43     print('Error:无法发送邮件.Case:%s'%e)
#执行以上程序,如果你开通了非本地服务,就会输出:
D:Pythonworkspacedatatime20180211>python HTML_PLAIN.py
邮件发送成功
6、加密SMTP
#使用标准25端口连接SMTP服务器时使用的是明文传输,发送邮件的整个过程可能会被窃听。要更安全地发送邮件,可以加密SMTP会话,实际上是先创建SSL安全连接,然后使用SMTP协议发送邮件。
#某些邮件服务商(如Gmail)提供的SMTP服务必须进行加密传输。下面来看如何通过Gmail提供的安全SMTP发送邮件。
#由于Gmail的SMTP端口是587,因此修改代码如下:
1 smtp_server='smtp.gmail.com'
2 smtp_port=587
3 server=smtplib.SMTP(smtp_server,smtp_port)
4 server.starttls()
5 server.set_debuglevel(1)
#只需要要创建SMTP对象后立刻调用starttls()方法,就可以创建安全连接。后面的代码和前面的发送邮件代码完全一样。
原文地址:https://www.cnblogs.com/DLHe/p/8457959.html