python3 禁用 base64 并删除 MIME 版本的电子邮件
python3 email message to disable base64 and remove 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:
header;它将此标识为 MIME 消息。
From:
header 确实应该是 RFC2047 编码的,文档表明它将是“当消息被序列化时”。当你 print(msg)
你没有正确序列化它;你想要 print(msg.as_string())
确实展示了所需的序列化。
当谈到传输编码时,Python 的 email
库对使用 base64
的内容没有吸引力,这些内容很可能被编码为 quoted-printable 反而。您不能真正可靠地发送完全未编码的内容(尽管如果您愿意,MIME 8bit
或 binary
编码将能够适应这种情况;但为了向后兼容,SMTP 要求对所有内容进行编码转换为 7 位表示法)。
在旧的 email
库中,需要各种技巧才能做到这一点,但在 Python 3.6 中引入的新 EmailMessage
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
不幸的是,从文档中弄清楚这一点几乎是不可能的。 The documentation for set_content
basically just defers to the policy
which obscurely points to the raw_data_manager
(如果您甚至注意到 link)...最终您希望注意到 cte
关键字参数的存在。
(顺便说一句,您可能还想
replace('\n ', '\n')
在 body 文本中。)
如果你选择 8bit
或 binary
内容传输编码,它们之间的区别在于前者有行长度限制(最多 900 个字符),而后者完全是无拘无束。但是您需要确保整个 SMTP 传输路径是 8 位干净的(此时您不妨完全转向 Unicode email / ESMTP SMTPUTF8
)。
为了您的娱乐,这里有一些关于 crazy hacks for Python 3.5 and earlier.
的老问题
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:
header;它将此标识为 MIME 消息。
From:
header 确实应该是 RFC2047 编码的,文档表明它将是“当消息被序列化时”。当你 print(msg)
你没有正确序列化它;你想要 print(msg.as_string())
确实展示了所需的序列化。
当谈到传输编码时,Python 的 email
库对使用 base64
的内容没有吸引力,这些内容很可能被编码为 quoted-printable 反而。您不能真正可靠地发送完全未编码的内容(尽管如果您愿意,MIME 8bit
或 binary
编码将能够适应这种情况;但为了向后兼容,SMTP 要求对所有内容进行编码转换为 7 位表示法)。
在旧的 email
库中,需要各种技巧才能做到这一点,但在 Python 3.6 中引入的新 EmailMessage
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
不幸的是,从文档中弄清楚这一点几乎是不可能的。 The documentation for set_content
basically just defers to the policy
which obscurely points to the raw_data_manager
(如果您甚至注意到 link)...最终您希望注意到 cte
关键字参数的存在。
(顺便说一句,您可能还想
replace('\n ', '\n')
在 body 文本中。)
如果你选择 8bit
或 binary
内容传输编码,它们之间的区别在于前者有行长度限制(最多 900 个字符),而后者完全是无拘无束。但是您需要确保整个 SMTP 传输路径是 8 位干净的(此时您不妨完全转向 Unicode email / ESMTP SMTPUTF8
)。
为了您的娱乐,这里有一些关于 crazy hacks for Python 3.5 and earlier.
的老问题