一、smtplib模块
SMTP 简单邮件传输协议,是专门用于发送电子邮件的协议。
SMTP规定了电子邮件应该如何格式化、加密、在邮件服务器之间传递,以及点击发送后计算机要处理的所有其他细节。
利用Python自带的smtplib模块,我们可以实现从第三方SMTP服务器(比如QQ邮箱)登录并发送电子邮件。
——
1. smtplib使用步骤
代码演示:
import smtplib
# 第一步:创建SMTP服务器对象
smtpobj = smtplib.SMTP('smtp.qq.com',587)
# 第二步:首先跟服务器打招呼
smtpobj.ehlo()
# 第三步:如果连接的SMTP的587端口,需要进行连接加密步骤(如果是465端口则可以跳过)
smtpobj.starttls()
# 第四步:登录到SMTP服务器
smtpobj.login('*******@qq.com','aaaabbbbccc')
# 输入邮箱账号以及授权码(这里并不是输入邮箱密码)
# 第五步:发送电子邮件(发件地址,收件地址,内容)
smtpobj.sendmail('*******@qq.com', '########@qq.com',
'Subject: So long. \nDear Alice, so long and thanks for all the fish. Sincerely,Bob') # Subject为邮件主题,通过换行符(\n)来区分主题和正文
#第六步:从SMTP服务器断开
smtpobj.quit()
——
2. 两个重点关注的点
需要重要说明的两个地方:
【01】如何开启第三方SMTP服务器并获得授权码
以QQ邮箱为例,登录自己的QQ邮箱,进入 [设置-账户],即可看到关于SMTP服务开启的选项,点击开启,按照提示要求进行,即可打开我们QQ邮箱的SMTP服务并获得相对应的授权码。
【02】邮件发送中无法使用中文的问题
如果邮件内容中有中文字符
# 第五步:发送电子邮件(发件地址,收件地址,内容)
smtpobj.sendmail('*******@qq.com', '########@qq.com',
'Subject: 大家好\n你好,你好鸭!') # 无法使用中文字符
会出现以下报错
本人也查阅了相关资料,发现该错误一般是出现在Python2的版本中,Python3默认字符集基本都是"utf-8"。
所以也不清楚为啥会出现无法使用中文的情况(要是哪些大神知道这是啥原因,恳请指点一二!)
那就意味着我们不能发中文内容的邮件呢么?
当然不是,在smtplib基础上结合email,我们就能实现。
二、email模块
smtplib与email相结合,我们能够实现更加强大的发送邮件功能,不仅能够发送纯文本,还能够发送html文本邮件、正文中含有图片的邮件以及带有附件的邮件。
那么我们首先来认识了解一下email模块中我们常用的函数方法。
——
1. 常用函数详解
from email.header import Header
from email.mime.text import MIMEText
from email.mime.image import MIMEImage
from email.mime.multipart import MIMEMultipart
通过使用Header()函数,我们可以定义邮件头信息,比如From(发件人)、To(收件人)、Subject(邮件主题)。
msg_root['From'] = Header('逆旅鸭<*******@qq.com>','utf-8') # 发件人
msg_root['To'] = Header('李XXX<&&&&&&&&@qq.com>','utf-8') # 收件人
subject = '好久不见,别来无恙'
msg_root['subject'] = Header(subject,'utf-8') # 邮件主题
关于MIMEText、MIMEImage和MIMEMultipart最好放在一起解释。
- 首先这个三个都是用来构造邮件对象
- MIMEText表示文本对象,包含三个值(正文内容,正文类型,正文内容编码)。正文类型有"plain"纯文本,"html"超文本。
- MIMEImage表示图片对象,通过使用MIMEImage,我们能够在正文内容中显示图片
- MIMEMultipart,表示整个邮件,可以将多个对象组合在一起。
重点说下MIMEMultipart,它的参数有三个值
- alternative:邮件正文包括纯文本和超文本;
- related:邮件正文除了文本,还包括图片、声音等内嵌资源;
- mixed:邮件包含文本、图片、附件等等内容,基本上包括了所有可发送内容。一般情况下我们使用的是它。
——
2. 邮件构造原理
一张图告诉你email邮件构造原理
- 创建MIMEMultipart(‘mixed’)
- 根据个人需求,分别构造纯文本、超文本、正文带图片、带附件的部分
- 再将以上部分通过attach()方法添加到MIMEMultipart对象中
简单列下每个内容构造的代码
【01】构造纯文本
text_info = 'Hello world!'
text_sub = MIMEText(text_info, 'plain', 'utf-8')
msg_root.attach(text_sub) # 将纯文本对象添加到MIMEMultipart对象
【02】构造超文本
html_info = """
<p>CSDN首页</p>
<p><a href="https://www.csdn.net/">欢迎进入CSDN</a></p>
"""
html_sub = MIMEText(html_info, 'html', 'utf-8')
msg_root.attach(html_sub) # 将超文本对象添加到MIMEMultipart对象
【03】构造正文显示图片
# 要在正文显示图片,需要先构造超文本
html_info = """
<p>图片演示:</p>
<p><img src="cid:image1"></p>
"""
html_sub = MIMEText(html_info, 'html', 'utf-8')
msg_root.attach(html_sub) # 将超文本对象添加到MIMEMultipart对象
image_file = open(pic_address, 'rb').read()
image = MIMEImage(image_file)
image.add_header('Content-ID', '<image1>') # 将图片命名
msg_root.attach(image) # 将图片对象添加到MIMEMultipart对象
【04】构造附件
enc_file = open(enc_address,'rb').read()
enc = MIMEText(enc_file, 'base64', 'utf-8') # 注意这里要加入参数'base64'
enc['Content-Type'] = 'application/octet-stream'
enc.add_header('Content-Disposition', 'attachment', filename=enc_name) # 给附件命名
msg_root.attach(enc) # 将附件对象添加到MIMEMultipart对象
以上就是关于email模块的介绍,基本上能够满足于我们日常的发送电子邮件需求了。
在下一部分我会整合smtplib与email的使用,通过使用构造函数的方式,让整个代码更加清晰易懂且方便。
三、smtp+email轻松发送邮件
代码演示如下:
import smtplib
from email.header import Header
from email.mime.text import MIMEText
from email.mime.image import MIMEImage
from email.mime.multipart import MIMEMultipart
# 【01】构建邮件头部信息
def basic_info(from1, to1, subject1):
msg_root['From'] = Header(from1,'utf-8') # 发件人
msg_root['To'] = Header(to1,'utf-8') # 收件人
subject = subject1
msg_root['subject'] = Header(subject,'utf-8') # 邮件主题
# 【02】构造文本内容
def text(text1):
text_info = text1
text_sub = MIMEText(text_info, 'plain', 'utf-8')
msg_root.attach(text_sub)
# 【03】构造超文本
def html(hype_text):
html_info = hype_text
html_sub = MIMEText(html_info, 'html', 'utf-8')
msg_root.attach(html_sub)
# 【04】构造正文显示图片
def image(pic_address):
image_file = open(pic_address, 'rb').read()
image = MIMEImage(image_file)
image.add_header('Content-ID', '<image1>')
msg_root.attach(image)
#【05】构造附件
def enclosure(enc_address, enc_name):
enc_file = open(enc_address,'rb').read()
enc = MIMEText(enc_file, 'base64', 'utf-8')
enc['Content-Type'] = 'application/octet-stream'
enc.add_header('Content-Disposition', 'attachment', filename=enc_name)
msg_root.attach(enc)
# 【06】程序主体
try:
mail_host = 'smtp.qq.com' # QQ邮箱SMTP服务器地址
mail_user = '*********@qq.com' # 邮箱账号
mail_pass = 'aaaabbbbbbcccccc' # 邮箱授权码
sender = '[email protected]' # 发件人邮箱地址
receivers = ['%%%%%%%%%@qq.com'] # 收件人邮箱地址
smtpobj = smtplib.SMTP() # 创建SMTP对象
smtpobj.connect(mail_host, 587) # 连接邮箱SMTP服务器
smtpobj.login(mail_user, mail_pass) # 登录SMTP服务器
msg_root = MIMEMultipart('mixed')
basic_info('逆旅鸭','李XX','邮件发送测试') # 写入邮件头部信息
text('这是 Python 邮件发送测试....') # 在正文内容写入纯文本
# 如果要在正文显示图片,需要在html中写入
html_text = """
<p>CSDN首页</p>
<p><a href="https://www.csdn.net/">欢迎进入CSDN</a></p>
<p>图片演示:</p>
<p><img src="cid:image1"></p>
"""
html(html_text) # 在正文内容写入超文本
image('开启QQ邮箱的SMTP服务.png') # 在正文内容显示图片
enclosure('test.txt', '纪念品.txt') # 添加附件并命名“纪念品.txt”
smtpobj.sendmail(sender,receivers,msg_root.as_string()) # 发送电子邮件
print('邮件发送成功')
smtpobj.quit() # 断开SMTP服务器
except smtplib.SMTPException:
print('Error: 无法发送邮件')
最后运行程序,就会在邮箱中接受到这样一封邮件
四、复盘总结
- 以QQ邮箱为例,我们如果要利用python发送电子邮件,需要打开QQ邮箱的SMTP服务,并获得授权码
- 关于smtplib与email模块的结合使用:利用smptlib实现连接、登录以及最终的邮件发送功能,利用email来构造整个邮件体
- 熟练掌握email模块中最常用的4个功能:Header()、MIMEText()、MIMEImage()、MIMEMultipart()