Python解析中文电子邮件解码错误
我编写了一些Python代码来从Gmail服务器获取电子邮件。以下是代码:Python解析中文电子邮件解码错误,python,decode,Python,Decode,我编写了一些Python代码来从Gmail服务器获取电子邮件。以下是代码: self.M = imaplib.IMAP4_SSL(self.IMAP_SERVER, self.IMAP_PORT) data = self.M.fetch(id,"(RFC822)") if data[0] == 'OK': msg = email.message_from_string(data[1][0][1]) else: print 'Error!' mail_subject = email
self.M = imaplib.IMAP4_SSL(self.IMAP_SERVER, self.IMAP_PORT)
data = self.M.fetch(id,"(RFC822)")
if data[0] == 'OK':
msg = email.message_from_string(data[1][0][1])
else:
print 'Error!'
mail_subject = email.Header.decode_header(msg['subject'])[0][0]
print email.Header.decode_header(msg['subject'])
print '~~~separator~~~'
print mail_subject
正确显示英文邮件主题:
[('[bonnshore.github.com] Page build successful', None)]
~~~separator~~~
[bonnshore.github.com] Page build successful
但在中文之后:
[('\xd5\xe2\xca\xc7\xd6\xd0\xce\xc4\xb2\xe2\xca\xd4\xa3\xa1', 'gb2312')]
~~~separator~~~
╒Γ╩╟╓╨╬─▓Γ╩╘úí
函数isinstance()显示字符类型为'str',
所以我试着解决这个问题:
print unicode(mail_subject, 'gb2312')
并发生错误:
File "C:\Python27\lib\encodings\cp437.py", line 12, in encode
return codecs.charmap_encode(input,errors,encoding_map)
UnicodeEncodeError: 'charmap' codec can't encode characters in position 0-6:
character maps to <undefined>
我又犯了同样的错误
那么,如何解决这个问题呢
非常感谢!:) 您的第一次尝试显示为,因为您正在将原始gb2312打印到非gb2312控制台
decode_header
执行作业的第一部分,即将看起来像=?iso-8859-1?q?p=F6stal?=
的头转换为可以向用户显示的内容。由于同一个头可以包含多个字符集,因此您得到的是(raw_data
,charset
)对的列表
您应该使用Unicode构造函数将它们转换为Unicode,然后再转换为UTF-8或任何适合您需要的格式,正如您正确猜测的那样。但第二次尝试失败,因为代码页437无法显示中文。第三个问题来自对解码
和编码
工作方向的误解。unicode字符串被“编码”为外部编码。(但即使成功了,您仍然可以回到原来的mojibake,即在终端上打印gb2312。)
要测试结果,您需要正确创建Unicode字符串并进行检查,或者使用正确的编码将其打印到文件中。例如:
>>> x = unicode('\xd5\xe2\xca\xc7\xd6\xd0\xce\xc4\xb2\xe2\xca\xd4\xa3\xa1', 'gb2312')
>>> import unicodedata
>>> map(unicodedata.name, x) # see if it looks chinese
['CJK UNIFIED IDEOGRAPH-8FD9', 'CJK UNIFIED IDEOGRAPH-662F', 'CJK UNIFIED IDEOGRAPH-4E2D', 'CJK UNIFIED IDEOGRAPH-6587', 'CJK UNIFIED IDEOGRAPH-6D4B', 'CJK UNIFIED IDEOGRAPH-8BD5', 'FULLWIDTH EXCLAMATION MARK']
>>> print x # this works for me because I'm in a UTF-8 locale
这是中文测试!
您可以这样做来测试它是否适合您:
>>> with open('file.txt', 'w') as f:
... f.write(x.encode('utf-8'))
最后,请注意,通过decode_header
获取第一个返回项不足以获取报头的全部值,因为它可以分为几个块。您需要将块连接到单个Unicode字符串中,这最好通过组合make_header
实用程序函数和Unicode
构造函数来实现:
subject_header = msg['subject']
subject = unicode(email.header.make_header(email.header.decode_header(subject_header))
# now proceed as before...
必须调用
make_header
和decode_header
,这是违反直觉的,但这是当前的API。您确定数据实际上是在gb2312
中编码的吗?decode_header返回一个元组(包括实际使用的编码)是有原因的;)@bonn我刚刚发现,标题
支持unicode构造函数,所以您只需键入subject=unicode(msg['subject'])
即可将主题正确解码为unicode。@4815162342我稍后将尝试此解决方案,我猜也没问题……而且您在回答中提到的终端编码错误完全正确,因此我将编码格式更改为支持utf-8,现在我可以使用email.Header.decode_Header(subject)[0][0]
获得正确的电子邮件主题,该主题是用中文键入的。@bonndecode_Header(subject)[0][0])
很简单,但不正确。首先,它只会给出标题的第一部分(可以由几个部分组成)。其次,它将为您提供原始头中使用的任何字符集中的原始数据,而不是UTF-8。要获得UTF-8的完整主题,请使用unicode(主题)。encode(“UTF-8”)@4815162342您所说的第一个理由让我信服,但第二个理由不起作用。我得到了类似于=?utf-8?B…Hkv6E=?=
,当使用unicode(msg['subject'])
或unicode(msg['subject'])时。encode(“utf-8”)
@bonn你是对的,它不能按预期工作。似乎email.header.header.\uuuuuUnicode\uuuuuu
不会尝试解码头。现在,我已经用一个正确调用的示例更新了答案。
subject_header = msg['subject']
subject = unicode(email.header.make_header(email.header.decode_header(subject_header))
# now proceed as before...