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 结构本身并没有 错误 ,但是增加不必要的复杂性和开销是愚蠢的。)
在名称中使用非 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 结构本身并没有 错误 ,但是增加不必要的复杂性和开销是愚蠢的。)