前言     

最近有小伙伴提醒,说还有邮件服务没有发文章,后面自己检查发现确实自己漏了,所以今天给大家补上。

首先web自动化可以自动生成报告,但是在实际工作中,最好能够将报告发送给指定的相关人员,那么省的我们手动进行发送,所以邮件发送也是自动化需要完成的一部分。如果此部分要完成自动化的话,肯定有同学一开始会认为也是通过访问邮箱地址,然后元素定位,最后上传附件报告发送,这种思维肯定可以,但是不稳定且极其复杂,所以我们会通过其内置的服务进行完成。

邮件的基础知识

1、邮件发送的基本过程与概念

一封邮件的基本内容通常分为三部分:邮件头部;邮件体;邮件附件

邮件服务器 :类似于现实生活中的邮局,它主要负责接收用户投递过来的邮件,并把邮件投递到邮件接收者的电子邮箱中。
from:wzmtest1313@163.com           ----发件人
to:wzmtest1313@163.com             ----收件人
subject:Crm系统执行测试报告     ----主题
body: 执行总共用例数?通过用例数?失败用例数?   -----内容体

2、邮件传输协议
SMTP协议:全称为 Simple Mail Transfer Protocol,简单邮件传输协议。它定义了邮件客户端软件和SMTP邮件服务器之间,以及两台SMTP邮件服务器之间的通信规则

POP3协议:全称为 Post Office Protocol,邮局协议。它定义了邮件客户端软件和POP3邮件服务器的通信规则

IMAP协议:全称为 Internet Message Access Protocol,Internet消息访问协议,它是对POP3协议的一种扩展,也是定义了邮件客户端软件和IMAP邮件服务器的通信规则

SMTPLib模块

Python的smtplib提供了一种很方便的途径发送电子邮件。它对smtp协议进行了简单的封装。Python对SMTP支持有smtplib和email两个模块,email负责构造邮件,smtplib负责发送邮件。

与邮件服务器进行建立会话连接

import smtplibfrom email.mime.text import MIMEText#声明邮件的发送者、接收者sender = 'wzmtest1313@163.com'receivers = 'wzmtest1313@163.com'# 三个参数:第一个为文本内容,第二个 plain 设置文本格式,第三个 utf-8 设置编码message = MIMEText('详细内容如下', 'plain', 'utf-8')message['From'] = sendermessage['To'] = receiversmessage['Subject']="Crm系统测试报告"get_smtp=smtplib.SMTP(host="smtp.163.com")get_smtp.login("wzmtest1313@163.com","wzmtest1313")get_smtp.sendmail(sender,receivers,message.as_string())

上面是一个最简单的邮件发送,下面来详细说明下内容:

a.如果想要能够将邮件发送成功,第一必须先将163发送者的邮件服务器的smtp服务启动

进入163邮箱,点击设置

qq的设置也是一样的,进入qq邮箱,点击设置

b.get_smtp.login传入的两个参数是用户名和密码,而此处的密码并不是你登陆邮箱的密码是刚才说的授权码

c.get_smtp.sendmail传入的三个参数,第一个参数是发送者,第二个是接收者,第三个是邮件对象,邮件对象可以通过email下的MIMEText完成文本对象的创建,此时创建的对象只由邮件头、邮件体两部分所构成,无法通过该对象创建邮件附件。

d.MIMEText同样传入的三个参数,第一个参数是邮件体内容,第二个参数表示的是邮件内容以什么样的文本类型发送,第三个参数表示的是编码格式。

e.获取到的message对象,From、To、Subject是发送者、接收者、标题等,可以通过字典的形式写入到message对象,实际也就是邮件头的设定。

注意:如果邮件的内容过于简单,内容过于敏感,服务器有可能将邮件拒绝甚至提示错误代码。

邮件附件

前面我们知道可以通过MIMEText模块完成邮件头和邮件体的构建,但是邮件附件无法构建,那么需要使用MIMEMultipart模块完成。

MIME(Multipurpose Internet Mail Extensions)多用途网络邮件扩展类型,可被称为Media type或Content type,它设定某种类型的文件当被浏览器打开的时候需要用什么样的应用程序,多用于HTTP通信和设定文档类型例如HTML。

MIME组成:(type/subtype; parameter)) 主类型+子类型+参数(可选)也可称为信息头+段头,这种称为更接近于“邮件”的概念。

常见MIME类型:

application: 某种二进制附件,对于没有subtype的情况,默认是application/octet-stream

text: 文本,理论上可读,对于没有subtype的情况,默认是text/plain

image: 图像

audio: 音频

video: 视频

multipart: 多部分文档文件(复合文档文件)

是不是有点跟我们讲过的Content-Type类似呢,不要类似了,其实就是相同的东西啦~~相信大家也懂MIMEText和MIMEMultipart两者区别了。

那么构建一个带有附件的邮件如何实现呢?

from email.mime.text import MIMEText from email.mime.multipart import MIMEMultipart#创建的是一个邮件文本def create_text(self,message):        message_object=MIMEText(message,_charset="utf-8")        return message_object#创建邮件附件def create_attach(self,reportname,reportpath):        with open(reportpath,mode="rb") as fp:            attach=MIMEText(fp.read(),_subtype="base64",_charset="utf-8")            attach["Content-Type"]="application/octet-stream"            attach.add_header('Content-Disposition', 'attachment', filename='%s'%reportname)            return attachdef create_mail(self,subject,message,reportname,reportpath):        mail=MIMEMultipart()        mail["Subject"] = subject        mail["From"] = self.from_addr()        mail["To"] = self.show_to_addr()        mail["Cc"]=self.get_cc        mail["Bcc"]=self.get_bcc        mail.attach(self.create_text(message))        mail.attach(self.create_attach(reportname,reportpath))        return mail

上述代码进行了封装,提取了数据,全部都是以参数的形式进行存在。

首先create_text表示的是构建邮件体,create_attach表示的是构建邮件附件,create_email表示的是构建一封完整的邮件,由邮件头、邮件体、邮件附件所构成;

邮件体还是通过MIMEText模块完成,这个在前面介绍过了。

邮件附件是生成的测试报告,测试报告文本类型是html类型,所以必须声明Content-Type类型为文件二进制流类型,且需要声明文件所在位置,那么就必须通过Content-Disposition进行确定。

在构建一封完整的邮件中,其中Subject、From、To这个前面讲过,Cc表示的是抄送,Bcc表示的是密送。

注意:1.在构建附件的时候,本来其文件位置可以通过下面代码完成,

attach["Content-Disposition"]='attachment;filename=%s'%reportname

但是上述代码只能够针对报个名中非中文的情况才能够实现,如果报告名中存在中文则上传的文件会被重新编码,从而不是原有的格式文件。

2. 此处的to_address需要的是字符串信息不能够是列表对象,与send_mail方法中传入参数to_address的值类型不同哦。

处理发件人和收件人的显示问题

在发送邮件后,肯定有同学会发现,自己给自己发邮件的话,显示的信息是我,下面我们就处理显示邮件的格式

如何将我修改成wzmtest1313即邮件的账户格式:wzmtest1313

def to_addr(self):            get_to_addr=self.get_mail_config["to_addr"]            get_list=get_to_addr.split(",")            if len(self.get_cc)!=0:                get_list+=self.get_cc.split(",")            if len(self.get_bcc)!=0:                get_list+=self.get_bcc.split(",")            return get_listdef from_addr(self):            get_from_addr=self.get_mail_config["from_addr"]            return get_from_addr.split("@")[0]+""%get_from_addrdef show_to_addr(self):       return ",".join([value.split("@")[0]+""%value for value in self.get_mail_config["to_addr"].split(",")])

上述三个方法,第一个方法to_addr是当收件人如果是多个的话,获取到的是一个字符串,需要将字符串转换成一个列表对象,因为send_mail方法中传入的是列表对象,而邮件头中的是字符串格式,所以最后又使用show_to_addr进行将我类型的邮件进行处理,显示格式与发件人格式一致。

最后封装完整的邮件代码如下:

先将固定的配置信息写入到ini文件中,

然后定义一个模块读ini文件

最后发送邮件的代码:

#-*- coding:utf-8 -*-##-------------------------------------------------------------------------#ProjectName:       Python2020#FileName:          Send_Mail.py#Author:            mutou#Date:              2020/6/26 21:52#Description:实现报告邮件的发送#--------------------------------------------------------------------------import smtplibfrom email.mime.text import MIMEText  #主要处理邮件正文信息from email.mime.multipart import MIMEMultipartfrom CRMProject.Public_Object.Read_Ini import ReadInifrom CRMProject.GETP_ATH import GETPATHfrom CRMProject.Public_Object.Crm_Log import CrmLog,LOG_PATHimport sys#固定常量,mail的配置文件所在位置path=GETPATH+"\Public_Object\Mail.ini"class  SendMail(object):    #实现创建对象的时候则完成邮件的用户的信息初始化    def  __init__(self):        self.log_mail=CrmLog()        self.log_mail.get_handle(LOG_PATH+"\mail.log")        __read=ReadIni()        self.get_mail_config=__read.read_ini(path,"mail_config")        self.get_cc = self.get_mail_config["cc"]        self.get_bcc=self.get_mail_config["bcc"]    #需要处理to_addr,传递给send_mail中的参数    def to_addr(self):        try:            get_to_addr=self.get_mail_config["to_addr"]            get_list=get_to_addr.split(",")            if len(self.get_cc)!=0:                get_list+=self.get_cc.split(",")            if len(self.get_bcc)!=0:                get_list+=self.get_bcc.split(",")            return get_list        except:            self.log_mail.log_object.error("收件人信息处理失败")    #将发件人的信息进行处理  wzmtest1313    def from_addr(self):        try:            get_from_addr=self.get_mail_config["from_addr"]            return get_from_addr.split("@")[0]+""%get_from_addr        except:            self.log_mail.log_object.error("发件人信息处理失败")    def show_to_addr(self):       return ",".join([value.split("@")[0]+""%value for value in self.get_mail_config["to_addr"].split(",")])    #声明一个完整邮件的方法;通过MIMEMultipart完成附件和文本邮件的构成    #邮件除了收件人、发件人以外还有:抄送者、密送者    def create_mail(self,subject,message,reportname,reportpath):        mail=MIMEMultipart()        mail["Subject"] = subject        mail["From"] = self.from_addr()        #此处的to_address需要的是字符串信息不能够是列表对象        mail["To"] = self.show_to_addr()        #添加上抄送和密送者,后期可自动选择;此处Ini中存在一个坑:会将所有的文件读取出来的键名全部默认为小写        mail["Cc"]=self.get_cc        mail["Bcc"]=self.get_bcc        mail.attach(self.create_text(message))        mail.attach(self.create_attach(reportname,reportpath))        self.log_mail.log_object.info("邮件创建成功")        return mail    #创建邮件附件    def create_attach(self,reportname,reportpath):        #使用MIMEText完成一个文件的读取操作        with open(reportpath,mode="rb") as fp:            #_subtype:表示指定文本类型的子类型;默认是文本类型:text/html   text/xml   text/json   application/www--xxxx-form  application/octet-stream            #对应的content-type类型;类似处理12306验证码的方式,将文件以二进制流的形式进行写入指定的位置            attach=MIMEText(fp.read(),_subtype="base64",_charset="utf-8")            #为了能够上传任意格式文件的类型,则将其文件的父类型定义为二进制流类型            attach["Content-Type"]="application/octet-stream"            #attach.add_header("Content-Type","appliction/octet-stream")            #attach["Content-Type"]="text/html"            #文件是否需要指定位置;如果此处的reportname的值中带有中文的话,那么下面的这种方式可能上传的附件会失败会改变其编码格式,导致其产生bin的结构文件            #attach["Content-Disposition"]='attachment;filename=%s'%reportname            #下面此种方式可以解决文件名中带有中文的情况,因为add_header中第三个传入的参数filename其默认值就是utf-8的编码格式,所以可以实现中文的文件名上传            attach.add_header('Content-Disposition', 'attachment', filename='%s'%reportname)            return attach    #封装一封邮件:那么在python中必须要使用email模块    #创建的是一个邮件文本    def create_text(self,message):        message_object=MIMEText(message,_charset="utf-8")        return message_object    #与邮件服务器进行建立会话连接    def send_mail(self,subject,message,reportname,reportpath):        try:            get_smtp=smtplib.SMTP(host=self.get_mail_config["mail_server"])  #创建smtp的会话连接对象            #实现登陆操作:login中传入的用户名、密码是实现smtp服务授权的用户名、密码,不是前台登陆的用户名密码            get_smtp.login(self.get_mail_config["mail_user"],self.get_mail_config["mail_password"])            #登陆成功发送邮件:声明发件者、收件者、收件信息; msg词过于简单,或者过于敏感,邮件服务器都会将其进行屏蔽            #如果发送出现554状态时,考虑其发送的信息以及发送的邮件的完整性问题(声明邮件头的发件人、收件人等信息)            get_smtp.sendmail(self.get_mail_config["from_addr"],self.to_addr(),self.create_mail(subject,message,reportname,reportpath).as_string())            self.log_mail.log_object.info("邮件发送成功")        except:            self.log_mail.log_object.error(sys.exc_info())

无法用php smtp发送邮件. 您的服务器可能没有配置用此方法_补充:Web自动化邮件发送...相关推荐

  1. 无法用php smtp发送邮件. 您的服务器可能没有配置用此方法_Web自动化测试:邮件发送测试报告...

    在我们运行完整个项目后,已经生成了 测试报告,一般自动化会在本地或者公司服务器上运行,那如何获取自动化测试的运行结果呢,此时就需要把测试结果以邮件的形式发送到邮箱,这样就可以在测试完成的第一时间知道测 ...

  2. ibmx3650服务器bios阵列配置安装系统,IBMx3650服务器BIOS阵列配置安装系统(方法二+PXE网启安装法)ok.doc...

    IBMx3650服务器BIOS阵列配置安装系统(方法二PXE网启安装法)ok PXE网启安装法 这一次我采用了WEB BIOS来配置阵列,用光盘引导盘配置阵列虽然简单,但是如果想随心所欲的配置的,这一 ...

  3. 我的世界服务器修改完配置怎么使用方法,我的世界服务器地址设置教程

    我的世界是一款高度自由化的游戏,该游戏有多人模式,不过有些不熟悉网络的玩家对于服务器地址设置并不是很了解,以下是小编给大家带来的我的世界服务器地址设置教程. 我的世界服务器地址教学 第一步.在我的世界 ...

  4. java smtp收信_求一个简单java编写的邮件收发程序,邮件发送程序为smtpsend,邮件接收程序为popreceive。急需,感谢。...

    展开全部 import javax.mail.*; import javax.mail.internet.*; import java.util.*; import java.io.*; public ...

  5. box300注册服务器,华为Box300配置Touch接入方法讲解

    今天重庆劲浪科技来说说使用Touch对终端进行配置前需要先将Touch接入终端,接入方式包括TOUCH口连接.交换机网口连接和Wi-Fi连接. TOUCH口连接 将Touch接入终端的TOUCH口,如 ...

  6. php邮件发送tp,在Thinkphp3.2 中使用PHPMailer 发送邮件

    phpmailer发送邮件是php开发者首选的一个邮件发送插件了,下面我来介绍怎么集成phpmailer到thinkphp框架了,有需要了解的朋友可参考. phpmailer发送邮件功能很强大,今天真 ...

  7. 在 Laravel 5.1 中使用SMTP驱动实现邮件发送(含附件和图片)详细教程

    0. 步骤一:使我们的QQ邮箱能够发送邮件 这里怎么说能够发送邮件呢?其实我们的邮箱都是可以发送邮件的,但是要实现在我们的网站中发送邮件,那就要设置一下我们的QQ邮箱了,因为此时我们的网站现在是作为一 ...

  8. PHP邮件发送:PHP使用SMTP服务器发送邮件

    1.下载好phpmailer 后只需要几个重要的文件即可,其余的都可以删除 class.phpmailer.php class.smtp.php class.pos3.php(我未用到这个接受文件) ...

  9. 阿里云服务器使用SMTP发送邮件

    在阿里云上买了一个轻量应用服务器,之所以选择这个是因为该类型的服务器可以在购买时配置开发环境,而且价格比较便宜.将网站在本地搭好上传到云上时,发现原本可以运行的邮件发送功能失效了.折腾了将近一天之后, ...

最新文章

  1. 广告等第三方应用嵌入到web页面方案 之 使用js片段
  2. 源码|并发一枝花之CopyOnWriteArrayList
  3. android开源系统brvah,Android Jetpack之通用Adapter(Databinding+BRVAH)
  4. 数学建模3 论文排版注意点
  5. 图片添加图片水印和文字水印
  6. linux在什么环境运行,Linux环境变量是什么
  7. 教你在Linux操作系统中如何创建函数库
  8. 有用的linux命令笔记
  9. 中国医学史(第三章 中医药理论体系的初步形成)
  10. github镜像网站_Jenkins把GitHub项目做成Docker镜像
  11. 【HTML5】嵌入另一张HTML文档、通过插件嵌入内容、嵌入数字表现形式
  12. 棋类游戏-五子棋小游戏
  13. python 开发窗体应用程序_Python如何编写窗体程序
  14. c语言访问mysql,C语言访问mysql数据库
  15. JVM:这次一定要搞懂字节码
  16. 2019最新Android常用开源库总结(持续更新,建议收藏)
  17. 【招银网络科技java面试题目面试经验】-看准网
  18. 【RASA】TED Policy:Dialogue Transformers
  19. 解决:运行pytest时,报错:'TestCaseFunction' object has no attribute 'get_marker'
  20. 科技云报道:广交“朋友圈”的信服云,让金融云有了新选择

热门文章

  1. sysbench数据库性能压测详解
  2. 字典含有重复的key不覆盖_EXCEL字典实例应用一(求首次和末次)
  3. php 获取数据库函数吗,如何正确理解PHP获取显示数据库数据函数
  4. python 如何快速判断列表是否相同_python如何判断两个list是否相等
  5. SpringBoot 多种定时任务实现方式
  6. scheduled只执行一次,有个定时任务突然不执行了?
  7. Oracle数据库中IN参数个数超过1000的问题
  8. Android开发笔记(三十三)文本文件和图片文件的读写
  9. 用Python快速找到出现次数最多的数据
  10. linux的FTP服务器搭建及FTP服务器的入侵和防御