使用变音符号以收件人或发件人的名义从Python发送电子邮件

时间:2017-03-29 06:46:29

标签: python email encoding

我目前正在尝试从python脚本发送电子邮件到一组来自数据库(名称+电子邮件地址)的收件人,我希望这样发送邮件,使其名称也包含在邮件头中。但是,如果名称包含变音符号(äöü...),我的脚本会失败(如果名称中有ü):

UnicodeEncodeError: 'ascii' codec can't encode character '\xfc' in position 5: ordinal not in range(128)

但是在消息的内容中,所有变音符号都被=C3=BC的{​​{1}}正确替换为ü

以下是我使用的示例代码:

import smtplib
from email.message import EmailMessage
from email.headerregistry import Address
from email.utils import make_msgid

msg = EmailMessage() 
msg["Subject"] = "Python Test" 
msg["From"] = Address("Max Müller" , addr_spec="maxmueller@localhost.localnet") 
msg["To"] =  Address("Max Möller", ddr_spec="moeller@localhost.localnet")

msg.set_content("""\
This is a test with umlauts. öäü
--- Max Müller """)
server = smtplib.SMTP('localhost', 25) 
server.send_message(msg)
server.quit() 

我用Python 3.5.2尝试过它。

如果替换

msg["From"] = Address("Max Müller" , addr_spec="maxmueller@localhost.localnet") 

通过

msg["From"] = Address("Max Müller".encode("utf-8") , addr_spec="maxmueller@localhost.localnet") 

我收到了邮件客户端,因为发件人姓名为b'Max M\xc3\xbcller',这对大多数电子邮件客户端都没用。

那么我如何获得收件人中的变音符号和邮件内容中的发件人编码?

2 个答案:

答案 0 :(得分:3)

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

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

...
server.sendmail(msg["From"], msg["To"], msg.as_string())

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

def enveloppeAddr(header):
    return [a.addr_spec for a in header.addresses]

sendmail命令变为:

server.sendmail(msg["From"], enveloppeAddr(msg["To"]), msg.as_string())

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

答案 1 :(得分:0)

def dd_b64(s):
    s = '=?utf-8?b?' + base64.b64encode(s.encode('UTF-8')).decode() + '?='
    s = '=?utf-8?b?' + base64.b64encode(s.encode('UTF-8')).decode() + '?='
    return s

msg = EmailMessage()
#msg['From'] = Address(dd_b64(发送者昵称), *发送者账号.rsplit('@', 1))
msg['From'] = Address(dd_b64(发送者昵称), addr_spec = 发送者账号)  #省略addr_spec会出现 由 public@zxxxn.com 代发
msg['To'] = Group(None, [Address(dd_b64(name), to_addrs)])
msg['Subject'] = '63中文'
msg['Date'] = localtime()
===========================================================================

将b64双重编码为​​“从,到和添加附件的文件名”

msg["From"] = Address(dd_b64("Max Müller") , addr_spec="maxmueller@localhost.localnet") 
msg["To"] also dd_b64.

msg.add_attachment(fi.read(), *ctype.split('/', 1), filename = dd_b64('工作表.xlsx'))