Python 发送邮件时遇到的问题

目录

前言

错误重现

 解决错误

问题重现

中文附件名"未命名"

解决方法

附件内容中的中文报错

解决方法

尾声


前言

这篇文章主要是解决使用python发送邮件时遇到的一些问题

分别是在发送邮件时报了这么个错误

535, b'Login Fail. Please enter your authorization code to login. More information in http://XXX'

第二个是发送带有附件的邮件时,如果附件文件名中文,则附件文件名"未命名"

第三个是附件内容中有中文报错

UnicodeDecodeError: 'gbk' codec can't decode byte XXX in position XXX: illegal multibyte sequence

错误重现

先来一个小例子,我就使用QQ邮箱发送邮件到163邮箱

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


def QQEmailTo163Email():
	# 登录QQ邮箱,发邮件给163邮箱
	# ①设置服务器所需信息
	# QQ邮箱服务器地址
    # 登录QQ邮箱
	mail_host = 'smtp.qq.com'
	# QQ邮箱用户名(登录)
	mail_userName = 'XXX@qq.com'
	# QQ邮箱密码
	mail_passWord = 'XXX'
	
	# ===========================
	
	# 邮件发送方邮箱
	sender = 'XXX@qq.com'
	# 邮件接收方邮箱
	receivers = 'XXX@163.com'
	
	# ===========================
	
	# ②设置email信息
	# 设置邮件内容,三个参数:第一个为文本内容,第二个 plain 设置文本格式,第三个 utf-8 设置编码
	message = MIMEText('你好啊,这是一次测试', 'plain', 'utf-8')
	# 设置邮件主题
	# Header是用来构建邮件头的
	subject = 'python发送邮件测试'
	message['Subject'] = Header(f'{subject}', 'utf-8')
	# 发送方信息
	message['From'] = Header(f'{sender}', 'utf-8')
	# 接收方信息
	message['To'] = Header(f'{receivers}', 'utf-8')

	# ===========================

	# ③登录并发送邮件
	try:
		# 创建SMTP对象
		smtpObj = smtplib.SMTP()
		# 连接到服务器,25为SMTP端口号
		smtpObj.connect(mail_host, 25)
		# 登录服务器
		smtpObj.login(mail_userName, mail_passWord)
		# 发送
		smtpObj.sendmail(sender, receivers, message.as_string())
		# 退出
		smtpObj.quit()
		print('邮件发送成功')
	except smtplib.SMTPException as e:
		print(f'QQ向163→邮件发送失败,原因是:{e}')


if __name__ == '__main__':
	QQEmailTo163Email()

 然后就报了这么个错误,要求我们使用授权码登录

 解决错误

 那这么获得发送邮箱的授权码呢?由于我是QQ邮箱为发送方,那么就获得QQ邮箱的授权码

登录QQ邮箱→进入设置→账户

 接下来应该不用说了,将获得到的授权码替换成密码,再执行一次

 成功执行,打开163邮箱查看一下


问题重现

中文附件名"未命名"

先准备好两个的附件,附件内容不能有中文

 这两个附件的名字是不是中文不重要,因为在发送附件的时候,可以对附件重命名

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


def QQEmailTo163Email_attachment():
	# 发送带附件的邮件,首先要创建MIMEMultipart()实例,然后构造附件,如果有多个附件,可依次构造,最后利用smtplib.smtp发送。
	# 登录QQ邮箱,发邮件给163邮箱
	# ①设置服务器所需信息
	# QQ邮箱服务器地址
	# 登录QQ邮箱
	mail_host = 'smtp.qq.com'
	# QQ邮箱用户名(登录)
	mail_userName = 'XXX@qq.com'
	# QQ邮箱密码
	# mail_passWord = 'XXX'

	# ===========================

	# 邮件发送方邮箱
	sender = 'XXX@qq.com'
	# 邮件接收方邮箱
	receivers = 'XXX@163.com'

	# ===========================

	# 创建MIMEMultipart实例
	message = MIMEMultipart()
	# ②设置email信息
	# 设置邮件主题
	# Header是用来构建邮件头的
	subject = 'python发送带附件的邮件测试'
	message['Subject'] = Header(f'{subject}', 'utf-8')
	# 发送方信息
	message['From'] = Header(f'{sender}', 'utf-8')
	# 接收方信息
	message['To'] = Header(f'{receivers}', 'utf-8')

	# 邮件正文内容
	message.attach(MIMEText('你好啊,这是一次测试', 'plain', 'utf-8'))

	# ===========================

	# 构造附件1
	file_name = '附件1.txt'
	# 文件路径
	filePath = f'file/{file_name}'
	appendix1 = MIMEText(open(filePath).read(), 'html', 'utf-8')
	# 定附件义内容类型
	appendix1['Content-Type'] = 'application/octet-stream'
	# 定义内容配置
	# 这里的filename可以任意写,写什么名字,邮件中附件就显示什么名字,相当于重新命名
	# # 附件名称为非中文且附件内容没有中文时使用
	appendix1['Content-Disposition'] = f'attachment; filename="test1.txt"'
	# # 将附件添加进邮件内容
	message.attach(appendix1)

	# 构造附件2
	file_name2 = '附件2.txt'
	# 文件路径
	filePath2 = f'file/{file_name2}'
	appendix2 = MIMEText(open(filePath2).read(), 'html', 'utf-8')
	# 定附件义内容类型
	appendix2['Content-Type'] = 'application/octet-stream'
	# 定义内容配置
	# 这里的filename可以任意写,写什么名字,邮件中附件就显示什么名字,相当于重新命名
	# 附件名称为非中文且附件内容没有中文时使用
	appendix2['Content-Disposition'] = f'attachment; filename="test2.txt"'
	# # 将附件添加进邮件内容
	message.attach(appendix2)

	# ③登录并发送邮件
	try:
		# 创建SMTP对象
		smtpObj = smtplib.SMTP()
		# 连接到服务器,25为SMTP端口号
		smtpObj.connect(mail_host, 25)
		# 登录服务器
		smtpObj.login(mail_userName, mail_passWord)
		# 发送
		smtpObj.sendmail(sender, receivers, message.as_string())
		# 退出
		smtpObj.quit()
		print('邮件发送成功')
	except smtplib.SMTPException as e:
		print(f'QQ向163→邮件发送失败,原因是:{e}')

if __name__ == '__main__':
	QQEmailTo163Email_attachment()

 注意,我这里对附件进行了重命名,将它们的名字改为了test1.txttest2.txt,主要是要先看正常情况下是怎么样的,要形成对比。

 接收到的文件名没有问题,把文件下载下来看一看

 可以看见test2出了点小问题,英文竟然也出了问题,唉,等下一起解决吧


 接下来我将附件名称改为中文

appendix1['Content-Disposition'] = f'attachment; filename="{file_name}"'
appendix2['Content-Disposition'] = f'attachment; filename="{file_name2}"'

 再次执行

 可以看见出了问题,文件名不太对劲,甚至连后缀都没有

解决方法

# 附件命名为中文时使用,文件可以为中文,但下载附件打开时会乱码
appendix1.add_header('Content-Disposition', 'attachment', filename=('utf-8', '', f'{file_name}'))

我先改一个,方便形成对比参照

 效果显著,至于内容,我试过了,跟之前的一样。

中文文件名问题已经结解决了,接下来要解决的是,附件内容中的中文乱码


附件内容中的中文报错

先在附件中添加中文

 

 执行之前的代码

 直接就裂开,跑都跑不动,报了这么个错误,很显然是中文引起的

UnicodeDecodeError: 'gbk' codec can't decode byte XXX in position XXX: illegal multibyte sequenc

解决方法

这个其实挺好解决的,出现这个现象的原因是:在python中默认的编码方式是 “ gbk ”,而Windows中的文件默认的编码方式是 “ utf-8 ” ,所以导致python编译器无法成功读取或写入文件内容。

在读取文件的时候,指定一下编码就好了

with open(file=f'{filePath}', mode='r', encoding='utf-8') as f:
	data = f
	appendix1 = MIMEText(data.read(), 'html', 'utf-8')

执行一下

 文件名没有问题

 附件内容也没有问题


尾声

很抱歉,写的有些乱,再给大家总结一下吧

# 附件名称为非中文且附件内容没有中文时使用
appendix1['Content-Disposition'] = f'attachment; filename="{file_name}"'

# 附件命名为中文时使用,文件可以为中文,但下载附件打开时会乱码
appendix1.add_header('Content-Disposition', 'attachment', filename=('utf-8', '', f'{file_name}'))

#使用这种读取方式可以读取中文内容
with open(file=f'{filePath}', mode='r', encoding='utf-8') as f:
	data = f
	appendix1 = MIMEText(data.read(), 'html', 'utf-8')

如果这篇文章对您有所帮助,那么这篇文章就有意义!


感谢您的观看!

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值