Python3:如何发送包含二进制数据的电子邮件消息?

5
以下代码执行失败:

这里是相关文档。

>>> a = email.message.Message()
>>> a.set_payload(b'some data')
>>> a.as_string()
TypeError: string payload expected: <class 'bytes'>

它甚至无法使用生成器显式地调用flatten。消息正文被转换为ASCII码,然后应用转义,最后再将其转换为字节以进行传输,那么我为什么不能设置字节有效载荷呢?
如何获取首选非MIME消息并带有字节有效载荷,以便smtplib.SMTP.send_message可以接受?

1
你可能需要将它编码为字符串。我不知道Python中有什么可用的方法,但通常会使用Base-64编码。 - Jeff Mercado
1
无论你如何操作,如果你能够这样做,非ASCII码、非MIME类型的邮件在接收端和任何中间邮件传输代理上都会出现问题。所谓的“问题”指的是“难以解释”、“被退回”或“被丢弃”。 - msw
1
@msw - 该死的还只支持ASCII编码的邮件代理!:) - mac
相反,消息首先会被转换为 ASCII 码,而不管发送方。我不明白为什么要为我的字节选择一个随机的字符串编码,只是为了后来再次被编码为 ASCII 码(当然,最后还要再次转换为字节 -.-)。 - Matt Joiner
为什么不使用双字节填充并将其转换为Unicode(或选择您喜欢的奇特编码)?然后在另一端,您可以将Unicode字符串转换为字节。我仍然建议使用MIME解决方案,即使只是因为库可以帮助您并且它是标准,但转换为字符串可能有效。 - 101100
1个回答

1

记住:在Python 3中,字符串是全部unicode。实际上,您正在向Python提供一个字节对象,然后告诉它您想要一个Unicode字符串,但没有告诉它使用哪种编码将字节对象转换为字符串。

您需要做的是在set_payload()调用的第二个参数中提供编码,如下所示:

test = email.message.Message()
test.set_payload(b'some example_data', 'latin1') # use latin-1 for no-op translation
test.as_string()

'MIME-Version: 1.0\nContent-Type: text/plain; charset="latin1"\nContent-Transfer-Encoding: base64\n\nc29tZSBleGFtcGxlIGRhdGE=\n'

这会返回一个 MIME 类型的消息 -- 希望对你有用。


你能解释一下为什么选择使用latin1编码吗? - Matt Joiner
latin1和unicode在前256个字符上是相同的,因此在“解码”过程中字节不会被更改。 - Ethan Furman

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接