1

電子メール パーサーを使用して shift_jis でエンコードされた電子メールをデコードして Unicode に変換しようとすると、「UnicodeDecodeError: 'shift_jis' コーデックは位置 2-3 のバイトをデコードできません: 不正なマルチバイト シーケンス」というエラーが表示されます。コードと電子メールは以下にあります。

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 のエンコード方法の違いに関連している可能性があるという別のスタック オーバーフローの質問を読みました (このマイクロソフト サポート技術情報の記事を参照しました)。私のコードの何が原因で動作しないのか誰かが知っている場合、またはこれが合理的に修正可能である場合でも、その方法を見つけていただければ幸いです。

4

1 に答える 1

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 の回答を読むと、文字列の末尾に「?=」を追加してみることになりました。

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

グーグル翻訳によると、これは「あなたは非常に重要なものがあることを知っています」と訳されるかもしれません。

そのため、件名が切り捨てられているようです。

于 2011-03-31T20:48:21.027 に答える