我试图用Python处理旧的、可能不合规的电子邮件。我可以毫无疑问地在留言中读到:
In [1]: m=email.message_from_binary_file(open('/path/to/problematic:2,S',mode='rb'))
但随后将其转换为字符串时会出现UnicodeEncodeError:“gb2312”编解码器无法对1238位置的字符“\ufffd”进行编码:非法的多字节序列。这个有问题的消息的(多)部分有“Content Type:text/plain;charset=”gb2312“和“Content Transfer Encoding:8bit”。在
^{pr2}$我不太熟悉电子邮件内部的特性,在网上搜索这种类型的错误时发现的主要问题是在抓取网页时,基本上有点明显的建议:读入的原始字节包含无法用目标编解码器编码的Unicode字符。在
我的问题是:什么是正确的方法来可靠地处理(可能不符合)电子邮件?在
编辑
有趣的是,m.get_payload(i=0).as_string()
会触发相同的异常,但是m.get_payload(i=0).get_payload(decode=False)
给出了在我的终端上正确显示的str
,而{bytes
(b'\xd7\xaa...'
)。但是,错误发生在不同的字符上:
----> 1 m.get_payload(i=0).get_payload(decode=True).decode('gb2312')
UnicodeDecodeError: 'gb2312' codec can't decode byte 0xac in position 1995: illegal multibyte sequence
或者
----> 1 m.get_payload(i=0).get_payload(decode=True).decode('gb18030')
UnicodeDecodeError: 'gb18030' codec can't decode byte 0xa3 in position 2033: illegal multibyte sequence
简短的答案通常是error handlers在您的
bytes.decode
调用中。但细节取决于很多事情。在首先,你想如何处理这些数据?通常你需要一些绝对可逆的东西,所以你可以保证在最坏的情况下你可以重新生成你所接受的东西,在这种情况下你可能想要
surrogate-escape
。在其他情况下,你想生成一些人类可读的东西,最好跳过不可能的mojibake,而不是试图呈现它,因此ignore
可能是正确的答案。等等。在第二,这是一个绝大多数消息都是好消息,但有少数消息是错误的,还是许多消息大多数都很好但有一些错误?在
最后,在某些情况下(对于传统的中文编码尤其如此),实际问题只是有人指定了一个密切相关的字符集,而不是他们实际使用的字符集。如果您看到的是这种情况,您可能需要尝试编写显式的后备代码:如果您遇到异常,请在常见错误的dict中查找编码,然后尝试其他编码。如果它们都不起作用,则返回到使用错误处理程序的特定编码。在
显然,如果}时才会发生。在
Content-Transfer-Encoding
是8bit
,message.get_payload(decode=False)
仍将尝试解码以恢复原始字节。另一方面,message.get_payload(decode=True)
总是产生bytes
,尽管实际解码只有在Content-Transfer-Encoding
存在并且是quoted-printable
或{最后我得到了以下代码。不确定这是否是处理电子邮件的正确方法。在
相关问题 更多 >
编程相关推荐