前言
一封电子邮件的旅程是:
那么编写程序发送邮件的本质是:
编写MUA把邮件发到MTA上。
一、发送的协议是什么?
发邮件时,MUA和MTA 使用的协议是SMTP,后边的MTA到另一个MTA也是SMTP协议。
二、引入模块
Python对SMTP的支持有smithib和email两个模块:
email负责构造邮件,smbbib负责发送邮件。简单邮件传输协议(Simple Mail Transfer Protocol)SMTP)是从源地址到目的地址传送邮件的规则,由该协议控制信件的中转方式。Python的smiplib提供了一种很方便的途径发送电子邮件,对SMIP协议进行了简单的封装。
Python创建SMTP对象的语法如下:smtpObj = smtplib.SMTP([host[,port,[local_hostname]]])
语法中各个参数的说明如下:
- host:SMTP 服务器主机。一般是
SMTP+邮箱的域名.com
。如SMTP.qq.com - port:如果提供了host参数,就需要指定SMTP服务器使用的端口号,一般情况下smtp的端口号是25
什么是SMTP服务器
SMTP是Simple Message Transfer Protocol(简单邮件传输协议)的缩写,默认端口是25。SMTP主要负责邮件的转发,以及接收其他邮件服务器发来的邮件。
什么是端口号?
比如学校同一个食堂卖菜的管卖菜,卖饮料的管饮料
同一台电脑对外来说只有一个IP,但是一台电脑可以提供各种不同的服务,比如WEB服务,FTP服务,SMTP邮键服务。
端口就是用来区别的服务的,也就是说网络上的服务是用IP+端口这样的形式来区别的。
一般而言,FTP端口大家都用21,web(http)用80,这些端口也可以自己指定。
0~1023之间的端口是周知端口,就是说哪个端口分配给哪个服务一般是固定的,网络上大家都这么用,都知道。
1024~65535之间的端口是动态端口,不固定分配。
每个网络程序通信都要通过端口的,不管是QQ,BT,迅雷等等。
- local_hoatname:如果SMTP在本地主机上。只需要指定服务器地址为localhost 即可。
Python SMTP对象使用 sendmail 方法发送邮件的语法如下:
SMTP.sendmail(from_addr,to_addr,msg[,mail_options,rcpt_options]
参数说明:
- from_addr:邮件发送者的地址。
- to_addr:邮件接收者的地址。
- msg:发送消息。
三.普通文本邮件
本章以qq为例,使用前先在邮箱-设置-账户-开通POP3/SMTP服务,需要发送手机验证码,返回一个授权码。
代码如下:
MIME协议在邮件中的应用详解
电子邮件基本格式(MIME格式)
import smtplib
from email.mime.text import MIMEText
from email.header import Header
sender = '@qq.com'#自己的邮箱地址
pwd=''#授权码
receives = ['@qq.com']#接受者的邮箱地址
#三个参数,第一个是文本内容,第二个是文本格式,第三个是 utf-8 设置编码
message =MIMEText(' Hi Handsome boy 我在用 Python 给你发急救邮件,需要...','plain','utf-8')
message['From'] = Header('邮件测试','utf-8') #发件人
message['to'] = Header('测试','utf-8') #收件人
subject = 'Python SMTP 邮件测试' #标题
message['Subject'] = Header(subject,'utf-8')
#使用非本地服务器,需要建立ssl连接
try:
smtpObj = smtplib.SMTP_SSL("SMTP.qq.com",465)
smtpObj.login(sender,pwd)
smtpObj.sendmail(sender,receives,message.as_string())
print("邮件发送成功")
except smtplib.SMTPException as e:
print("Error: 无法发送邮件.Case:%s"%e)
四、发送HTML格式的邮件
方法很简单,在构造的MIMEText 对象时把 HTML字符串传进去,再把第二个参数变成html。
代码:
import smtplib
from email.mime.text import MIMEText
from email.header import Header
sender = '@qq.com'
pwd=''
receives = ['@qq.com']
mail_msg=""" #三个引号就表明里边的字符任意
<p>链接吗,你懂得</p>
<p><a href="https://www.120ask.com/zhishi/141092.html">这是一个链接</a></p>
"""
message =MIMEText(mail_msg,'html','utf-8')
message['From'] = Header('邮件测试','utf-8')
message['to'] = Header('测试','utf-8')
subject = 'Python SMTP 邮件测试'
message['Subject'] = Header(subject,'utf-8')
try:
smtpObj = smtplib.SMTP_SSL("SMTP.qq.com",465)
smtpObj.login(sender,pwd)
smtpObj.sendmail(sender,receives,message.as_string())
print("邮件发送成功")
except smtplib.SMTPException as e:
print("Error: 无法发送邮件.Case:%s"%e)
五.发送带附件邮件
带附件的邮件可以看作包含文本和各个附件,可以构造一个MIMEMutipati奠定件本身,然后往里面添加一个MIMEText作为邮件正文,再添加表示附件的MIMEBa sq。即可。
代码实现如下:
import smtplib
from email.mime.text import MIMEText
from email.header import Header
from email.mime.multipart import MIMEMultipart
sender = '@qq.com'
pwd=''
receives = ['@qq.com']
message =MIMEMultipart() #创建包围文本和内容的对象
message['From'] = Header('邮件测试','utf-8')
message['to'] = Header('测试','utf-8')
subject = 'Python SMTP 邮件测试'
message['Subject'] = Header(subject,'utf-8')
message.attach(MIMEText('资源懂得都懂','plain','utf-8')) #加入文本
att1=MIMEText(open('test.txt','rb').read(),'base64','utf-8')
att1['Content-Type']='application/octet-stream' #邮件正文类型,application/octet-stream(任意的二进制数据)
att1['Content-Disposition']='attachment;filename="runnoob.txt"'#命名不能有中文
message.attach(att1) #加入附件
try:
smtpObj = smtplib.SMTP_SSL("SMTP.qq.com",465)
smtpObj.login(sender,pwd)
smtpObj.sendmail(sender,receives,message.as_string())
print("邮件发送成功")
except smtplib.SMTPException as e:
print("Error: 无法发送邮件.Case:%s"%e)
五.发送嵌有图片的邮件
要把图片嵌入邮件正文,我们只需按照发送附件的方式把邮件作为附件添加进去,然后在HTML中通过引用Src=”cid:0"把附件作为图片嵌入。如果有多张图片,就需要给它们依次编号,然后引用不同的cidx。
代码:
import smtplib
from email.mime.text import MIMEText
from email.header import Header
from email.mime.multipart import MIMEMultipart
from email.mime.image import MIMEImage
sender = '@qq.com'
pwd=''
receives = ['@qq.com']
msgRoot =MIMEMultipart('related')
msgRoot['From'] = Header('邮件测试','utf-8')
msgRoot['to'] = Header('测试','utf-8')
subject = 'Python SMTP 邮件测试'
msgRoot['Subject'] = Header(subject,'utf-8')
msgAlternative =MIMEMultipart('alternative')
msgRoot.attach(msgAlternative)
mail_msg ="""
<p>图片资源来了!</p>
<p><a href="https://image.baidu.com/search/index?tn=baiduimage&ct=201326592&lm=-1&cl=2&ie=gb18030&word=%B6%FE%B4%CE%D4%AA%CD%BC%C6%AC%B4%F3%C8%AB%B8%DF%C7%E5&fr=ala&ala=1&alatpl=normal&pos=0">图片</a></p>
<p>图片演示:</p>
<p><img src='cid:image1'></p>
"""
msgAlternative.attach(MIMEText(mail_msg,"html",'utf-8'))
fp=open('test.png','rb')
msgImage=MIMEImage(fp.read())
fp.close()
msgImage.add_header('Content-ID','<image1>')
msgRoot.attach(msgImage)
try:
smtpObj = smtplib.SMTP_SSL("SMTP.qq.com",465)
smtpObj.login(sender,pwd)
smtpObj.sendmail(sender,receives,msgRoot.as_string())
print("邮件发送成功")
except smtplib.SMTPException as e:
print("Error: 无法发送邮件.Case:%s"%e)