python - 用于禁用 base64 并删除 MIME 版本的 python3 电子邮件
问题描述
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
内容很不吸引人,这些内容很可能被编码为quoted-printable。您不能真正可靠地发送完全未编码的内容(尽管如果您愿意,MIME8bit
或binary
编码将能够适应这种情况;但为了向后兼容,SMTP 要求将所有内容编码为 7 位表示)。
在旧email
库中,需要各种恶作剧才能做到这一点,但在EmailMessage
Python 3.6 中引入的新 API 中,您实际上只需要添加调用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
基本上只是推迟到policy
哪个模糊地指向raw_data_manager
(如果你甚至注意到链接)......最后你希望注意到cte
关键字参数的存在。
(顺便说一句,您可能还想
replace('\n ', '\n')
在正文中。)
如果您使用8bit
或binary
内容传输编码,它们之间的区别在于前者有行长限制(最多 900 个字符),而后者完全不受限制。但是您需要确保整个 SMTP 传输路径是 8 位干净的(此时您不妨完全转向Unicode 电子邮件/ESMTP SMTPUTF8
)。
推荐阅读
- mysql - MySqlDataReader 强制转换函数,wpf
- csv - NiFi:路由 CSV,按内容拆分,并通过相同内容更改名称
- spring-boot - Spring Boot 应用程序、内容服务和应用程序运行良好,但收到大量“未找到 *... 的处理程序方法”垃圾邮件
- java - Spring:何时选择哪种验证方法?
- eclipse - 如何通过 eclipse 中的不同 p2.inf 文件触发多个更改?
- python - 是否可以将单一回归技术应用于具有不同模式的数据?
- sql - 从 Oracle 中提取 Excel 查询偶尔失败(ODBC 错误)如何解决?
- java - 从缓冲区读取器输入字符串时出现 Java 编号异常
- c# - N 个线程中有 1 个从未加入
- html - 减小窗口大小时如何制作2个固定按钮而不重叠它们