python接口自动化(三十二)--Python发送邮件(常见四种邮件内容)番外篇——上(详解)
简介
本篇文章与前边没有多大关联,就是对前边有关发邮件的总结和梳理。在写脚本时,放到后台运行,想知道执行情况,会通过邮件、SMS(短信)、飞信、微信等方式通知管理员,用的最多的是邮件。在linux下,Shell脚本发送邮件告警是件很简单的事,有现成的邮
件服务软件或者调用运营商邮箱服务器。
对于Python来说,需要编写脚本调用邮件服务器来发送邮件,使用的协议是SMTP。接收邮件,使用的协议是POP3和IMAP。我想有必要说明下 ,POP3和IMAP的区别:POP3在客户端邮箱中所做的操作不会反馈到邮箱服务器,比如删除一封邮件,邮箱服务器并不
会删除。IMAP则会反馈到邮箱服务器,会做相应的操作。
Python分别提供了收发邮件的库,smtplib、poplib和imaplib。
本章主要讲解如果使用smtplib库实现发送各种形式的邮件内容。在smtplib库中,主要主要用smtplib.SMTP()类,用于连接SMTP服务器,发送邮件。
这个类有几个常用的方法:
|
方法 |
描述 |
| SMTP.set_debuglevel(level) | 设置输出debug调试信息,默认不输出 |
| SMTP.docmd(cmd[, argstring]) | 发送一个命令到SMTP服务器 |
| SMTP.connect([host[, port]]) | 连接到指定的SMTP服务器 |
| SMTP.helo([hostname]) | 使用helo指令向SMTP服务器确认你的身份 |
| SMTP.ehlo(hostname) | 使用ehlo指令像ESMTP(SMTP扩展)确认你的身份 |
| SMTP.ehlo_or_helo_if_needed() | 如果在以前的会话连接中没有提供ehlo或者helo指令,这个方法会调用ehlo()或helo() |
| SMTP.has_extn(name) | 判断指定名称是否在SMTP服务器上 |
| SMTP.verify(address) | 判断邮件地址是否在SMTP服务器上 |
| SMTP.starttls([keyfile[, certfile]]) | 使SMTP连接运行在TLS模式,所有的SMTP指令都会被加密 |
| SMTP.login(user, password) | 登录SMTP服务器 |
| SMTP.sendmail(from_addr, to_addrs, msg, mail_options=[], rcpt_options=[]) |
发送邮件 from_addr:邮件发件人 to_addrs:邮件收件人 msg:发送消息 |
| SMTP.quit() | 关闭SMTP会话 |
| SMTP.close() | 关闭SMTP服务器连接 |
看下官方给的示例:

我们根据示例给自己发一个邮件测试下:
我这里测试使用本地的SMTP服务器,也就是要装一个支持SMTP协议的服务,比如sendmail、postfix等。
CentOS安装sendmail:yum install sendmail
>>> import smtplib
>>> s = smtplib.SMTP("localhost")
>>> tolist = ["xxx@qq.com", "xxx@163.com"]
>>> msg = '''\
... From: Me@my.org
... Subject: test
... This is a test '''
>>> s.sendmail("me@my.org", tolist, msg)
{}
进入腾讯和网易收件人邮箱,就能看到刚发的测试邮件,一般都被邮箱服务器过滤成垃圾邮件,所以收件箱没有,你要去垃圾箱看看。

可以看到,多个收件人可以放到一个列表中进行群发。msg对象里From表示发件人,Subject是邮件标题,换行后输入的是邮件内容。
1.1 Python发送邮件并抄送
#!/usr/bin/python
# -*- coding: utf- -*-
import smtplib
def sendMail(body):
smtp_server = 'smtp.163.com'
from_mail = 'hongge@163.com'
mail_pass = 'xxx'
to_mail = ['xxx@qq.com', 'xxx@163.com']
cc_mail = ['hongge@xxx.com']
from_name = 'monitor'
subject = u'监控'.encode('gbk') # 以gbk编码发送,一般邮件客户端都能识别
# msg = '''\
# From: %s <%s>
# To: %s
# Subject: %s
# %s''' %(from_name, from_mail, to_mail_str, subject, body) # 这种方式必须将邮件头信息靠左,也就是每行开头不能用空格,否则报SMTP 554
mail = [
"From: %s <%s>" % (from_name, from_mail),
"To: %s" % ','.join(to_mail), # 转成字符串,以逗号分隔元素
"Subject: %s" % subject,
"Cc: %s" % ','.join(cc_mail),
"",
body
]
msg = '\n'.join(mail) # 这种方式先将头信息放到列表中,然后用join拼接,并以换行符分隔元素,结果就是和上面注释一样了
try:
s = smtplib.SMTP()
s.connect(smtp_server, '')
s.login(from_mail, mail_pass)
s.sendmail(from_mail, to_mail+cc_mail, msg)
s.quit()
except smtplib.SMTPException as e:
print "Error: %s" %e
if __name__ == "__main__":
sendMail("This is a test!")

s.sendmail(from_mail, to_mail+cc_mail, msg) 在这里注意下,收件人和抄送人为什么放一起发送呢?其实无论是收件人还是抄送人,它们收到的邮件都是一样的,SMTP都是认为收件人这样一封一封的发出。所以实际上并没有抄送这个概念,只是在邮件头加了抄送人的信息罢了!另外,如果不需要抄送人,直接把上面cc的信息去掉即可。
另外以上代码发送的邮件会出现主题中文乱码:

解决方案:三行代码即可,修改成红色框代码即可

1.2 Python发送邮件带附件
由于SMTP.sendmail()方法不支持添加附件,所以可以使用email模块来满足需求。email模块是一个构造邮件和解析邮件的模块。
先看下如何用email库构造一个简单的邮件:
message = Message()
message['Subject'] = '邮件主题'
message['From'] = from_mail
message['To'] = to_mail
message['Cc'] = cc_mail
message.set_payload('邮件内容')
基本的格式就是这样的!
继续回到主题,发送邮件带附件:
# coding=utf-
#.先设置编码,utf-8可支持中英文,如上,一般放在第一行 #.注释:包括记录创建时间,创建人,项目名称。
'''
Created on --
@author: 北京-宏哥
Project:学习和使用邮箱发带有附件邮件
'''
#.导入模块
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.header import Header
from email import encoders
from email.mime.base import MIMEBase def send_mail(file_new):
#-----------.跟发件相关的参数------
smtpserver = 'smtp.mxhichina.com' #发件服务器
port = #端口
username = 'noreply@cxx.cn' #发件箱用户名
password = 'xx@@123' #发件箱密码
sender = 'noreply@cxx.cn' #发件人邮箱
receiver = ['hongge@cedex.cn','1918991791@qq.com'] #收件人邮箱
# ----------.编辑邮件的内容------
#读文件内容
f = open(file_new, 'rb')
mail_body = f.read()
f.close()
# 邮件正文是MIMEText
body = MIMEText(mail_body, 'html', 'utf-8')
# 邮件对象
msg = MIMEMultipart()
msg['Subject'] = Header("自动化测试报告", 'utf-8').encode()#主题
msg['From'] = Header(u'测试机 <%s>'%sender) #发件人
msg['To'] = Header(u'测试负责人 <%s>'%receiver) #收件人
msg['To'] = ';'.join(receiver)
msg.attach(body)
# # MIMEBase表示附件的对象
att = MIMEText(mail_body, "base64", "utf-8")
att["Content-Type"] = "application/octet-stream"
# filename是显示附件名字
att["Content-Disposition"] = 'attachment; filename="test_report.html"'
msg.attach(att)
# ----------.发送邮件------
try:
smtp = smtplib.SMTP()
smtp.connect(smtpserver) # 连服务器
smtp.login(sender, password)
except:
smtp = smtplib.SMTP_SSL(smtpserver, port)
smtp.login(sender, password) # 登录
smtp.sendmail(sender, receiver, msg.as_string()) # 发送
smtp.quit() if __name__ == "__main__":
#本地文件的路径
att_path= r'E:\pythontest\text.txt'
send_mail(att_path)

1.3 Python发送HTML邮件
# coding=utf-
#.先设置编码,utf-8可支持中英文,如上,一般放在第一行 #.注释:包括记录创建时间,创建人,项目名称。
'''
Created on --
@author: 北京-宏哥
Project:学习和使用邮箱发HTML邮件
'''
#.导入模块
#"-*- coding: utf-8 -*-"
import smtplib
from email.mime.text import MIMEText mail_user="XXX@163.com"
mail_password="******q1125"
mailto_list=["1918991791<1918991791@qq.com>","2014816656@qq.com"]
mail_host="smtp.163.com"
mail_postfix="163.com" def sendmail(to_list,sub,content):
me="北京-宏哥"+"<"+mail_user+"@"+mail_postfix+">"
msg=MIMEText("<a href='https://www.cnblogs.com/du-hong'><font color='red'>北京-宏哥</font></a>","html","utf-8")
msg['Subject']=sub
msg['From']=me
msg['To']=",".join(to_list)
try:
server=smtplib.SMTP()
server.connect(mail_host)
server.login(mail_user,mail_password)
server.sendmail(me,to_list,msg.as_string())
server.close()
return True
except Exception as e:
print (str(e))
return False
if sendmail(mailto_list,"标题:发送的是html格式","<a href='https://www.cnblogs.com/du-hong'>北京-宏哥</a>"):
print ("done!")
else:
print ("falsed!")

1.4 Python发送图片邮件
# coding=utf-
#.先设置编码,utf-8可支持中英文,如上,一般放在第一行 #.注释:包括记录创建时间,创建人,项目名称。
'''
Created on --
@author: 北京-宏哥
Project:学习和使用1邮箱发HTML邮件
'''
#.导入模块
#"-*- coding: utf-8 -*-"
import smtplib
from email.mime.text import MIMEText mail_user="@@@@@163.com"
mail_password="@@@@"
mailto_list=["1918991791<1918991791@qq.com>","2014816656@qq.com"]
mail_host="smtp.163.com"
mail_postfix="163.com" def sendmail(to_list,sub,content):
me="北京-宏哥"+"<"+mail_user+"@"+mail_postfix+">"
msg=MIMEText('<html><body><img hidefocus="true" class="index-logo-src" src="//www.baidu.com/img/bd_logo1.png" width="270" height="129" usemap="#mp"></body></html>', 'html', 'utf-8')
msg['Subject']=sub
msg['From']=me
msg['To']=",".join(to_list)
try:
server=smtplib.SMTP()
server.connect(mail_host)
server.login(mail_user,mail_password)
server.sendmail(me,to_list,msg.as_string())
server.close()
return True
except Exception as e:
print (str(e))
return False
if sendmail(mailto_list,"标题:发送的是HTML格式","<a href='https://www.cnblogs.com/du-hong'>北京-宏哥</a>"):
print ("done!")
else:
print ("falsed!")

上面发邮件的几种常见的发邮件方法基本满足日常需求了。
小结
1、linux环境下提示AttributeError: module 'smtplib' has no attribute 'SMTP',Windows环境运行代码也报如下错误:

2、原因当然不是模块的问题,检查了一下拼写也没有出问题,最后在这个帖子(链接)的启发下发现,发现自己的文件命名为email.py,和模块中的函数有冲突,改名之后Linux环境邮件正常发送。
python接口自动化(三十二)--Python发送邮件(常见四种邮件内容)番外篇——上(详解)的更多相关文章
- 《手把手教你》系列技巧篇(三十一)-java+ selenium自动化测试- Actions的相关操作-番外篇(详解教程)
1.简介 上一篇中,宏哥说的宏哥在最后提到网站的反爬虫机制,那么宏哥在自己本地做一个网页,没有那个反爬虫的机制,谷歌浏览器是不是就可以验证成功了,宏哥就想验证一下自己想法,于是写了这一篇文章,另外也是 ...
- Python发送邮件(常见四种邮件内容)
Python发送邮件(常见四种邮件内容) 转载 2017年03月03日 17:17:04 转自:http://lizhenliang.blog.51cto.com/7876557/1875330 ...
- 《手把手教你》系列技巧篇(三十六)-java+ selenium自动化测试-单选和多选按钮操作-番外篇(详解教程)
1.简介 前边几篇文章是宏哥自己在本地弄了一个单选和多选的demo,然后又找了网上相关联的例子给小伙伴或童鞋们演示了一下如何自动化测试,这一篇宏哥在网上找了一个问卷调查,给小伙伴或童鞋们来演示一下.上 ...
- 《手把手教你》系列基础篇(八十)-java+ selenium自动化测试-框架设计基础-TestNG依赖测试-番外篇(详解教程)
1.简介 经过前边几篇知识点的介绍,今天宏哥就在实际测试中应用一下前边所学的依赖测试.这一篇主要介绍在TestNG中一个类中有多个测试方法的时候,多个测试方法的执行顺序或者依赖关系的问题.如果不用de ...
- 【转】【Python】Python发送邮件(常见四种邮件内容)
在写脚本时,放到后台运行,想知道执行情况,会通过邮件.SMS(短信).飞信.微信等方式通知管理员,用的最多的是邮件.在linux下,Shell脚本发送邮件告警是件很简单的事,有现成的邮件服务软件或者调 ...
- python接口自动化(十二)--https请求(SSL)(详解)
简介 本来最新的requests库V2.13.0是支持https请求的,但是一般写脚本时候,我们会用抓包工具fiddler,这时候会 报:requests.exceptions.SSLError: [ ...
- Appium+python自动化(十二)- Android UIAutomator终极定位凶“胸”器(七)(超详解)
简介 乍眼一看,小伙伴们觉得这部分其实在异性兄弟那里就做过介绍和分享了,其实不然,上次介绍和分享的大哥是uiautomatorviewer,是一款定位工具.今天介绍的是一个java库,提供执行自动化测 ...
- Jmeter(四十二) - 从入门到精通进阶篇 - Jmeter配置文件的刨根问底 -番外篇(详解教程)
1.简介 为什么宏哥要对Jmeter的配置文件进行一下讲解了,因为有的童鞋或者小伙伴在测试中遇到一些需要修改配置文件的问题不是很清楚也不是很懂,就算修改了也是模模糊糊的.更有甚者觉得那是禁地神圣不可轻 ...
- python接口自动化(十)--post请求四种传送正文方式(详解)
简介 post请求我在python接口自动化(八)--发送post请求的接口(详解)已经讲过一部分了,主要是发送一些较长的数据,还有就是数据比较安全等.我们要知道post请求四种传送正文方式首先需要先 ...
随机推荐
- php 将一个二维数组中两个相同的value 相同 指定值相加
array(3) { [0]=> array(7) { ["mlid"]=> int(1) ["num"]=> int(1) ["c ...
- 零元学Expression Blend 4 - Chapter 46 三分钟快速充电-设定Margin的小撇步
原文:零元学Expression Blend 4 - Chapter 46 三分钟快速充电-设定Margin的小撇步 如果需要经常的使用某一项工具,总会希望能够更快速的使用各项设定达到效果 今天要介绍 ...
- Qt 开发WEB Services客户端代码(使用gSoap)
1. 首先下载gSoap开发包 http://sourceforge.net/projects/gsoap2 目录包含 wsdl2h.exe( 由wsdl生成接口头文件C/C++格式的头文件 ) ...
- Rainyday.js – Rendering Raindrops with JavaScript
Posted · Category:GPL License,Tools 直击现场 The idea behind Rainyday.js is to create a JavaScript libra ...
- WCF研究-前篇
前篇 1.从SOA说起 2.什么是WCF 3.WCF通信模型 4.Endpoint与ABC以及元数据 1.SOA (Service Oriented Architecture) Ø 一种组件架 ...
- C语言实现常用查找算法——二分查找
#include<stdio.h> void insert_sort(int a[],int n); int binary_search(int a[],int x,int n); voi ...
- 深入浅出Ajax
原文(我的GitHub):https://github.com/liangfengbo/frontend-ability/issues/1 学习大纲 理解Ajax的工作原理 Ajax核心-XMLHtt ...
- jmeter安装与部署
1.JDK组件安装 jmeter是一款java开发的测试软件,需要JDK运行环境支持,因此在安装jmeter前需要安装调试好jdk运行环境.jmeter3.2需要1.8以上版本jdk才可以正常运行.首 ...
- 【python3两小时快速入门】入门笔记03:简单爬虫+多线程爬虫
作用,之间将目标网页保存金本地 1.爬虫代码修改自网络,目前运行平稳,博主需要的是精准爬取,数据量并不大,暂未加多线程. 2.分割策略是通过查询条件进行分类,循环启动多条线程. 1.单线程简单爬虫(第 ...
- laravel中的构造函数依赖注入理解
laravel中的自动依赖注入是非常强大的,刚开始会疑惑为什么只要在构造函数中传入一个强制类型的变量(就是参数有类型限制)过去就行了? 通过查看源码即查阅资料发现其实这其中有一个php技术,就是反射技 ...