2011-03-31 48 views
1

当我尝试使用“UnicodeDecodeError:'shift_jis'编解码器无法解码位置2-3中的字节:非法多字节序列”时,出现错误我的电子邮件解析器解码一个shift_jis编码的电子邮件并将其转换为unicode。该代码和电子邮件可以发现如下:当编码位于shift_jis中时,使用Python的电子邮件模块解析电子邮件时出错

import email.header 
import base64 
import sys 
import email 

def getrawemail(): 
    line = ' ' 
    raw_email = '' 
    while line: 
     line = sys.stdin.readline() 
     raw_email += line 
    return raw_email 

def getheader(subject, charsets): 
    for i in charsets: 
     if isinstance(i, str): 
      encoding = i 
      break 
    if subject[-2] == "?=": 
     encoded = subject[5 + len(encoding):len(subject) - 2] 
    else: 
     encoded = subject[5 + len(encoding):] 
    return (encoding, encoded) 

def decodeheader((encoding, encoded)): 
    decoded = base64.b64decode(encoded) 
    decoded = unicode(decoded, encoding) 
    return decoded 

raw_email = getrawemail() 
msg = email.message_from_string(raw_email) 
subject = decodeheader(getheader(msg["Subject"], msg.get_charsets())) 
print subject 

电子邮件:http://pastebin.com/L4jAkm5R

我已经在另一个堆栈溢出问题,这可能与之间的Unicode和shift_jis访问是如何编码的差异看(他们引用this Microsoft知识库文章)。如果有人知道我的代码中有什么可能导致它无法工作,或者如果这是可以合理解决的,我将非常感激发现如何。

回答

1

以该字符串开始:

In [124]: msg['Subject'] 
Out[124]: '=?ISO-2022-JP?B?GyRCNS5KfSRLJEgkRiRiQmdAWiRKJCpDTiRpJDskLCQiJGo' 

=?ISO-2022-JP?B?表示字符串是ISO-2022-JP编码,则base64编码。

In [125]: msg['Subject'].lstrip('=?ISO-2022-JP?B?') 
Out[125]: 'GyRCNS5KfSRLJEgkRiRiQmdAWiRKJCpDTiRpJDskLCQiJGo' 

不幸的是,试图扭转一个错误,处理结果:

In [126]: base64.b64decode(msg['Subject'].lstrip('=?ISO-2022-JP?B?')) 
TypeError: Incorrect padding 

阅读本SO answer导致我尝试添加到字符串的结尾 '=?':

In [130]: print(base64.b64decode(msg['Subject'].lstrip('=?ISO-2022-JP?B?')+'?=').decode('ISO-2022-JP')) 
貴方にとても大切なお知らせがあり 

根据谷歌翻译,这可能会被翻译为“你知道有一个非常重要的”。

所以看来主题行已被截断。