python-使用163邮箱发送邮件

目的:将自动化测试的最新测试报告通过163邮箱发送邮件通知用户

网络上有很多相关资料,记录过程和调试过程中遇到的问题

目录

一、邮件传输协议基础

二、发送文本类型邮件

三、发送HTML和附件格式邮件

四、发送带图片的邮件(部分代码)

五、优化:读取测试报告作为邮件内容发送

六、发送邮件功能封装

七、邮箱设置

八、注意事项

参考网站


一、邮件传输协议基础

常见的电子邮件传输协议有:

POP3:接收全部邮件,是client/server协议

SMTP:Simple Mail Transfer Protocol  简单邮件传输协议,是一组用于由源地址到目的地址传送邮件的规则,由它来控制信件的中转方式,是一种邮件发送协议

IMAP4:仅接收邮件标题,仅接收离线邮件的标题,与pop3协议相比较节省了空间

MIME:由参数控制邮件内容的文件类型:如文本或HTML、附件等

PGP:邮件加密

python的smtplib提供了一种很方便的途径发送电子邮件,它对SMTP协议进行了简单的封装

二、发送文本类型邮件

#!/usr/bin/python3

import smtplib
from email.mime.text import MIMEText
from email.header import Header

# 第三方 SMTP 服务
mail_host = "smtp.163.com"  # 设置服务器
mail_user = "xxx@163.com"  # 邮箱用户名
mail_pass = "xxx"  # 是邮箱授权口令,不是邮箱登录密码

sender = "xxx@163.com"    # 发送邮件邮箱
receivers = ["xxx1@qq.com","xxx2@qq.com"]  # 接收邮件,可添加多个邮箱

message = MIMEText('Python 邮件发送测试...', 'plain', 'utf-8')    # 发送邮件的内容、类型
message['From'] = "xxx@163.com"    # 邮件发信人,也可以自己定义,建议和发件人一致
message['To'] = "xxx@qq.com"       # 邮件收件人,可自己定义,建议和收件人一致

subject = 'Python SMTP 邮件测试'
message['Subject'] = Header(subject, 'utf-8')

try:
    smtpObj = smtplib.SMTP()
    smtpObj.connect(mail_host, 25)  # SMTP端口号25,pop3端口号110
    smtpObj.login(mail_user, mail_pass)
    smtpObj.sendmail(sender, receivers, message.as_string())
    print("邮件发送成功")
except smtplib.SMTPException:
    print("Error: 无法发送邮件")

运行程序,控制台输出发送成功,邮箱收到邮件

三、发送HTML和附件格式邮件

和文本类型相比,修改邮件内容和类型就可以

#!/usr/bin/python3

import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.header import Header
import os

"""
发带附件的邮件
需要先创建MIMEMultipart()实例,然后构件附件,最后利用smtplib.smtp发送
@wei
2023-11-08
"""

# 第三方 SMTP 服务
mail_host = "smtp.163.com"  # 设置服务器
mail_user = "xxx@163.com"  # 用户名
mail_pass = "xxx"  # 口令

sender = "xxx@163.com"
receivers = ["xxx@qq.com"]  # 接收邮件,可设置为你的QQ邮箱或者其他邮箱

#创建一个带附件的实例
message = MIMEMultipart()
message['From'] = "xxx@163.com"
message['To'] = "xxx@qq.com"
subject = 'Python SMTP 邮件测试'
message['Subject'] = Header(subject, 'utf-8')


mail_msg = """
<p>Python 邮件发送测试...</p>
<p><a href="http://www.runoob.com">这是一个链接</a></p>
"""
# 邮件正文内容
message.attach(MIMEText(mail_msg, 'html', 'utf-8'))

# 获取文件的目录
cur_path = os.path.dirname(os.path.realpath(__file__))
report_file = os.path.join(cur_path, "report\\2023-10-18result.html")

# 构造附件1,传送目录下的report.html文件
att1 = MIMEText(open(report_file, 'rb').read(), 'base64', 'utf-8')
att1["Content-Type"] = 'application/octet-stream'
# 这里的filename可以任意写,写什么名字,邮件中显示什么名字
att1["Content-Disposition"] = 'attachment; filename="2023-10-18result.html"'
message.attach(att1)

# 构造附件2,传送目录下的report.html文件
att2 = MIMEText(open(report_file, 'rb').read(), 'base64', 'utf-8')
att2["Content-Type"] = 'application/octet-stream'
# 这里的filename可以任意写,邮件中显示什么名字,尽量不用中文
att2["Content-Disposition"] = 'attachment; filename="2023-10-18result.html"'
message.attach(att2)


try:
    smtpObj = smtplib.SMTP()
    smtpObj.connect(mail_host, 25)  # 25 为 SMTP 端口号
    smtpObj.login(mail_user, mail_pass)
    smtpObj.sendmail(sender, receivers, message.as_string())
    print("邮件发送成功")
except smtplib.SMTPException:
    print("Error: 无法发送邮件")

四、发送带图片的邮件(部分代码)

# multipart类型主要有三种子类型:mixed、alternative、related。

# 创建一个带附件的实例
message = MIMEMultipart('related')
message['From'] = "@163.com"
message['To'] = "@qq.com"
subject = 'Python SMTP 邮件测试'
message['Subject'] = Header(subject, 'utf-8')

messageAlternative = MIMEMultipart('alternative')
message.attach(messageAlternative)


mail_msg = """
<p>Python 邮件发送测试...</p>
<p><a href="http://www.runoob.com">这是一个链接</a></p>
<p>图片测试</p>
<p><img decoding="async" src="cid:image1"></p>
"""
# 邮件正文内容
message.attach(MIMEText(mail_msg, 'html', 'utf-8'))    #发送HTML格式邮件


#获取图片
with open("D:\\testdata\\apic41419_s.jpg", 'rb') as fp:
    msgImage = MIMEImage(fp.read())

# 定义图片ID在HTML文本中引用
msgImage.add_header('Content-ID', '<image1>')

message.attach(msgImage)

五、优化:读取测试报告作为邮件内容发送

# 和图片类似,读取测试报告中的内容作为邮件的正文,但是没有添加对应样式,可能没有HTML中美观

with open(report_file, "rb") as f:
     mail_body = f.read()

msg = MIMEMultipart()
body = MIMEText(mail_body, _subtype='html', _charset='utf-8')
msg.attach(body)

六、发送邮件功能封装

将邮件基本信息放在配置文件config.py中,添加readConfig.py 读取配置文件

将发送邮件封装为函数,参数为测试文档,在测试用例执行完成后调用

七、邮箱设置

邮箱平台-设置页面开启相应的协议,并设置授权码即可(授权码就是代码中对应的密码)

仅为163邮箱,其他邮箱设置可能有差异

八、注意事项

1、需提前确认邮箱客户端是可以正常发送和接收邮件的,如果收件箱没有找到,可以看一下垃圾箱里有没有

2、以上以163邮箱为例,使用其他邮箱(如:QQ 邮箱 SMTP 服务器地址:smtp.qq.com,ssl 端口:465)会根据具体的SMTP协议导致服务器信息和端口号不同,一般控制台会报错:邮件发送失败,无法连接到服务器;这时候可以先查看防火墙或者对应的服务器、端口号是否一致

3、最常见报错

AttributeError: 'tuple' object has no attribute 'encode'

一般问题是出现在邮件的标题,SMTP协议中有定义的格式,MIME类型的标题必须是字符串,可以尝试以下方法

# 修改前
msg["from"]=sender
msg["to"]=psw

# 修改后  join方法或直接输入整个字符串
msg["from"] = ','.join(sender)
msg["to"] = "xx1@qq.com,xx2@qq.com,"

本人也遇到了这个问题,在标题这里死磕了半天,怎么都不对;最后发现是在每个参数的后边加了逗号,于是字符串变成了元组。。。。。

4、注意邮件所在类的命名,不能为email,因为和包重名了,运行会报错没有找到这个包,修改类名就可以了

ImportError: The module name 'email.mime' could not be found. email is not a package

5、windows系统自动升级到11后,文件夹都默认设置成了只读权限,修改后再打开还是只读,尝试了网络上其他方法也没有解决,客服没有回复,社区看了一下好像当前就是这样,也没有修改的措施,所以发送附件时只能选择到具体的文件,如果想选择某个文件夹下的HTML格式的文件,程序会报错文件夹没有权限

 6、添加附件中的filename尽量不用中文,否则邮箱实际接收到的HTML文件就会如下显示

参考网站:

Python3 SMTP发送邮件 | 菜鸟教程

smtplib,'tuple'对象没有属性'encode' | 那些遇到过的问题

python编程,排除163邮箱发送邮件报错(AttributeError: ‘tuple‘ object has no attribute ‘encode‘) - 代码先锋网python中发邮件时的 MIMEMultipart - 简书

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值