![](/img/trans.png)
[英]Python send email with "quoted-printable" transfer-encoding and "utf-8" content-encoding
[英]How do I use Python 3.2 email module to send unicode messages encoded in utf-8 with quoted-printable?
我想在Python 3.2程序中发送具有任意unicode主体的电子邮件。 但实际上,这些消息主要由7位ASCII文本组成。 所以我想使用quoted-printable在utf-8中编码的消息。 到目前为止,我发现这有效,但似乎错了:
c = email.charset.Charset('utf-8')
c.body_encoding = email.charset.QP
m = email.message.Message()
m.set_payload("My message with an '\u05d0' in it.".encode('utf-8').decode('iso8859-1'), c)
这会生成包含完全正确内容的电子邮件:
To: someone@example.com
From: someone_else@example.com
Subject: This is a subjective subject.
MIME-Version: 1.0
Content-Type: text/plain; charset="utf-8"
Content-Transfer-Encoding: quoted-printable
My message with an '=D7=90' in it.
特别是b'\\xd7\\x90'.decode('utf-8')
产生原始的Unicode字符。 因此quoted-printable
编码正确呈现utf-8
。 我很清楚这是一个令人难以置信的丑陋黑客。 但它的确有效。
这是Python 3.文本字符串应始终是unicode。 我不应该将其解码为utf-8。 然后通过.decode('iso8859-1')
将它从bytes
回str
是一个可怕的黑客攻击,我也不应该这样做。
email
模块刚刚打破了编码? 我没有得到什么吗?
我试图只是简单地设置它,没有字符集。 这留给我一个unicode电子邮件消息,这根本不对。 我也尝试过了encode
和decode
步骤。 如果我将它们都关闭,它会在尝试确定是否需要在quoted-printable编码中引用该字符时抱怨\א
超出范围。 如果我只留下encode
步骤,它会痛苦地抱怨我是如何传递一个bytes
而它想要一个str
。
该电子邮件包并不混淆哪个(编码的unicode与内容传输编码的二进制数据),但是文档没有说清楚,因为大部分文档都是从“编码” 意味着内容的时代开始的 -传输编码。 我们正在开发一个更好的API,这将使所有这些更容易grok(和更好的文档)。
实际上有一种方法可以让电子邮件包将QP用于utf-8机构,但它没有很好的记录。 你这样做:
>>> charset.add_charset('utf-8', charset.QP, charset.QP)
>>> m = MIMEText("This is utf-8 text: á", _charset='utf-8')
>>> str(m)
'Content-Type: text/plain; charset="utf-8"\nMIME-Version: 1.0\nContent-Transfer-Encoding: quoted-printable\n\nThis is utf-8 text: =E1'
运行
import email
import email.charset
import email.message
c = email.charset.Charset('utf-8')
c.body_encoding = email.charset.QP
m = email.message.Message()
m.set_payload("My message with an '\u05d0' in it.", c)
print(m.as_string())
产生此回溯消息:
File "/usr/lib/python3.2/email/quoprimime.py", line 81, in body_check
return chr(octet) != _QUOPRI_BODY_MAP[octet]
KeyError: 1488
以来
In [11]: int('5d0',16)
Out[11]: 1488
很明显,unicode '\א'
是问题角色。 _QUOPRI_BODY_MAP
在quoprimime.py中定义
_QUOPRI_HEADER_MAP = dict((c, '=%02X' % c) for c in range(256))
_QUOPRI_BODY_MAP = _QUOPRI_HEADER_MAP.copy()
此dict仅包含range(256)
中的键。 所以我认为你是对的; quoprimime.py
不能用于编码任意unicode。
作为解决方法,您可以通过省略使用(默认)base64
c.body_encoding = email.charset.QP
请注意, 最新版本的quoprimime.py根本不使用_QUOPRI_BODY_MAP
,因此使用最新的Python可能会解决问题。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.