Python smtplib 和国际化错误与 smtputf8 修复

Python smtplib and internationalization error with smtputf8 fix

在名称中使用非 ascii 字符时,python smtplib 出现问题。部分错误代码 - 是

server does not advertise the required SMTPUTF8 capability

我在网上查了解决办法,也在 Whosebug 上看了一圈也没有解决办法。

使用相同

smtp

在其他具有相同发件人名称的邮件客户端上它起作用了,所以我认为这可以用代码解决,因为我无法编辑服务器配置。

请提供解决方案指南或示例以帮助解决此问题。

请参阅下面带有回溯的代码片段。

# the problem is this line below. How do I make it work regardless 
# since i have no means of advertising smtputf8 from there server.
# Thunderbird doesn't have problem with the name when used as client.

data['from_name'] = "Böy" # problem is the ö
data['from_email'] = "user@example.com"
msg = MIMEMultipart()
msg['To'] = "{to_name} <{to_email}>".format(**data)
msg['From'] = "{} <{}>".format(data['from_name'], data['from_email'])
msg['Date'] = formatdate(localtime=True)
msg['Subject'] = subject
msg.attach(MIMEText(body, 'html'))

smtp_server.send_message(msg) # exception is raised here

回溯:

`Traceback (most recent call last):
  File "Emailer.py", line 460, in <module>
    main(args)
  File "Emailer.py", line 447, in main
    sender.send()
  File "Emailer.py", line 386, in send
    smtp_server.send_message(msg)
  File "/usr/local/Cellar/python3/3.6.4_2/Frameworks/Python.framework/Versions/3.6/lib/python3.6/smtplib.py", line 952, in send_message
    "One or more source or delivery addresses require"
smtplib.SMTPNotSupportedError: One or more source or delivery addresses require internationalized email support, but the server does not advertise the required SMTPUTF8 capability`

我无法重现您的问题。使用以下增强代码,我得到了 MCVE:

from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.utils import formatdate


data = {'to_name': 'me', 'to_email': 'me@example.net'}
subject = 'Hellö'
body = 'Hellö'

data['from_name'] = "Böy" # problem is the ö
data['from_email'] = "user@example.com"
msg = MIMEMultipart()
msg['To'] = "{to_name} <{to_email}>".format(**data)
msg['From'] = "{} <{}>".format(data['from_name'], data['from_email'])
msg['Date'] = formatdate(localtime=True)
msg['Subject'] = subject
msg.attach(MIMEText(body, 'html'))

print(msg.as_string())

但是当我 运行 它时,Python 会生成一个完全健康的、完全 7 位的 US-ASCII 消息,所有部分都经过精确编码,就像它们应该用于没有遗留服务器的那样。不支持 SMTPUTF8。

Content-Type: multipart/mixed; boundary="===============2605356503081581034=="
MIME-Version: 1.0
To: me <me@example.net>
From: =?utf-8?b?QsO2eSA8dXNlckBleGFtcGxlLmNvbT4=?=
Date: Mon, 13 Aug 2018 10:56:02 +0300
Subject: =?utf-8?b?SGVsbMO2?=

--===============2605356503081581034==
Content-Type: text/html; charset="utf-8"
MIME-Version: 1.0
Content-Transfer-Encoding: base64

SGVsbMO2

--===============2605356503081581034==--

但是,我会注意到将裸 MIMEMultipart 实例化为您的顶级消息并不正确。你应该有一个 Message object and then add MIME parts to that. But this still uses the somewhat complex legacy Python email API; with the new API, which was introduced in 3.3 and became the preferred API in 3.6, you should start with an EmailMessage 并从那里拿走它。

无论如何,如果您只有一个正文部分,则不应将其包装在多部分消息中。只需创建一封电子邮件并将文本部分直接附加到该邮件即可。 (拥有比您需要的更复杂的 MIME 结构本身并没有 错误 ,但是增加不必要的复杂性和开销是愚蠢的。)