在Python中编码包含非ASCII字符的邮件主题(SMTP)

20 投票
3 回答
19221 浏览
提问于 2025-04-16 22:43

我正在使用Python的模块MimeWriter来构建一封邮件,然后用smtplib来发送这封邮件。构建的邮件内容是:

file msg.txt:
-----------------------
Content-Type: multipart/mixed;
from: me<me@abc.com>
to: me@abc.com
subject: 主題

Content-Type: text/plain;charset=utf-8

主題

我用下面的代码来发送邮件:

import smtplib
s=smtplib.SMTP('smtp.abc.com')
toList = ['me@abc.com']
f=open('msg.txt') #above msg in msg.txt file
msg=f.read()
f.close()
s.sendmail('me@abc.com',toList,msg)

我能正确获取邮件的正文内容,但主题却不太对劲,

subject: some junk characters

主題           <- body is correct.

请问有什么建议吗?有没有办法像处理正文那样,指定主题的解码方式?我该如何正确解码主题呢?

3 个回答

1

简单来说,如果你使用 EmailMessage 这个接口,你应该这样写代码:

from email.message import EmailMessage
from email.header import Header
msg = EmailMessage()
msg['Subject'] = Header('主題', 'utf-8').encode()

@Sérgio 的回答不能在 EmailMessage 接口中使用,因为 只能把字符串对象 赋值给 EmailMessage()["Subject"],而不能用 email.header.Header 这个对象。

8

主题是通过SMTP头部传输的,并且这些头部必须只使用ASCII字符。如果你想在主题中使用其他编码,就需要在主题前面加上你想用的编码标识。比如在你的情况下,我建议在主题前加上 ?UTF-8?B?,这表示使用的是UTF-8编码,并且是用Base64格式编码的。

换句话说,我认为你的主题头部应该大致是这个样子的:

Subject: =?UTF-8?B?JiMyMDAyNzsmIzM4OTg4Ow=?=

在PHP中,你可以这样做:

// Convert subject to base64
$subject_base64 = base64_encode($subject);
fwrite($smtp, "Subject: =?UTF-8?B?{$subject_base64}?=\r\n");

在Python中:

import base64
subject_base64 = base64.encodestring(subject).strip()
subject_line = "Subject: =?UTF-8?B?%s?=" % subject_base64
36

来自 http://docs.python.org/library/email.header.html

from email.message import Message
from email.header import Header
msg = Message()
msg['Subject'] = Header('主題', 'utf-8')
print msg.as_string()

主题: =?utf-8?b?5Li76aGM?=

更简单的写法是:

from email.header import Header
print Header('主題', 'utf-8').encode()

=?utf-8?b?5Li76aGM?=

另外,解码可以用以下方法:

from email.header import decode_header
a = decode_header("""=?utf-8?b?5Li76aGM?=""")[0]
print(a[0].decode(a[1]))

参考: Python - 邮件头的UTF-8解码

撰写回答