Python发送邮件550错误,邮件被系统退回,From字段汉字编码问题,上传附件附件名是中文编码问题(已解决)

一、FROM字段编码

1.问题

未知原因导致退信

服务器返回码:

SMTP error, DOT: Host qq.com(157.255.4.241) DOT said 550 The "From" header is missing or invalid. Please follow RFC5322, RFC2047, RFC822 standard protocol. [MIeJ6idQjpU+jtSwT+aVpzZn6Lt4t7L9L5SNdRRpvHFjruDr7ldlZXtjm76w== IP: 117.135.210.5]. https://service.mail.qq.com/detail/124/995.

 由邮件返回信息可知是From字段出现了问题,查询163邮件合法性检查

邮箱From合法性检查

一、根据RFC5322协议,邮件标头中需要包含’From’信息。

二、根据RFC2047, RFC822协议,邮件标头中的’From’形式为:

1.邮箱地址形式:prefix@domain, 如 ‘abc@qq.com’。

2.昵称+空格+<邮箱地址>形式:nickname prefix@domain,其中,nickname为ASCII字符集中字符组合或编码文本:

如果昵称全为ASCII字符,如’ABC’,邮箱地址为’abc@qq.com’,则标头中的’From’为’ABC abc@qq.com‘。注意’ABC’和’abc@qq.com‘之间用空格隔开;

如果昵称包含非ASCII字符,如中文,则请使用base64对昵称进行编码。nickname最终的形式为:”=?” charset “?” encoding “?” encoded-text “?=”。其中,charset为字符集;encoding为编码方式,’B’代表base64;encoded-text为编码后的文本。例如,昵称为’QQ邮箱昵称示例’,邮箱地址为’abc@qq.com’,则对昵称进行base64编码,字符集使用UTF-8,则nickname为 ‘=?UTF-8?B?UVHpgq7nrrHmmLXnp7DnpLrkvos=?=’,最终邮件标头中的’From’为’”=?utf-8?B?UVHpgq7nrrHmmLXnp7DnpLrkvos=?=” abc@qq.com‘。注意编码文本和邮件地址间用空格隔开。

参考文献
https://www.rfc-editor.org/rfc/rfc5322
https://www.rfc-editor.org/rfc/rfc822
https://www.rfc-editor.org/rfc/rfc2047

2.解决

当From为中文的时候,需要满足格式

’”=?utf-8?B?你的字段编码后内容?=” abc@qq.com‘
1.需要对From要送的内容进行base64编码,字符集使用utf-8,然后前面拼接上”=?utf-8?B?,后面拼接上?=”,拼接之后有一个空格,再拼接上发送的邮箱地址(双引号可带可不带)
2.对From使用Header()函数赋值的时候不能使用utf-8编码

示例代码

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

sender = 'xxx@163.com'
pwd = 'FCPYYGMK'

receivers = ['123456@qq.com']

nickname='邮件测试'
encoded_nickname = '"=?UTF-8?B?' + base64.b64encode(nickname.encode('utf-8')).decode('utf-8') + f'?=" {sender}'

message = MIMEText('Python 邮件发送测试。。。', 'plain', 'utf-8')
message['From'] = Header(encoded_nickname)
message['To'] = Header('测试', 'utf-8')

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

try:
    smtpObj = smtplib.SMTP_SSL('smtp.163.com',465)
    smtpObj.login(sender, pwd)
    smtpObj.sendmail(sender, receivers, message.as_string())
    print(message.as_string())
    print('邮件发送成功')
except smtplib.SMTPException as se:
    print(f'ERROR:无法发送邮件.Case:{se}')

-----------------------------------------------------------------
打印结果:
Content-Type: text/plain; charset="utf-8"
MIME-Version: 1.0
Content-Transfer-Encoding: base64
From: "=?UTF-8?B?6YKL6K+V?=" xxx@163.com
To: =?utf-8?b?5rK+V?=
Subject: =?utf-8?b?UHl0aG9uIFAg6YKu5Lu25rWL6K+V?=

UHl0aG9uIOmCruS7tuWAgea1i+ivleOAguOAguOAgg==

邮件发送成功

邮件接收:

二、附件中文名编码

1.问题

邮件添加附件"文件.txt",附件名是中文,能发送成功,但是接收后附件显示是bin文件

2.解决

与上面的问题一样,也是中文编码的问题,将中文部分进行编解码,拼接到字符串中(不可带双引号)

att1 = MIMEText(open('D:\\Downloads\\test.txt', 'rb').read(), 'base64', 'utf-8')
att1["Content-Type"] = 'application/octet-stream'

#如果文件名是中文需要做如下编解码处理
fname = '=?UTF-8?B?' + base64.b64encode('文本'.encode('utf-8')).decode('utf-8') + '?='
att1["Content-Disposition"] = f'attachment; filename="{fname}.txt"'
message.attach(att1)

重新发送,问题解决

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值