一、普及下邮件协议
邮件协议包括有三种:SMTP协议,POP3协议,IMAP协议
1、SMTP协议,简称简单邮件传输协议,主要是源地址到目标地址传输,必须登陆账号和密码才能登陆SMTP服务器。Python的两个模块smtplib和email模块。
2、POP3协议,邮局协议,负责从邮件服务器中检索邮件,将全部邮件从服务器中下载下来,主要支持三种操作:
(1)从邮件服务器中检索邮件后并删除邮件
(2)从邮件服务器中检索邮件后不删除
(3)询问是否有新的邮件到
3、IMAP协议则是在POP3协议的基础上克服其缺点
(1)从服务器中检索到邮件后可以不用全部下载,可以选择性下载
(2)可决定客户机请求邮件服务器提交所收到的邮件的方式
二、Python发送邮件两个模块smtplib、email
1、Email:负责构造邮件,包括标题和正文等
(1)MIMEText模块--正文
from email.mime.text import MIMEText
#content:邮件发送的内容 #plain:纯文本 #utf-8:设置编码,兼容多语言 message = MIMEText(‘content’,’plain/html/base64’,’utf-8’)
(2)Header标题
from emial.header import Header #邮件标题 subject = 'The title of the email' message['Subject'] = Header(subject, 'utf-8')
2、smtplib:负责发送邮件,包括账号,密码,服务器等
import smtplib
sender = 'from@xxx.com' password = ‘xxxxxx’ #授权码 receivers = ['To@xxx.com'] server = ‘第三方邮件服务商服务器名’ message = MIMEText('内容', 'plain', 'utf-8')
#发送者
message['From'] = Header("sender", 'utf-8')
#接收者,[]可以写多个邮件地址群发
#receivers = ['XXXXXX@qq.com',’xxxxxx@qq.com’]
message['To'] = Header("reciver", 'utf-8')
#发送 smtpObj = smtplib.SMTP()
#smtpObj.connet(server,465)
smtpObj = smtplib.SMTP_SSL(server,465)
smtpObj.login(user, password)
smtpObj.sendmail(sender, receivers, message.as_string())
smtpObj.quit() print(“success”)
注:
后期测试的时候发现一直报连接失败的错误信息:
网上找了下原因,后来才发现,一些邮箱登录比如 QQ 邮箱需要 SSL 认证,所以 SMTP 已经不能满足要求,而需要SMTP_SSL,解决办法为:
#把smtpObj.connect(server,465)替换为smtpObj = smtplib.SMTP_SSL(server,465) smtpObj = smtplib.SMTP_SSL(server,465)
扩展:
服务器则为发送邮件的服务器,可以是本机的邮件代理程序sendmail,也可以是第三方的服务器。
(1)若本机有sendmail则可以直接使用sendmail发送邮件
实例化 smtplib 模块的 SMTP 对象 smtpObj 来连接到 SMTP 访问,并使用 sendmail 方法来发送信息
#localhost则是使用本机的邮件代理服务器sendmail smtpObj = smtplib.SMTP('localhost') smtpObj.sendmail(sender, receivers, message.as_string()) print("success")
(2)若本机没有sendmail,也可以尝试下下载sendmail来试试这个,配置sendmail的简单教程如下,以下安装sendmail需要在phpstudy集成环境中或者安装Apache+php的环境中。
- 下载地址:https://www.glob.com.au/sendmail/
- 解压到任意的目录下
- 以记事本的方式打开sendmail.ini
修改的内容:
1)smtp_server=XXXXXXX #第三方服务器名称,如QQ邮箱:smtp.qq.com
2)auth_username=邮箱登录账号名
3)auth_password=邮箱服务器授权码(非邮件密码)
4)force_sender=邮箱登录账号名
(注意ini文件中分号是注释的作用,可以在不需要的语句前面加上分号注释掉)
- 配置php.ini文件:sendmail_path = "XXXXXXsendmail.exe -t -i" ;#sendmail安装的位置
- 重启Apache,sendmail就配置完毕了
(3)若本机没有sendmail,则使用第三方邮件服务商,即类似QQ,163等邮箱服务器
前提是登录这些邮箱,将SMTP的服务打开。这种方式比较推荐,因为比较简单,且sendmail的代理程序其实也是在其配置文件上将账号授权码以及第三方的服务器等信息填写在配置文件中。
(4)打开SMTP服务器:以QQ邮箱为例
1)开启SMTP服务
2)验证密保
3)获取授权码
4)QQ邮箱SMTP服务器地址
三、SMTP支持三种形式的邮件
首先先了解下构造邮件的基类及其子类的结构关系:
Message
+- MIMEBase
+- MIMEMultipart
+- MIMENonMultipart
+- MIMEMessage
+- MIMEText
+- MIMEImage
+- MIMEApplication
+- MIMEAudio
Message类是email的核心类,是email对象模型中的基类。
MIMEBase作为MIME相关对象基类继承了Message,即拥有Message类的方法,可以表示任何邮件类型的对象
MIMEMultipart则继承自MIMEBase基类,以下的子类包括MIMEText,MIMEImage,MIMEMessage,MIMEApplication,MIMEAudio
1、纯文本邮件-Email正文内容
#1.1.导入支持文本的模块 from email.mime.text import MIMEText #1.2.编写文本内容以及设置文本的格式 Text_mail = "XXXXXX纯文本内容" message = MIMEText(Text_mail, ‘plain', 'utf-8')
2、HTML邮件
Html_mail = """ HTML代码 """ message = MIMEText(Html_mail , 'html', 'utf-8')
3、HTML邮件带图片
#3.1.导入支持的HTML和图片的模块 from email.mime.image import MIMEImage From email.mime.text import MIMEText #3.2.编写包含图片链接的HTML代码 Html_picture_mail = """ <p>图片</p> <p><img src="cid:图片ID"></p> """ #3.3.添加HTML的代码到正文中去,用attach方法 message.attach(MIMEText(Html_picture_mai, 'html', 'utf-8')) # 3.4.打开图片的存储路径,读取图片 file = open('图片路径', 'rb') Image = MIMEImage(file.read()) file.close() #3.5.自定义图片 ID,在 HTML图片链接地址写入该定义的ID Image .add_header('Content-ID', '<图片ID>') #3.6.添加图片附件到正文中去 message.attach(Image )
4、附件邮件
#4.1.导入支持附件的模块 from email.mime.text import MIMEText from email.mime.multipart import MIMEMultipart #4.2发送附件时需调用 MIMEMultipart类,创建 MIMEMultipart message= MIMEMultipart() #4.3附件包括附件的路径,名称,类型 attachfile = MIMEText(open('附件路径', 'rb').read(), 'base64', 'utf-8') # .*( 二进制流,不知道下载文件类型) attachfile ["Content-Type"] = 'application/octet-stream' attachfile ["Content-Disposition"] = 'attachment; filename="自定义文件名"'
#4.4.添加附件到正文中去 message.attach(attachfile)
注: 上传文件:1.文件路径 2.文件格式以及编码 3.文件扩展名 4. 文件名
1.application/octet-stream:文件扩展名。
2.Content-Disposition是MIME协议的扩展,激活文件下载对话框,文件名填充为指定的自定义文件名
5、包含文本和附件,图片的邮件
#邮件正文所需模块 from email.mime.image import MIMEImage from email.mime.text import MIMEText from email.mime.multipart import MIMEMultipart #邮件标题所需模块 from emial.header import Header #邮件对象所需模块 import smtplib #发送附件时需调用 MIMEMultipart类,创建 MIMEMultipart,MIMEMultipart可以通过attach添加多个MIME的文件 message= MIMEMultipart() #一、邮件对象 sender = ‘发送者邮箱账号’ #授权码 password = ‘xxxxxx’ receivers = ['接收者邮箱账号'] #服务器名称,如QQ邮箱smtp.qq.com server = 第三方邮件服务商服务器名 message['From'] = Header("发送者名称", 'utf-8') message['To'] = Header("接受者名称", 'utf-8') #二、构造邮件内容--标题 subject = 'The title of the email' message['Subject'] = Header(subject, 'utf-8') #二、构造邮件内容--正文 #纯文本 Text_message = “纯文本内容” message.attach(MIMEText(‘Text_message ,’plain’,’utf-8’)) #HTML内容 Html_message = “”” <p>HTML代码</p> “”” message.attach(MIMEText(‘Html_message’,’html’,’utf-8’)) #HTML包含图片内容 Picture_message = “”” <p><src = “cid:图片ID”</p> “”” message.attach(MIMEText(‘Picture_message’,’html’,’utf-8’)) file = open('图片路径', 'rb') Image = MIMEImage(file.read()) file.close() Image.add_header('Content-ID', '<图片ID>') message.attach(Image ) #添加其他附加,如word文档等 #message = MIMEMultipart()已经在开头上添加 attachfile = MMEText(open(‘word文档路径’,’rb’).read(),’base64,’utf-8’’) attachfile [“Content-Type”] = ‘application/octet-stream’ attachfile ["Content-Disposition"] = 'attachment; filename="自定义文件名"' message.attach(attachfile) #三、发送:添加发送者,接受者,服务器,发送的内容 smtpObj = smtplib.SMTP() #smtpObj.connet(server) smtpObj = smtplib.SMTP_SSL(server,465) smtpObj.login(user, password) smtpObj.sendmail(sender, receivers, message.as_string()) smtpObj.quit() print(“success”)
所有混合在一起的代码还没有验证,仅仅单个部分验证了下
四、实践
这里还是上一张发送成功的截图