【问题标题】:Python smtplib and internationalization error with smtputf8 fix使用 smtputf8 修复 Python smtplib 和国际化错误
【发布时间】:2018-08-12 13:01:04
【问题描述】:

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

server does not advertise the required SMTPUTF8 capability

我已经在网上查了解决方案,也在 stackoverflow 中查看了没有解决方案。

使用相同的

smtp

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

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

请参阅下面带有回溯的代码的 sn-p。

# 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`

【问题讨论】:

  • Thunderbird 最有可能使用 RFC2047 封装对字符串进行编码;因此它不会尝试将裸 UTF-8 发送到不支持此功能的服务器。
  • @tripleee 好建议,我会看看我能不能走那条路。不介意您是否可以对此进行更多说明,因为消息正文已经是 utf8。怀疑我可以结合两种编码

标签: python python-3.x email utf-8 smtplib


【解决方案1】:

我无法重现您的问题。使用以下增强代码,我有一个似乎是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 对象,然后向其中添加 MIME 部分。但这仍然使用有些复杂的遗留 Python email API;使用 3.3 中引入并在 3.6 中成为首选 API 的新 API,您应该从 EmailMessage 开始并从那里获取。

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

【讨论】:

  • 完美。我是从 github 源中找到的。 formataddr 是来自 email.utils 的解决方案,它需要一组名称和电子邮件。非常感谢其他提示
猜你喜欢
  • 1970-01-01
  • 2014-08-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-01-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多