Skip to main content
 首页 » 编程设计

python之如何向国际地址发送电子邮件

2024年08月23日37kuangbin

如何在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' codec can't encode character u'\xf1' in position 9: ordinal not in range(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 Syntax error. i7sm368361lbo.39 - gsmtp')}

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

我该如何解决?

提前致谢。

请您参考如下方法:

RFC 6533 - Overview and Framework for Internationalized Email 指出服务器端:

An SMTP relay MUST

  • Either recognize the format explicitly, agreeing to do so via an ESMTP option, or
  • Reject the message or, if necessary, return a non-delivery notification message, so that the sender can make another plan.

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

  • The EHLO keyword value associated with this extension is "SMTPUTF8"
  • One OPTIONAL parameter, SMTPUTF8, is added to the MAIL command.
  • If the envelope or message being sent requires the capabilities of the SMTPUTF8 extension, the SMTPUTF8-aware SMTP client MUST supply the SMTPUTF8 parameter with the MAIL command.

由于与 GMail SMTP 服务器交换的痕迹证明它宣布自己是 SMTPUTF8 兼容服务器,您只需要求 smtplib 提供 SMTPUTF8 选项邮件命令。您只需要将 sendmail 命令更改为:

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

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