python3邮件消息禁用base64并删除MIME-Version


from email.message import EmailMessage
from email.headerregistry import Address
msg = EmailMessage()
msg['From'] = Address("Pepé Le Pew", "pepe", "example.com")
msg['To'] = (
Address("Penelope Pussycat", "penelope", "example.com")
, Address("Fabrette Pussycat", "fabrette", "example.com")
)
msg['Subject'] = 'This email sent from Python code'
msg.set_content("""
Salut!
Cela ressemble à un excellent recipie[1] déjeuner.
[1] http://www.yummly.com/recipe/Roasted-Asparagus-Epicurious-203718
--Pepé
""")
print(msg)

上面的代码产生一个使用base64编码的电子邮件消息。如何禁用它?如何删除MIME-Version字段?

将编码为" pep"被接收者正确地翻译?如果不是,确保接收方正确解释其编码的正确方法是什么?

From: Pepé Le Pew <pepe@example.com>
To: Penelope Pussycat <penelope@example.com>,
Fabrette Pussycat <fabrette@example.com>
Subject: This email sent from Python code
Content-Type: text/plain; charset="utf-8"
Content-Transfer-Encoding: base64
MIME-Version: 1.0
CQlTYWx1dCEKCgkJQ2VsYSByZXNzZW1ibGUgw6AgdW4gZXhjZWxsZW50IHJlY2lwaWVbMV0gZMOp
amV1bmVyLgoKCQlbMV0gaHR0cDovL3d3dy55dW1tbHkuY29tL3JlY2lwZS9Sb2FzdGVkLUFzcGFy
YWd1cy1FcGljdXJpb3VzLTIwMzcxOAoKCQktLVBlcMOpCgkJCg==

绝对不能删除MIME-Version:标头;它是将此标识为MIME消息的东西。

From:报头确实应该是rfc2047编码的,并且文档表明当消息被序列化时它将是。当你使用print(msg)时,你没有正确序列化它;您希望print(msg.as_string())显示所需的序列化。

当涉及到传输编码时,Python的email库有一个不吸引人的倾向,即对可以很好地编码为引用可打印的内容使用base64。你不能真正可靠地发送完全不编码的内容(尽管如果你想,MIME8bitbinary编码将能够适应这一点;但为了向后兼容,SMTP要求所有内容都被编码为7位表示)。

在旧的email库中,需要各种诡计才能做到这一点,但在Python 3.6中引入的新EmailMessageAPI中,您实际上只需要将cte='quoted-printable'添加到set_content调用中。

from email.message import EmailMessage
from email.headerregistry import Address
msg = EmailMessage()
msg['From'] = Address("Pepé Le Pew", "pepe", "example.com")
msg['To'] = (
Address("Penelope Pussycat", "penelope", "example.com")
, Address("Fabrette Pussycat", "fabrette", "example.com")
)
msg['Subject'] = 'This email sent from Python code'
msg.set_content("""
Salut!
Cela ressemble à un excellent recipie[1] déjeuner.
[1] http://www.yummly.com/recipe/Roasted-Asparagus-Epicurious-203718
--Pepé
""", cte="quoted-printable")   # <-- notice added parameter
print(msg.as_string())                 # <-- properly serialize

不幸的是,从文档中找出这一点几乎是不可能的。set_content的文档基本上只是指向raw_data_managerpolicy(如果你注意到链接的话)…最后您可能会注意到cte关键字参数的存在。

演示:https://ideone.com/eLAt11

(顺便说一句,您可能还想

replace('n   ', 'n')

如果您选择8bitbinary内容传输编码,它们之间的区别在于前者有行长度限制(最多900个字符),而后者完全不受约束。但是您需要确保整个SMTP传输路径是8位干净的(在这一点上,您不妨完全转向Unicode email/ESMTPSMTPUTF8)。

为方便您娱乐,这里有一些关于Python 3.5及更早版本的疯狂技巧的老问题。

最新更新