从 Python 发送电子邮件,收件人或发件人姓名中包含变音符号

M.K*_*isu 5 python email encoding

我目前正在尝试从 python 脚本向一组从数据库(姓名+电子邮件地址)获取的收件人发送电子邮件,并且我希望发送邮件,以便他们的姓名也包含在邮件标头中。但是,如果名称包含元音变音 (\xc3\xa4\xc3\xb6\xc3\xbc...),我的脚本将失败(如果名称中有 \xc3\xbc):

\n\n
UnicodeEncodeError: \'ascii\' codec can\'t encode character \'\\xfc\' in position 5: ordinal not in range(128)\n
Run Code Online (Sandbox Code Playgroud)\n\n

但在消息内容中,所有元音变音都被正确替换为=C3=BC例如\xc3\xbc.

\n\n

这是我使用的示例代码:

\n\n
import smtplib\nfrom email.message import EmailMessage\nfrom email.headerregistry import Address\nfrom email.utils import make_msgid\n\nmsg = EmailMessage() \nmsg["Subject"] = "Python Test" \nmsg["From"] = Address("Max M\xc3\xbcller" , addr_spec="maxmueller@localhost.localnet") \nmsg["To"] =  Address("Max M\xc3\xb6ller", addr_spec="moeller@localhost.localnet")\n\nmsg.set_content("""\\\nThis is a test with umlauts. \xc3\xb6\xc3\xa4\xc3\xbc\n--- Max M\xc3\xbcller """)\nserver = smtplib.SMTP(\'localhost\', 25) \nserver.send_message(msg)\nserver.quit() \n
Run Code Online (Sandbox Code Playgroud)\n\n

我用Python 3.5.2尝试过。

\n\n

如果更换

\n\n
msg["From"] = Address("Max M\xc3\xbcller" , addr_spec="maxmueller@localhost.localnet") \n
Run Code Online (Sandbox Code Playgroud)\n\n

经过

\n\n
msg["From"] = Address("Max M\xc3\xbcller".encode("utf-8") , addr_spec="maxmueller@localhost.localnet") \n
Run Code Online (Sandbox Code Playgroud)\n\n

我在邮件客户端中输入了发件人姓名b\'Max M\\xc3\\xbcller\',这对大多数电子邮件客户端来说毫无用处。

\n\n

那么如何将收件人和发件人的变音符号编码为邮件内容呢?

\n

Ser*_*sta 6

几乎一切都很好,但是该send_message方法并不是真正的非 ASCII 友好的,因此您必须使用旧的sendmail. 问题是send_message尝试使用ToFrom标头的内容来构建信封地址,但不幸的是,对于包含非 ASCII 字符的地址,即使它们位于名称部分,它也会被破坏。

因此,如果您只有一个收件人地址,您的代码应该是:

...
server.sendmail(msg["From"], msg["To"], msg.as_string())
Run Code Online (Sandbox Code Playgroud)

如果您希望能够处理多个收件人地址,则必须添加显式处理:

def envelopeAddr(header):
    return [a.addr_spec for a in header.addresses]
Run Code Online (Sandbox Code Playgroud)

sendmail 命令变为:

server.sendmail(msg["From"], envelopeAddr(msg["To"]), msg.as_string())
Run Code Online (Sandbox Code Playgroud)

好消息是它也适用于单个目标地址。