《Python自动化运维:技术与最佳实践》一2.3 发送电子邮件模块smtplib

简介:

本节书摘来自华章出版社《Python自动化运维:技术与最佳实践》一书中的第2章,第2.3节,作者 (美)Neil Bergman ,更多章节内容可以访问云栖社区“华章计算机”公众号查看

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所示。

image

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" style="font-size:14px">*官网数据  <a href="monitor.domain.com">更多>></a></td>
      </tr>
      <tr>
        <td bgcolor="#EFEBDE" height="100" style="font-size:13px">
        1)日访问量:<font color=red>152433</font>  访问次数:23651 页面浏览量:45123 点击数:545122  数据流量:504Mb<br>
        2)状态码信息<br>
        &nbsp;&nbsp;500:105  404:3264  503:214<br>
        3)访客浏览器信息<br>
        &nbsp;&nbsp;IE:50%  firefox:10% chrome:30% other:10%<br>
        4)页面信息<br>
        &nbsp;&nbsp;/index.php 42153<br>
        &nbsp;&nbsp;/view.php 21451<br>
        &nbsp;&nbsp;/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所示,我们将业务日志分析结果定期推送给管理员,以方便管理员了解业务的服务情况。

image

示例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" style="font-size:14px">
        <td colspan=2>*官网性能数据  <a href="monitor.domain.com">更多>></a></td>
      </tr>
      <tr bgcolor="#EFEBDE" height="100" style="font-size:13px">
        <td>
         <img src="cid:io"></td><td>
         <img src="cid:key_hit"></td>
      </tr>
      <tr bgcolor="#EFEBDE" height="100" style="font-size: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所示,我们将业务服务器性能数据定期推送给管理员,以方便管理员了解业务的服务情况。

image

示例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所示,实现了发送业务服务质量周报的邮件功能。

image

相关文章
|
21天前
|
数据采集 存储 API
在信息时代,Python爬虫用于自动化网络数据采集,提高效率。
【7月更文挑战第5天】在信息时代,Python爬虫用于自动化网络数据采集,提高效率。基本概念包括发送HTTP请求、解析HTML、存储数据及异常处理。常用库有requests(发送请求)和BeautifulSoup(解析HTML)。基本流程:导入库,发送GET请求,解析网页提取数据,存储结果,并处理异常。应用案例涉及抓取新闻、商品信息等。
51 2
|
15天前
|
数据采集 存储 API
Python虚拟环境数据共享技术解析:最佳实践与常见误区
本文探讨了Python爬虫开发中如何在虚拟环境中管理数据,提倡使用共享目录、数据库和API进行数据共享。通过创建虚拟环境、安装依赖并提供一个使用代理IP爬取微博数据的示例,阐述了如何配置代理、解析网页及保存数据到共享路径。强调了避免硬编码路径、忽视依赖管理和数据安全性的误区。
36 11
Python虚拟环境数据共享技术解析:最佳实践与常见误区
|
20小时前
|
SQL 安全 数据库
构建安全的Python Web应用是一项持续的努力,需要开发者时刻保持警惕,并采用最佳实践来预防各种安全威胁
【7月更文挑战第26天】构建安全的Python Web应用是一项持续的努力,需要开发者时刻保持警惕,并采用最佳实践来预防各种安全威胁
|
17天前
|
运维 数据安全/隐私保护 Python
Python基于telnetlib模块实现交换机全面巡检自动化运维项目
Python基于telnetlib模块实现交换机全面巡检自动化运维项目
48 14
|
12天前
|
监控 jenkins 持续交付
Python进行自动化
【7月更文挑战第9天】 Python在自动化部署中发挥关键作用,提供如Fabric、Ansible、Docker SDK和Kubernetes Client等工具。自动化部署提高效率、减少错误,确保部署一致性和可控性。例如,Fabric库简化了远程服务器的部署任务,如在多台服务器上执行Git拉取和Docker容器启动。持续集成/部署(CI/CD)结合Jenkins和Fabric,实现代码变更自动构建、测试和部署。监控和持续改进是确保应用稳定性和质量的关键,通过定期回顾、度量分析以及有效监控系统来优化流程。
18 1
|
16天前
|
数据采集 存储 监控
python 10个自动化脚本
【7月更文挑战第10天】
37 3
|
16天前
DC/AC电源模块在工业自动化中扮演着重要角色
DC/AC电源模块在工业自动化中扮演着重要角色
DC/AC电源模块在工业自动化中扮演着重要角色
|
20天前
|
数据采集 数据处理 数据安全/隐私保护
Python的自动化脚本可以完成哪些任务?
【7月更文挑战第7天】Python的自动化脚本可以完成哪些任务?
24 3
|
24天前
|
测试技术 API 持续交付
【Python自动化测试】文章探讨了Python在测试领域的关键作用,分为三部分
【7月更文挑战第2天】【Python自动化测试】文章探讨了Python在测试领域的关键作用,分为三部分:1) 自动化测试的重要性与Python的易用性、库支持、跨平台和社区优势;2) Unittest作为标准测试框架的基础用法,及Pytest的灵活性与强大功能;3) 实践中包括Selenium的Web UI测试、Requests的API测试,强调测试隔离、持续集成等最佳实践。Python助力高效稳定的软件测试。
27 2
|
5天前
|
前端开发 JavaScript 数据处理
深入Python Web开发:模板引擎的力量与最佳实践
【7月更文挑战第21天】Python Web开发中,模板引擎如Jinja2促进MVC架构的View层,分离后端数据与前端展示,提升开发效率和代码复用。选择适合的模板引擎,利用其数据注入、模板继承等特性,保持模板简洁,注重安全性,是最佳实践。例如,Jinja2允许在HTML中嵌入变量并处理循环,简化渲染过程。
14 0