取自华章出版社所著《自动化运维: 技术与最佳实践》里的第2章, 第2.3节, 作者为(美)Neil , 更多章节内容能通过访问云栖社区“华章计算机”公众号予以查看, 本节书摘是这样。
2.3 发送电子邮件模块
关于电子邮件, 它身为极流行的互联网应用当中的一个。于系统管理范畴之内, 我们时常借助邮件去发送告警信息、业务质量报表之类, 以此便利运维人员能够在第一时间知晓业务的服务况态。在本节, 借助模块达成邮件的发送功能, 去模拟一个smtp客户端, 凭借与smtp服务器展开交互以实现邮件发送的功能, 这能够被理解成发邮件功能, 在首次使用之前, 我们要配置smtp主机地址、邮箱账号以及密码等信息, 2.3或更高版本默认自带该模块, 无需进行额外安装。下面详细进行介绍。
2.3.1 模块的常用类与方法
.SMTP(), 被界定为SMTP的构造函数, 其具备的功能是跟smtp服务器构建连接, 当连接达成成功状态后, 便能够朝着服务器递送相关请求, 诸如登录、校验、发送、退出等情况。host参数所指的是远程smtp主机地址, 举例来讲;port是连接采用的端口, 默认设定为25;它起到的作用是于本地主机的FQDN(完整的域名)发送HELO/EHLO(用于标识用户身份)指令, 针对连接或者尝试设定了在多少秒会超时。SMTP类拥有如下这些方法:
用于连接远程smtp主机的SMTP.()方法 , host是指其所连接的远程主机地址 , port是远程主机的smtp端口 , 默认值为25 , 其也能够直接采用host:port这种形式来进行表示 , 比如说: SMTP.("""25")。
具有校验远程smtp主机功能的SMTP.login(user, )方法, 其参数是用户名以及密码, 呈现形式为SMTP.login(“”, “”)。
SMTP.(, , msg
, ,
一种方式, 达成邮件的发送作用, 参数依次存有发件人、有收件人、含邮件内容, 举例来说: SMTP.((“ ”), (“ ”), body), 当中body内容界定如下:
"""From: python_2014@163.com To: demo@domail.com Subject: test mail test mail body"""(SMTP.)的方法, 会启用TLS(安全传输)模式, 在此模式下, 所有SMTP指令都会进行加密传输。例如, 当使用gmail的smtp服务时, 就需要启动此项才能够正常发送邮件, 就如同(SMTP.)一样。
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.3.2 定制个性化的邮件格式方法
用于通过邮件传输简单文本的方式, 已然没法契合我们的需求, 举例而言, 我们常常会去定制业务质量报表, 在邮件的主体部分, 会涵盖HTML、图像、声音以及附件格式等内容, MIME(Mail, 多用途互联网邮件扩展)作为一种全新的扩展邮件格式, 对这方面进行了良好的补充, 更多关于MIME的知识可见, 下面将介绍几个常用的MIME实现类:
email.mime..(
,
,
,
它的作用是, 生成那种包含多个部分的关于邮件体的MIME对象, 其参数用于指定, 要添加到“-type:/"报头的, 可选择的三种子类型, 这三种子类型分别为mixed、、, 其默认值是mixed。对mixed进行定义, 目的是实现构建一个带有附件的邮件体;对进行定义, 目的是实现构建内嵌有资源的邮件体;对进行定义, 目的是实现构建那种纯文本与超文本共同存在的邮件体。
email.mime.audio. (
,
,
, **
创建邮件体, 该邮件体包含音频数据, 此音频数据是包含原始二进制音频数据的字节字符串。
email.mime.image.(
,
,
, **
创建邮件体, 该邮件体包含图片数据, 此图片数据是原始图片数据的字节字符串。
email.mime.text. (_text
,
,
经由指定文本类型, 支持plain(默认值)或html类型的字符串, 来创建包含文本数据的邮件体:_text这个是包含消息负载的字符串 , 包含文本数据的邮件体被创建。
2.3.3 定制常用邮件格式示例详解
介绍了前面两小节所涉及的、email模块的常用方法, 那么在邮件定制直至发送的这个过程当中, 两者究竟是怎样进行分工的呢? 我们能够把email.mime理解为模块邮件内容主体的一种扩展, 它是从原本默认仅仅支持纯文本格式, 扩展到支持HTML格式, 并且同时支持附件、音频、图像等等格式, 只需负责邮件的投递就行。在下文中会介绍在日常运营工作里邮件应用的几个示例。
示例1:实现HTML格式的数据报表邮件。
仅为纯文本形式的邮件内容, 已然无法契合我们丰富多样的需求, 此示例藉由引入email.mime这个类, 达成对支持HTML格式邮件的支持, 能够支持全部的HTML元素,涵盖表格、图片、动画、CSS样式、表单等等, 此示例运用HTML的表格去定制美观的业务流量报表, 实现代码如下:
【/home/test//.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)、字 #符编码 [PROTECTED_756d0f4af91c6566f73c9ad28e09a8f2]""","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:实现图文格式的服务器性能报表邮件。
依据类达成HTML格式邮件的实现, 在想要嵌入含图片相关资料时, 应该引用类, 要是邮件主体由多个MIME对象构成, 那么同时也要引用类去完成组装。此示例借助与类的结合来制定图文格式性能报表邮件, 代码这般如此:
【/home/test//.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, #标签src用到 return msgImage #返回msgImage对象 msg = MIMEMultipart('related') #创建MIMEMultipart对象,采用related定义内嵌资源 #的邮件体 msgtext = MIMEText(""" #创建一个MIMEText对象,HTML元素包括表格[PROTECTED_8981f05ce9c8bb90bf6dde2fbad3e252]""","html","utf-8") #标签的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 所示, 能使其了解业务的服务情况, 方便管理员知晓。
示例3:实现带附件格式的业务服务质量周报邮件。
本示例借由跟类的组合, 达成图文邮件格式。另外借助类再度界定-属性来达成带附件的邮件。我们能够运用这些多样的特性去定制周报邮件, 像业务服务质量周报這樣的。使其代码展示如下:
【/home/test//.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主机 SUBJECT = u"官网业务服务质量周报" #定义邮件主题 TO = #定义邮件接收人 FROM = #定义邮件发件人 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, #标签src用到 return msgImage #返回msgImage对象 msg = MIMEMultipart('related') #创建MIMEMultipart对象,采用related定义内嵌资源 #的邮件体 #创建一个MIMEText对象,HTML元素包括文字与图片 msgtext = MIMEText("官网业务周平均延时图表: 详细内容见附件。","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所示, 可以看到已达成了发送业务服务质量周报的邮件相关功能。