协议
SMTP协议
SMTP的全称是“Simple Mail Transfer Protocol”,即简单邮件传输协议。它是一组用于从源地址到目的地址传输邮件的规范,通过它来控制邮件的中转方式。SMTP 协议属于TCP/IP协议簇,它帮助每台计算机在发送或中转信件时找到下一个目的地。SMTP 服务器就是遵循SMTP协议的发送邮件服务器。SMTP认证,简单地说就是要求必须在提供了账户名和密码之后才可以登录 SMTP 服务器,这就使得那些垃圾邮件的散播者无可乘之机。增加 SMTP 认证的目的是为了使用户避免受到垃圾邮件的侵扰。
SMTP已是事实上的E-Mail传输的标准。
POP协议
POP邮局协议负责从邮件服务器中检索电子邮件。它要求邮件服务器完成下面几种任务之一:从邮件服务器中检索邮件并从服务器中删除这个邮件;从邮件服务器中检索邮件但不删除它;不检索邮件,只是询问是否有新邮件到达。POP协议支持多用户互联网邮件扩展,后者允许用户在电子邮件上附带二进制文件,如文字处理文件和电子表格文件等,实际上这样就可以传输任何格式的文件了,包括图片和声音文件等。在用户阅读邮件时,POP命令所有的邮件信息立即下载到用户的计算机上,不在服务器上保留。
POP3(Post Office Protocol 3)即邮局协议的第3个版本,是因特网电子邮件的第一个离线协议标准。
IMAP协议
互联网信息访问协议(IMAP)是一种优于POP的新协议。和POP一样,IMAP也能下载邮件、从服务器中删除邮件或询问是否有新邮件,但IMAP克服了POP的一些缺点。例如,它可以决定客户机请求邮件服务器提交所收到邮件的方式,请求邮件服务器只下载所选中的邮件而不是全部邮件。客户机可先阅读邮件信息的标题和发送者的名字再决定是否下载这个邮件。通过用户的客户机电子邮件程序,IMAP可让用户在服务器上创建并管理邮件文件夹或邮箱、删除邮件、查询某封信的一部分或全部内容,完成所有这些工作时都不需要把邮件从服务器下载到用户的个人计算机上。
支持种IMAP的常用邮件客户端有:ThunderMail,Foxmail,Microsoft Outlook等。
SMTP
SMTP是发送邮件的协议,Python内置对SMTP的支持,可以发送纯文本邮件、HTML邮件以及带附件的邮件。
Python对SMTP支持有smtplib
和email
两个模块,email
负责构造邮件,smtplib
负责发送邮件。
准备工作
获取邮箱服务器的授权码
QQ邮箱为例:
2.进入到账户页面
-
滚动到 “开启服务”,然后选择开启“ IMAP/SMTP服务
4.按照提示进行设置后就会出现你所需要的授权码
发送邮件
python发邮件需要掌握两个模块的用法,smtplib和email,这俩模块是python自带的,只需import即可使用。smtplib模块主要负责发送邮件,email模块主要负责构造邮件。
smtplib模块主要负责发送邮件:是一个发送邮件的动作,连接邮箱服务器,登录邮箱,发送邮件(有发件人,收信人,邮件内容)。
email模块主要负责构造邮件:指的是邮箱页面显示的一些构造,如发件人,收件人,主题,正文,附件等。
smtplib模块
基本使用
import smtplib
smtp = smtplib.SMTP()
smtp.connect('smtp.163.com',25)
smtp.login(username, password)
smtp.sendmail(sender, receiver, msg.as_string())
smtp.quit()
说明:
smtplib.SMTP():实例化SMTP()
connect(host,port):
host:指定连接的邮箱服务器。常用邮箱的smtp服务器地址如下:
新浪邮箱:smtp.sina.com
新浪VIP:smtp.vip.sina.com
搜狐邮箱:smtp.sohu.com
126邮箱:smtp.126.com
139邮箱:smtp.139.com
QQ邮箱:smtp.qq.com
163网易邮箱:smtp.163.com
port:指定连接服务器的端口号,默认为25.(企业邮箱一般走465,994,更为安全)
login(user,password):
user:登录邮箱的用户名。
password:你刚才获取的授权码(不是登录密码)
sendmail(from_addr,to_addrs,msg,...):
from_addr:邮件发送者地址
to_addrs:邮件接收者地址。字符串列表['接收地址1','接收地址2','接收地址3',...]或'接收地址'
msg:发送消息:邮件内容。一般是msg.as_string():as_string()是将msg(MIMEText对象或者MIMEMultipart对象)变为str。
quit():用于结束SMTP会话。
email模块
email模块下有mime包,mime英文全称为“Multipurpose Internet Mail Extensions”,即多用途互联网邮件扩展,是目前互联网电子邮件普遍遵循的邮件技术规范。
该mime包下常用的有三个模块:text,image,multpart
导入方法如下:
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.image import MIMEImage
构造一个邮件对象就是一个Message
对象,如果构造一个MIMEText
对象,就表示一个文本邮件对象,如果构造一个MIMEImage
对象,就表示一个作为附件的图片,要把多个对象组合起来,就用MIMEMultipart
对象,而MIMEBase
可以表示任何对象。它们的继承关系如下:
Message
+- MIMEBase
+- MIMEMultipart
+- MIMENonMultipart
+- MIMEMessage
+- MIMEText
+- MIMEImage
2.1 text说明
邮件发送程序为了防止有些邮件阅读软件不能显示处理HTML格式的数据,通常都会用两类型分别为"text/plain"和"text/html"
构造MIMEText对象时,第一个参数是邮件正文,第二个参数是MIME的subtype,最后一定要用utf-8编码保证多语言兼容性。
2.1.1添加普通文本
text = "hello mail!"
text_plain = MIMEText(text,'plain', 'utf-8')
2.1.2添加超文本
html = """
Here is the link you wanted.
"""
text_html = MIMEText(html,'html', 'utf-8')
2.1.3添加附件
sendfile=open(r'D:\pythontest\1111.txt','rb').read()
text_att = MIMEText(sendfile, 'base64', 'utf-8')
text_att["Content-Type"] = 'application/octet-stream'
text_att["Content-Disposition"] = 'attachment; filename="显示的名字.txt"'
2.2 image说明
添加图片:
sendimagefile=open(r'D:\pythontest\testimage.png','rb').read()
image = MIMEImage(sendimagefile)
image.add_header('Content-ID','')
2.3 multpart说明
常见的multipart类型有三种:multipart/alternative, multipart/related和multipart/mixed。
邮件类型为"multipart/alternative"的邮件包括纯文本正文(text/plain)和超文本正文(text/html)。
邮件类型为"multipart/related"的邮件正文中包括图片,声音等内嵌资源。
邮件类型为"multipart/mixed"的邮件包含附件。向上兼容,如果一个邮件有纯文本正文,超文本正文,内嵌资源,附件,则选择mixed类型。
msg = MIMEMultipart('mixed')
我们必须把Subject,From,To,Date添加到MIMEText对象或者MIMEMultipart对象中,邮件中才会显示主题,发件人,收件人,时间(若无时间,就默认一般为当前时间,该值一般不设置)。
msg = MIMEMultipart('mixed')
msg['Subject'] = 'Python email test'
msg['From'] = '[email protected] '
msg['To'] = '[email protected]'
msg['Date']='2012-3-16'
说明:
msg.add_header(_name,_value,**_params):添加邮件头字段。
msg.as_string():是将msg(MIMEText对象或者MIMEMultipart对象)变为str,如果只有一个html超文本正文或者plain普通文本正文的话,一般msg的类型可以是MIMEText;如果是多个的话,就都添加到MIMEMultipart,msg类型就变为MIMEMultipart。
msg.attach(MIMEText对象或MIMEImage对象):将MIMEText对象或MIMEImage对象添加到MIMEMultipart对象中。MIMEMultipart对象代表邮件本身,MIMEText对象或MIMEImage对象代表邮件正文。
以上的构造的文本,超文本,附件,图片都何以添加到MIMEMultipart('mixed')中:
msg.attach(text_plain)
msg.attach(text_html)
msg.attach(text_att)
msg.attach(image)
实例代码:
import smtplib
from email.mime.application import MIMEApplication
from email.mime.image import MIMEImage
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from_mail = '发送邮箱'
to_mails = '接收邮箱,可以是个列表'
password = '你的授权码'
# 普通纯文本和html邮件
def text_mail():
# 消息主体
content = '这是一个html邮件
'
# 配置邮件内容
# 如果加上参数MIMEText(content,'html','utf-8')就可以指定是超文本标记语言
# 默认的类型是'plain'
msg = MIMEText(content)
# 配置标题
msg['Subject'] = '邮件标题'
# 配置发送人
msg['From'] = from_mail
# 配置收件人的别名
msg['To'] = '2001'
# 创建SMTP服务器对象
smt = smtplib.SMTP('smtp.qq.com')
# 登录服务器
smt.login(user=from_mail, password=password)
# 发送邮件
try:
# 调用sendmail方法发送邮件
# 第一个参数是发送人,必须跟登录账号相同
# 第二个是收件人列表,也可以是一个单独的邮箱账号
# msg.as_string():是将msg(MIMEText对象或者MIMEMultipart对象)变为str,
# 如果只有一个html超文本正文或者plain普通文本正文的话,一般msg的类型可以是MIMEText;
# 如果是多个的话,就都添加到MIMEMultipart,msg类型就变为MIMEMultipart。
smt.sendmail(from_mail, to_mails, msg.as_string())
print('邮件发送成功!')
except Exception as erro_msg:
print('发送失败', erro_msg)
# 关闭邮件服务器
smt.quit()
# 带附件的邮件
def multipart_mail():
"""
带附件的邮件要用MIMEMultipart对象
每一个附件就像一个个部件一样,需要单独构造
最后将小部件都添加到MIMEMultipart中
就像搭积木一样
:return:None
"""
# 构建消息主体
content = '这里是消息主体!'
content_part = MIMEText(content)
# 构建图片附件
# MIMEImage(图片的二进制数据,图片名字)
image = 'galaxy.jpg'
image_part = MIMEImage(open(image, 'rb').read(), image.split('.')[-1])
# 附件需要添加邮件头字段,指定文件类型和文件名
# 不然接收方会看到纯二进制的数据
# 第一个第二个参数固定写法,原理不详
image_part.add_header('Content-Disposition', 'attachment', filename=image)
# 构建文档或其他文件
# MIME的类型有很多,可以针对图片,音频,视频等等
# 如果不知道文件的类型,最简单的方式就是直接用MIMEApplication
md = 'HTH项目开发文档.md'
md_part = MIMEApplication(open(md, 'rb').read())
md_part.add_header('Content-Disposition', 'attachment', filename=md)
# 部件构建好了就创建MIMEMultipart对象,一个个添加
m = MIMEMultipart()
m.attach(content_part)
m.attach(image_part)
m.attach(md_part)
# 跟文本邮件一样设置基本参数
m['Subject'] = '我是标题'
m['From'] = from_mail
m['To'] = '2001'
# 发送邮件跟文本邮件一样
try:
smt = smtplib.SMTP('smtp.qq.com')
smt.login(from_mail, password)
smt.sendmail(from_mail, to_mails, m.as_string())
print('发送成功')
except Exception as erro_msg:
print('发送失败', erro_msg)
def main():
# 普通邮件
# text_mail()
# 带附件的邮件
multipart_mail()
if __name__ == '__main__':
main()