Ошибка синтаксического анализа писем с использованием модуля электронной почты Python, когда кодировка находится в shift_jis - PullRequest
1 голос
/ 31 марта 2011

Я получаю сообщение об ошибке «UnicodeDecodeError: кодек« shift_jis »не может декодировать байты в позиции 2-3: недопустимая многобайтовая последовательность», когда я пытаюсь использовать свой анализатор электронной почты для декодирования закодированной электронной почты shift_jis и преобразования ее в юникода. Код и адрес электронной почты можно найти ниже:

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

E-mail: http://pastebin.com/L4jAkm5R

Я прочитал другой вопрос о переполнении стека, что это может быть связано с разницей между тем, как кодируются Unicode и shift_jis (они ссылаются на эту статью базы знаний Майкрософт). Если кто-то знает, что в моем коде может не работать или если это даже можно исправить, я был бы очень признателен, если бы узнал, как это сделать.

1 Ответ

1 голос
/ 01 апреля 2011

Начиная с этой строки:

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

В соответствии с Google Translate, это может быть переведено как «Вы знаете, что это очень важно».

Похоже, тема была обрезана.

...