- 本书赞誉
- 前言
- 第一部分 基础篇
- 第1章 系统基础信息模块详解
- 第2章 业务服务监控详解
- 第3章 定制业务质量报表详解
- 第4章 Python 与系统安全
- 第二部分 高级篇
- 第5章 系统批量运维管理器 pexpect 详解
- 第6章 系统批量运维管理器 paramiko 详解
- 第7章 系统批量运维管理器Fabric详解
- 第8章 从零开发一个轻量级 WebServer
- 第9章 集中化管理平台 Ansible 详解
- 第10章 集中化管理平台 Saltstack 详解
- 第11章 统一网络控制器 Func 详解
- 第12章 Python 大数据应用详解
- 第三部分 案例篇
- 第13章 从零开始打造 B/S 自动化运维平台
- 第14章 打造 Linux 系统安全审计功能
- 第15章 构建分布式质量监控平台
- 第16章 构建桌面版 C/S 自动化运维平台
2.3 发送电子邮件模块 smtplib
电子邮件是最流行的互联网应用之一。在系统管理领域,我们常常使用邮件来发送告警信息、业务质量报表等,方便运维人员第一时间了解业务的服务状态。本节通过Python的smtplib模块来实现邮件的发送功能,模拟一个smtp客户端,通过与smtp服务器交互来实现邮件发送的功能,这可以理解成Foxmail的发邮件功能,在第一次使用之前我们需要配置smtp主机地址、邮箱账号及密码等信息,Python 2.3或更高版本默认自带smtplib模块,无需额外安装。下面详细进行介绍。
2.3.1 smtplib模块的常用类与方法
SMTP类定义:smtplib.SMTP([host[,port[,local_hostname[,timeout]]]]),作为SMTP的构造函数,功能是与smtp服务器建立连接,在连接成功后,就可以向服务器发送相关请求,比如登录、校验、发送、退出等。host参数为远程smtp主机地址,比如smtp.163.com;port为连接端口,默认为25;local_hostname的作用是在本地主机的FQDN(完整的域名)发送HELO/EHLO(标识用户身份)指令,timeout为连接或尝试在多少秒超时。SMTP类具有如下方法:
SMTP.connect([host[,port]])方法,连接远程smtp主机方法,host为远程主机地址,port为远程主机smtp端口,默认25,也可以直接使用host:port形式来表示,例如:SMTP.connect(“smtp.163.com”,“25”)。
SMTP.login(user,password)方法,远程smtp主机的校验方法,参数为用户名与密码,如SMTP.login(“python_2014@163.com”,“sdjkg358”)。
SMTP.sendmail(from_addr,to_addrs,msg[,mail_options,rcpt_options])方法,实现邮件的发送功能,参数依次为是发件人、收件人、邮件内容,例如:SMTP.sendmail(“python_2014@163.com”,“demo@domail.com”,body),其中body内容定义如下:
"""From: python_2014@163.com To: demo@domail.com Subject: test mail test mail body"""
SMTP.starttls([keyfile[,certfile]])方法,启用TLS(安全传输)模式,所有SMTP指令都将加密传输,例如使用gmail的smtp服务时需要启动此项才能正常发送邮件,如SMTP.starttls。
SMTP.quit方法,断开smtp服务器的连接。
下面通过一个简单示例帮助大家理解,目的是使用gmail向QQ邮箱发送测试邮件,代码如下:
#!/usr/bin/python import smtplib import string HOST = "smtp.gmail.com" #定义smtp主机 SUBJECT = "Test email from Python" #定义邮件主题 TO = "testmail@qq.com" #定义邮件收件人 FROM = "mymail@gmail.com" #定义邮件发件人 text = "Python rules them all!" #邮件内容 BODY = string.join(( #组装sendmail方法的邮件主体内容,各段以"\r\n"进行分隔 "From: %s" % FROM, "To: %s" % TO, "Subject: %s" % SUBJECT , "", text ), "\r\n") server = smtplib.SMTP #创建一个SMTP对象 server.connect(HOST,"25") #通过connect方法连接smtp主机 server.starttls #启动安全传输模式 server.login("mymail@gmail.com","mypassword") #邮箱账号登录校验 server.sendmail(FROM, [TO], BODY) #邮件发送 server.quit #断开smtp连接
我们将收到一封这样的邮件,如图2-5所示。
图2-5 收到的邮件
2.3.2 定制个性化的邮件格式方法
通过邮件传输简单的文本已经无法满足我们的需求,比如我们时常会定制业务质量报表,在邮件主体中会包含HTML、图像、声音以及附件格式等,MIME(Multipurpose Internet Mail Extensions,多用途互联网邮件扩展)作为一种新的扩展邮件格式很好地补充了这一点,更多MIME知识见 http://zh.wikipedia.org/wiki/MIME 。下面介绍几个Python中常用的MIME实现类:
email.mime.multipart.MIMEMultipart([_subtype[,boundary[,_subparts[,_params]]]]),作用是生成包含多个部分的邮件体的MIME对象,参数_subtype指定要添加到"Content-type:multipart/subtype"报头的可选的三种子类型,分别为mixed、related、alternative,默认值为mixed。定义mixed实现构建一个带附件的邮件体;定义related实现构建内嵌资源的邮件体;定义alternative则实现构建纯文本与超文本共存的邮件体。
email.mime.audio.MIMEAudio(_audiodata[,_subtype[,_encoder[,**_params]]]),创建包含音频数据的邮件体,_audiodata包含原始二进制音频数据的字节字符串。
email.mime.image.MIMEImage(_imagedata[,_subtype[,_encoder[,**_params]]]),创建包含图片数据的邮件体,_imagedata是包含原始图片数据的字节字符串。
email.mime.text.MIMEText(_text[,_subtype[,_charset]]),创建包含文本数据的邮件体,_text是包含消息负载的字符串,_subtype指定文本类型,支持plain(默认值)或html类型的字符串。
2.3.3 定制常用邮件格式示例详解
前面两小节介绍了Python的smtplib及email模块的常用方法,那么两者在邮件定制到发送过程中是如何分工的?我们可以将email.mime理解成smtplib模块邮件内容主体的扩展,从原先默认只支持纯文本格式扩展到HTML,同时支持附件、音频、图像等格式,smtplib只负责邮件的投递即可。下面介绍在日常运营工作中邮件应用的几个示例。
示例1 :实现HTML格式的数据报表邮件。
纯文本的邮件内容已经不能满足我们多样化的需求,本示例通过引入email.mime的MIMEText类来实现支持HTML格式的邮件,支持所有HTML元素,包含表格、图片、动画、CSS样式、表单等。本示例使用HTML的表格定制美观的业务流量报表,实现代码如下:
【/home/test/smtplib/simple2.py】
#coding: utf-8 import smtplib from email.mime.text import MIMEText #导入MIMEText类 HOST = "smtp.gmail.com" #定义smtp主机 SUBJECT = u"官网流量数据报表" #定义邮件主题 TO = "testmail@qq.com" #定义邮件收件人 FROM = "mymail@gmail.com" #定义邮件发件人 msg = MIMEText(""" #创建一个MIMEText对象,分别指定HTML内容、类型(文本或html)、字 #符编码 <table width="800" border="0" cellspacing="0" cellpadding="4"> <tr> <td bgcolor="#CECFAD" height="20"duokan-code-cn">:14px">*官网数据 <a href="monitor.domain.com">更多>></a></td> </tr> <tr> <td bgcolor="#EFEBDE" height="100"duokan-code-cn">:13px"> 1)日访问量:<font color=red>152433</font> 访问次数:23651 页面浏览量:45123 点击数:545122 数据流量:504Mb<br> 2)状态码信息<br>  ; ;500:105 404:3264 503:214<br> 3)访客浏览器信息<br>  ; ;IE:50% firefox:10% chrome:30% other:10%<br> 4)页面信息<br>  ; ;/index.php 42153<br>  ; ;/view.php 21451<br>  ; ;/login.php 5112<br> </td> </tr> </table>""","html","utf-8") msg['Subject'] = SUBJECT #邮件主题 msg['From']=FROM #邮件发件人,邮件头部可见 msg['To']=TO #邮件收件人,邮件头部可见 try: server = smtplib.SMTP #创建一个SMTP对象 server.connect(HOST,"25") #通过connect方法连接smtp主机 server.starttls #启动安全传输模式 server.login("mymail@gmail.com","mypassword") #邮箱账号登录校验 server.sendmail(FROM, TO, msg.as_string) #邮件发送 server.quit #断开smtp连接 print "邮件发送成功!" except Exception, e: print "失败:"+str(e)
代码运行结果如图2-6所示,我们将业务日志分析结果定期推送给管理员,以方便管理员了解业务的服务情况。
图2-6 示例1运行结果
示例2 :实现图文格式的服务器性能报表邮件。
示例1通过MIMEText类来实现HTML格式的邮件,当要求包含图片数据的邮件内容时,需要引用MIMEImage类,若邮件主体由多个MIME对象组成,则同时需引用MIMEMultipart类来进行组装。本示例通过MIMEText与MIMEImage类的组合来实现图文格式的服务器性能报表邮件的定制,实现代码如下:
【/home/test/smtplib/simple3.py】
#coding: utf-8 import smtplib from email.mime.multipart import MIMEMultipart #导入MIMEMultipart类 from email.mime.text import MIMEText #导入MIMEText类 from email.mime.image import MIMEImage #导入MIMEImage类 HOST = "smtp.gmail.com" #定义smtp主机 SUBJECT = u"业务性能数据报表" #定义邮件主题 TO = "testmail@qq.com" #定义邮件收件人 FROM = "mymail@gmail.com" #定义邮件发件人 def addimg(src,imgid): #添加图片函数,参数1:图片路径,参数2:图片id fp = open(src, 'rb') #打开文件 msgImage = MIMEImage(fp.read) #创建MIMEImage对象,读取图片内容并作为参数 fp.close #关闭文件 msgImage.add_header('Content-ID', imgid) #指定图片文件的Content-ID,<img> #标签src用到 return msgImage #返回msgImage对象 msg = MIMEMultipart('related') #创建MIMEMultipart对象,采用related定义内嵌资源 #的邮件体 msgtext = MIMEText(""" #创建一个MIMEText对象,HTML元素包括表格<table>及图片<img> <table width="600" border="0" cellspacing="0" cellpadding="4"> <tr bgcolor="#CECFAD" height="20"duokan-code-cn">:14px"> <td colspan=2>*官网性能数据 <a href="monitor.domain.com">更多>></a></td> </tr> <tr bgcolor="#EFEBDE" height="100"duokan-code-cn">:13px"> <td> <img src="cid:io"></td><td> <img src="cid:key_hit"></td> </tr> <tr bgcolor="#EFEBDE" height="100"duokan-code-cn">:13px"> <td> <img src="cid:men"></td><td> <img src="cid:swap"></td> </tr> </table>""","html","utf-8") #<img>标签的src属性是通过Content-ID来引用的 msg.attach(msgtext) #MIMEMultipart对象附加MIMEText的内容 msg.attach(addimg("img/bytes_io.png","io")) #使用MIMEMultipart对象附加MIMEImage #的内容 msg.attach(addimg("img/myisam_key_hit.png","key_hit")) msg.attach(addimg("img/os_mem.png","men")) msg.attach(addimg("img/os_swap.png","swap")) msg['Subject'] = SUBJECT #邮件主题 msg['From']=FROM #邮件发件人,邮件头部可见 msg['To']=TO #邮件收件人,邮件头部可见 try: server = smtplib.SMTP #创建一个SMTP对象 server.connect(HOST,"25") #通过connect方法连接smtp主机 server.starttls #启动安全传输模式 server.login("mymail@gmail.com","mypassword") #邮箱账号登录校验 server.sendmail(FROM, TO, msg.as_string) #邮件发送 server.quit #断开smtp连接 print "邮件发送成功!" except Exception, e: print "失败:"+str(e)
代码运行结果如图2-7所示,我们将业务服务器性能数据定期推送给管理员,以方便管理员了解业务的服务情况。
图2-7 示例2运行结果
示例3 :实现带附件格式的业务服务质量周报邮件。
本示例通过MIMEText与MIMEImage类的组合,实现图文邮件格式。另通过MIMEText类再定义Content-Disposition属性来实现带附件的邮件。我们可以利用这些丰富的特性来定制周报邮件,如业务服务质量周报。实现代码如下:
【/home/test/smtplib/simple4.py】
#coding: utf-8 import smtplib from email.mime.multipart import MIMEMultipart #导入MIMEMultipart类 from email.mime.text import MIMEText #导入MIMEText类 from email.mime.image import MIMEImage #导入MIMEImage类 HOST = "smtp.gmail.com" #定义smtp主机 SUBJECT = u"官网业务服务质量周报" #定义邮件主题 TO = "testmail@qq.com" #定义邮件接收人 FROM = "mymail@gmail.com" #定义邮件发件人 def addimg(src,imgid): #添加图片函数,参数1:图片路径,参数2:图片id fp = open(src, 'rb') #打开文件 msgImage = MIMEImage(fp.read) #创建MIMEImage对象,读取图片内容作为参数 fp.close #关闭文件 msgImage.add_header('Content-ID', imgid) #指定图片文件的Content-ID,<img> #标签src用到 return msgImage #返回msgImage对象 msg = MIMEMultipart('related') #创建MIMEMultipart对象,采用related定义内嵌资源 #的邮件体 #创建一个MIMEText对象,HTML元素包括文字与图片<img> msgtext = MIMEText("<font color=red>官网业务周平均延时图表:<br><img src=\"cid:weekly\" border=\"1\"><br>详细内容见附件。</font>","html","utf-8") msg.attach(msgtext) #MIMEMultipart对象附加MIMEText的内容 msg.attach(addimg("img/weekly.png","weekly")) #使用MIMEMultipart对象附加 # MIMEImage的内容 #创建一个MIMEText对象,附加week_report.xlsx文档 attach = MIMEText(open("doc/week_report.xlsx", "rb").read, "base64", "utf-8") attach["Content-Type"] = "application/octet-stream" #指定文件格式类型 #指定Content-Disposition值为attachment则出现下载保存对话框,保存的默认文件名使用 #filename指定 #由于qqmail使用gb18030页面编码,为保证中文文件名不出现乱码,对文件名进行编码转换 attach["Content-Disposition"] = "attachment; filename=\"业务服务质量周报(12周).xlsx\"".decode("utf-8").encode("gb18030") msg.attach(attach) #MIMEMultipart对象附加MIMEText附件内容 msg['Subject'] = SUBJECT #邮件主题 msg['From']=FROM #邮件发件人,邮件头部可见 msg['To']=TO #邮件收件人,邮件头部可见 try: server = smtplib.SMTP #创建一个SMTP对象 server.connect(HOST,"25") #通过connect方法连接smtp主机 server.starttls #启动安全传输模式 server.login("mymail@gmail.com","mypassword") #邮箱账号登录校验 server.sendmail(FROM, TO, msg.as_string) #邮件发送 server.quit #断开smtp连接 print "邮件发送成功!" except Exception, e: print "失败:"+str(e)
代码运行结果如图2-8所示,实现了发送业务服务质量周报的邮件功能。
图2-8 示例3的运行结果
参考提示
2.3.1节smtplib模块的常用类与方法内容参考https://docs.python.org/2.7/library/smtplib.html。
2.3.2节email.mime常用类定义内容参考https://docs.python.org/2.7/library/email.mime.html。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论