【问题标题】:How to send an e-mail to the international address如何向国际地址发送电子邮件
【发布时间】:2016-03-06 13:38:54
【问题描述】:

如何在 Python 中通过smtplib 向国际地址发送电子邮件?

如果我使用以下代码

    try:
        server = None

        msg = MIMEMultipart('alternative')
        msg['From'] = formataddr((from_email_name, from_email))
        msg['To'] = Header(to_email, 'utf-8')
        msg['Subject'] = Header(subject, 'utf-8')

        plain_text_part = MIMEText(plain_text_body, 'plain', _charset='utf-8')
        msg.attach(plain_text_part)

        html_part = MIMEText(html_body, 'html', _charset='utf-8')
        msg.attach(html_part)

        server = smtplib.SMTP(smtp_server)
        server.starttls()
        server.login(from_email, from_email_password)
        server.sendmail(from_email, to_email, msg.as_string())
    finally:
        if server is not None:
            server.quit()

然后,当我使用ñoñó1234@server.com 电子邮件作为目标地址 (to_email) 调用此代码时,脚本在以下行失败:

server.sendmail(from_email, to_email, msg.as_string())

输出

'ascii' 编解码器无法对位置 9 中的字符 u'\xf1' 进行编码:序数不在范围内(128)

但是,如果我将 sendmail 函数调用更改为以下内容

server.sendmail(from_email, to_email.encode('utf-8'), msg.as_string())

它失败并出现以下错误:

{'\xc3\xb1o\xc3\xb1\xc3\xb31234@server.com': (555, '5.5.2 语法 错误。 i7sm368361lbo.39 - gsmtp')}

我正在使用 GMail 的 SMTP 服务器来发送这些电子邮件。

我该如何解决?

提前致谢。

【问题讨论】:

  • 试试这个:msg['To'] = str(Header(to_email, 'utf-8')) 告诉我这是否有效。
  • @Prav001 不幸的是,它不起作用。请注意,应用程序在 sendmail 函数调用时崩溃
  • 也许您应该尝试utf-8以外的其他编码方案?
  • @Iron Fist UTF-16 也不起作用 -- {'\xff\xfe\xf1\x00o\x00\xf1\x00\xf3\x001\x002\x003\x004\x00@\x00s\x00e\x00r\x00v\x00e\x00r\x00.\x00c\x00o\x00m\x00': (555, '5.5.2 Syntax error. qp7sm484744lbc.24 - gsmtp')}
  • 国际化地址是一个特殊的用例,根据 RFC 6530,服务器应该宣布 SMTPUTF8 功能,并且客户端在其MAIL 命令中传递 SMTPUTF8 选项。如果服务器宣布它并且如果程序员要求,Python smtplib 可以传递 SMTPUTF8 选项。您应该在server = smtplib.SMTP(smtp_server) 之后立即添加server.set_debuglevel(7) 并在此处报告会话记录。

标签: python python-2.7 email unicode


【解决方案1】:

RFC 6533 - Overview and Framework for Internationalized Email 声明服务器端:

SMTP 中继必须

  • 要么明确识别格式,要么通过以下方式同意这样做 ESMTP 选项,或
  • 拒绝邮件,或者,如有必要,退回未送达 通知消息,以便发件人可以制作另一个 计划。

并且 RFC 6531 - SMTP Extension for Internationalized Email 表示精度(摘录):

  • 与此扩展关联的 EHLO 关键字值为 "SMTPUTF8"
  • 一个可选参数 SMTPUTF8 被添加到 MAIL 命令中。
  • 如果要发送的信封或消息需要以下功能 SMTPUTF8 扩展,支持 SMTPUTF8 的 SMTP 客户端必须提供 MAIL 命令的 SMTPUTF8 参数。

由于与 GMail SMTP 服务器的交换记录证明它宣称自己是符合 SMTPUTF8 的服务器,因此您只需要求smtplib 在邮件命令中提供SMTPUTF8 选项。你只需要将sendmail命令改为:

server.sendmail(from_email, to_email.encode('utf-8'), msg.as_string(), ['SMTPUTF8'])

因为您已经在正文中处理了最终的非 ASCII 字符并使用 MIMEMultipart 和 MIMEText 设置了适当的标题,所以一切都应该没问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-03-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-04
    • 1970-01-01
    • 1970-01-01
    • 2014-07-20
    相关资源
    最近更新 更多