Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/291.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python解析中文电子邮件解码错误_Python_Decode - Fatal编程技术网

Python解析中文电子邮件解码错误

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

我编写了一些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.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]
获得正确的电子邮件主题,该主题是用中文键入的。@bonn
decode_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...