Я недавно столкнулся с файлом EML, который я хотел проанализировать с модулем электронной почты Python.В заголовке from
был следующий текст:
From: "=?utf-8?b?5b2t5Lul5Zu9L+esrOS6jOS6i+S4mumDqOmhueebrumDqC/nrKzkuozkuovkuJrp?=
=?utf-8?b?g6g=?=" <email@address.com>
Таким образом, имя закодировано в 2 частях.Когда я объединяю код и декодирую его вручную в шестнадцатеричный формат, я получаю следующий результат, который является правильной строкой UTF-8:
e5 bd ad e4 bb a5 e5 9b bd 2f e7 ac ac e4 ba 8c e4 ba 8b e4 b8 9a e9 83 a8 e9 a1 b9 e7 9b ae e9 83 a8 2f e7 ac ac e4 ba 8c e4 ba 8b e4 b8 9a e9 83 a8
Однако, когда я вызываю анализатор электронной почты Python parse
, последний3 байта не декодируются правильно.Вместо этого, когда я читаю значения message['from']
, появляются суррогаты:
dce9:20:dc83:dca8
Поэтому, когда я, например, хочу напечатать строку, она заканчивается на
UnicodeEncodeError('utf-8', '彭以国/第二事业部项目部/第二事业\udce9\udc83\udca8', 17, 18, 'surrogates not allowed')
Когда я соединяю 2 закодированных части в заголовке From
в одну, которая выглядит следующим образом:
From: "=?utf-8?b?5b2t5Lul5Zu9L+esrOS6jOS6i+S4mumDqOmhueebrumDqC/nrKzkuozkuovkuJrpg6g=?=" <email@address.com>
Строка правильно декодируется библиотекой и может быть напечатана очень хорошо.
Это ошибка внутри почтового модуля Python?Допустимо ли двойное кодированное значение даже в стандарте EML?
Вот пример файла EML + код Python для воспроизведения неправильного декодирования (на самом деле это не вызывает исключения, что происходит позже, т. Е. С невозможностью SQLAlchemyзакодировать строку обратно в UTF-8)
EML:
Content-Type: multipart/mixed; boundary="===============2193163039290138103=="
MIME-Version: 1.0
Date: Wed, 25 Aug 2018 19:21:23 +0100
From: "=?utf-8?b?5b2t5Lul5Zu9L+esrOS6jOS6i+S4mumDqOmhueebrumDqC/nrKzkuozkuovkuJrp?=
=?utf-8?b?g6g=?=" <addr@addr.com>
Message-Id: <12312924463694945698.525C0AC435BA7D0E@xxxxx.com>
Subject: Sample subject
To: addr@addr.com
--===============2193163039290138103==
MIME-Version: 1.0
Content-Type: text/plain; charset="utf-8"
Content-Transfer-Encoding: base64
VGhpcyBpcyBhIHNhbXBsZSB0ZXh0
--===============2193163039290138103==--
Код Python:
from email.parser import Parser
from email import policy
from sys import argv
with open(argv[1], 'r', encoding='utf-8') as eml_file:
msg = Parser(policy=policy.default).parse(eml_file)
print(msg['from'])
Результат:
彭 以 国 / 第10 事业 部 项目 部 / 第二 事业 � ��