测试开发【提测平台】分享11-Python实现邮件发送的两种方法实践
微信搜索【大奇测试开】,关注这个坚持分享测试开发干货的家伙。
按照开发安排,本篇本应该是关于提测页面的搜索和显示实现,怕相似内容疲劳,这期改下内容顺序,将邮件服务的相关的提前,在之前的产品需求和原型中有一个功能点,就是需要在提测人进行提测,以及测试完成的操作的时候要按照一定的模版发送邮件通知,那我们就研究一下Python flask 后台服务如何实现发送邮件的知识点,最后形成一个邮件工具类,以便在实现提测功能流程中使用。
本篇内容思维导读

内置邮件模块 smtplib
从某度搜索关于python如何发送邮件,给到结果最多的就是 smtplib,资料参差不齐,抑或内容太陈旧,这里通过实践整理总结如下:
首先 了解基本使用
官方 [注解1] 的语法以及教程参考 [注解2]:
# 导入包,python环境默认自有,无需而外安装
import smtplib
from smtplib import SMTP # 通过给定参数链接服务对象
smtplib.SMTP(host='', port=0, local_hostname=None, [timeout, ]source_address=None)
# 或需要SSL连接
smtplib.SMTP_SSL(host='', port=0, local_hostname=None, keyfile=None, certfile=None, [timeout, ]context=None, source_address=None) # 支持with方式,否则一般上边的操作需要手动关闭
with smtplib.SMTP("domain.org") as smtp:
# 配置发送地址和内容等
建立服务对象重要参数说明:
host: SMTP 服务器主机。你可以指定主机的ip地址或者域名;
port: 需要指定 SMTP 服务使用的端口号,一般情况下 SMTP 端口号为25;
Python SMTP 对象使用 sendmail 方法发送邮件,语法如下:
SMTP.sendmail(from_addr, to_addrs, msg, mail_options=(), rcpt_options=())
其中重要参数说明:
from_addr: 邮件发送者地址。
to_addrs: 字符串列表,邮件发送地址。
msg: 发送消息
其次 准备一个可用的邮件发送服务
可以本地,公司邮箱服务,或者是第三方服务,我这里准备的一个测试邮件服务是“企业微信邮箱”,如果你在编码测试过程中没有可用的,可以私信我发我信息,给你添加个我注册测试用的企业微信邮箱,也可以直接使用自己的如网易和QQ邮箱,只不过需要提前在设置开启对应的权限设置,具体配置可以在网上搜索下。用账号密码登录企业邮箱后在设置中找到如图信息,在测试代码中会使用到。

最后 一个完整的例子
直接通过给定HTML样式,实现模版发送,内容文字+链接,这里需要特别注意的是测试“微信企业邮箱”链接需要SSL,所以需要使用 SMTP_SSL 创建链接,而非往上很多例子使用SMTP进行创建,对应代码(源代码在github上)和执行测试内容如下:

查看我自己的邮箱是否真的收到了邮件,可以看到功能正常,上边代码中有一处需要主要是发件人和服务登录人应为为同一个否则会报SMTP 501错误。

但这里有个问题,在邮箱列表里的发件人信息和详细内容里的邮件人信息展示异常,如图:列表显示空白,邮件详细没能正确显示邮箱等。

经过资料查询,需要依赖包的一个工具类进行格式化,分别是email.utils 中的 parseaddr, formataddr,经过优化后代码如图红色标注:

增加优化逻辑后再发送一个测试邮件,看看结果,列表和详细都正常显示了。

本来调研的例子还准备写如何添加附件和图片等,看了麻烦,另外从上边的体验来看smtplib坑不少,然后在解决的问题的过程中发现有文章推荐 yagmail 这个python邮件服务包,感觉眼前一亮,有更好的方法就要学会使用,因为我们处在了一个好的信息共享时代~
简单易用邮件模块 yagmail
yagmail 使用
yagmail 是个外部包,使用前需要安装
# 可能需要外网访问
pip3 install yagmail
# 或从github安装
pip3 install -e git+https://github.com/kootenpv/yagmail#egg=yagmail
从实践的例子来看,发送邮件变得如此简单,不需要多说,直接上代码:
def demo_yagmail():
# 设置收件人(不需要再设置发件人)
receivers = ['zyueqi@qq.com', 'daqigroup@mrzcode.com']
# 邮件主题
subject = 'Yagmail测试主题'
# 内容,可以单独定义,然后组成一个内容体
body = 'Body描述'
html = '<a href="https://github.com/mrzcode/TestProjectManagement">项目代码点我!</a>' # 附件文件绝对路径, 或者 通过open打开直接给io流文件
path_file = os.path.dirname(os.path.abspath(__file__))+'/source/result.txt'
attachments =[path_file] # 初始化服务对象直接根据参数给定,更多参考SMTP()内部
server = yagmail.SMTP(host='smtp.exmail.qq.com', port=465, user='daqi@mrzcode.com', password='Test@2021')
# 发送内容,设置接受人等信息,更多参考SMTP.send()内部
server.send(to=receivers,
subject=subject,
contents=[body, html],
attachments=attachments) server.close()
print("邮件发送的如此简单!") if __name__ == "__main__":
demo_yagmail()
看看发送结果,正常收到,各项均没有异常,完美~ 更多参数说明参考官方 [注释3] 或者在idea 开发工具点跳到源码。

是不是Pyhon 发送邮件变得如此轻松愉快了~,上述的调研实践代码均提交到git项目代码库了,可以前去查看位置:/demoCode/emailDemo.py
邮件工具类编写
调研和实践完了上述“Python 如何实现邮件发送服务” 内容,最终目的是编写个工具类和一些方法来供后续的提测流程使用
1. configs/config.py 添加邮件服务的常量
# config.py
MAIL_HOST = "发送服务的地址"
MAIL_PORT = 25
MAIL_USER = "发送服务邮箱账号"
MAIL_PASSWORD = "发送服务邮箱密码"
2. 创建/utils/emialUtils.py 实现的参数化方法,这里对于模版因为是否也定义在其中,后边实际开发后再优化
#!/usr/bin/python
# -*- coding: UTF-8 -*-
import yagmail
import traceback
from configs import config
'''
receivers 收件人,字符数组['邮件地址']
subject 邮件主题, 字符串
contents 邮件内容,自定义 字符数组
attachments 附件默认为空
'''
def sendEmail(receivers, subject,contents, attachments=[]): try:
# 初始化服务对象直接根据参数给定,更多参考SMTP()内部
server = yagmail.SMTP(host=config.MAIL_HOST, port=config.MAIL_PORT,
user=config.MAIL_USER, password=config.MAIL_PASSWORD)
# 发送内容,设置接受人等信息,更多参考SMTP.send()内部
server.send(to=receivers,
subject=subject,
contents=contents,
attachments=attachments)
server.close() except Exception:
print('traceback.format_exc(): {}'.format(traceback.format_exc()))
return False # 无任何异常表示发送成功
return True
3. 调用测试,工具类直接编写变量调用方法进行测试,查看邮件发送是否OK
if __name__ == "__main__":
# 测试发送服务
receivers = ['zyueqi@qq.com', 'daqigroup@mrzcode.com']
subject = 'DaQi工具类测试'
body = '简单的问题内容体'
sendEmail(receivers,subject,[body])
以上本篇内容所有知识点,后边文章会继续进行提测平台功能开发,另外马上也到国庆了,不知道依然不敢太放肆走的你,有什么安排,如果宅家里,学学习,动动手也是不错的选择,也提前透漏下,后边文章更新会上一些新方向,比如性能测试,比如接口自动化测试等等,敬请期待下吧,祝大家2021国庆快乐!
问题集锦
1. smtplib腾讯邮箱链接和收发邮件人显示问题
使用SMTP_SSL()创建链接而非SMTP(),显示问题通过工具类方法parseaddr, formataddr优化发送和接收邮件地址格式
2. 邮箱服务常见的两个错误提示
账号或密码错误 535, b'Error: authentication failed, system busy')
发送人和登录不一致 501, b'mail from address must be same as authorization user)
【代码更新】
地址:https://github.com/mrzcode/TestProjectManagement
TAG:TPMShare11
【注解&参考】
[注解1]:https://docs.python.org/zh-cn/3.8/library/smtplib.html#
[注解2]:https://www.runoob.com/python/python-email.html
[注解3]:https://github.com/kootenpv/yagmail
坚持原创,坚持实践,坚持干货,如果你觉得有用,请点击推荐,也欢迎关注我博客园和微信公众号。
测试开发【提测平台】分享11-Python实现邮件发送的两种方法实践的更多相关文章
- python执行linux命令的两种方法
python执行linux命令有两种方法: 在此以Linux常用的ls命令为例: 方法一:使用os模块 1 2 3 shell# python >> import os >> ...
- python学习--python 连接SQLServer数据库(两种方法)
1. python 学习.安装教程参照: http://www.runoob.com/python/python-tutorial.html 2. 集成开发环境 JetBrains PyCharm C ...
- 「python」: arp脚本的两种方法
「python」: arp脚本的两种方法 第一种是使用arping工具: #!/usr/bin/env python import subprocess import sys import re de ...
- python中执行shell的两种方法总结
这篇文章主要介绍了python中执行shell的两种方法,有两种方法可以在Python中执行SHELL程序,方法一是使用Python的commands包,方法二则是使用subprocess包,这两个包 ...
- Python随机生成验证码的两种方法
Python随机生成验证码的方法有很多,今天给大家列举两种,大家也可以在这个基础上进行改造,设计出适合自己的验证码方法方法一:利用range Python随机生成验证码的方法有很多,今天给大家列举两种 ...
- iOS开发小技巧--边接受数据边写入文件的两种方法
一.NSFileHanle 使用注意点:在往文件写入数据时,必须创建一个空的文件 指定文件写入的方式 -- 覆盖还是追加 最后记得关闭 <1>代码是在大文件传输的练习中截取的.写入数据之前 ...
- python语言实现阶乘的两种方法---递归和迭代
阶乘的递归实现,代码如下: def factorial(n): if n==1: return 1 else: return n*factorial(n-1) number = int(input(& ...
- python中字符串格式化的两种方法
知识点汇总;1-字符串格式化输出方法一: % 1-print('名字是 %s,年龄是%s' % (name ,age)) 2- %s ---字符串-----相当于执行了str() 3- (name , ...
- python进行md5加密的两种方法
本文转自:https://www.cnblogs.com/zknublx/p/6212590.html 一. 使用md5包 import md5 src = 'this is a md5 test.' ...
随机推荐
- NOIP 模拟 7 寿司
题解 题目 这道题考试的时候直接打暴力,结果暴力连样例都过不了,最后放上去一个玄学东西,骗了 \(5pts\). 正解: 此题中我们可以看到原序列是一个环,所以我们要把它拆成一条链,那么我们需要暴力枚 ...
- 针对Hbuilderx内置终端无法输入问题,总结了三种方法供大家参考
下图,是内置终端无法输入的现象(本人使用的第三种方案,解决了该问题) 第一种解决方案,也是网上推荐最多的方案: 打开Hbuilder安装路径下插件文件夹中的main.js文件:HBuilderX\pl ...
- 【C++】 四种强制类型转换(static_cast 与 dynamic_cast 的区别!)
强制类型转换 1. static_cast 2. dynamic_cast 3. const_cast 4. reinterpret_cast 5. 为什么要需要四种类型转换? 1. static_c ...
- 深入浅出Mybatis系列(一)---Mybatis简介
1.什么是MyBatis? MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且 ...
- Servlet学习之复习
Servlet的注册与运行(Servlet程序通常需要存储在<web应用程序目录>\WEB-INF\classes\目录中) 1.注册Servlet:在web.xml文件中,一个<s ...
- windows安装trojan记录
1.trojan 客户端安装教程 https://v2raytech.com/trojan-clients/ 2.chrome安装插件(crx文件)教程 https://www.jianshu.com ...
- C++类和对象笔记
笔记参考C++视频课程 黑马C++ C++ 面向对象的三大特性:封装.继承.多态 目录 目录 目录 一.封装 1.1 封装的意义-属性和行为 1.2 struct和class的区别 1.3 成员属性设 ...
- 微信公众号授权回调用户信息,获取openid
1.--------------------用户授权登录并获取code 授权登录方式有两个,一种为静默授权登录(scope=snsapi_base),一种为非静默授权登录(scope=snsapi_u ...
- nginx 开启,关闭,重启
2021-08-191. 启动 # 判断配置文件是否正确 cd /usr/local/nginx/sbin ./nginx -t # 启动 cd usr/local/nginx/sbin ./ngin ...
- MFC中L, _T(),TEXT,_TEXT区别以及含义
字符串前面加L表示该字符串是Unicode字符串. _T是一个宏,如果项目使用了Unicode字符集(定义了UNICODE宏),则自动在字符串前面加上L,否则字符串不变.因此,Visual C++里边 ...