2011-03-31 50 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')) 
貴方にとても大切なお知らせがあり 

根據谷歌翻譯,這可能會被翻譯爲「你知道有一個非常重要的」。

所以看來主題行已被截斷。