Как разобрать почту FROM заголовки с круглыми скобками в Python? - PullRequest
0 голосов
/ 19 декабря 2018

У меня проблемы с использованием модуля Python email для анализа электронных писем, в которых заголовок FROM содержит круглые скобки.Это только кажется проблемой при использовании email.policy.default в отличие от email.policy.compat32.

Есть ли решение этой проблемы, кроме политики переключения?

Ниже приведен минимальный рабочий пример, для Python 3.6.5:

import email
import email.policy as email_policy

raw_mime_msg=b"from: James Mishra \\(says hi\\) <james@example.com>"

compat32_obj = email.message_from_bytes(
    raw_mime_msg, policy=email_policy.compat32)

default_obj = email.message_from_bytes(
    raw_mime_msg, policy=email_policy.default)

print(compat32_obj['from'])
print(default_obj['from'])

Первый оператор печати возвращает: James Mishra \(says hi\) <james@example.com> , а второй оператор печати возвращает:

Traceback (most recent call last):
  File "/usr/local/lib/python3.6/email/_header_value_parser.py", line 1908, in get_address
    token, value = get_group(value)
  File "/usr/local/lib/python3.6/email/_header_value_parser.py", line 1867, in get_group
    "display name but found '{}'".format(value))
email.errors.HeaderParseError: expected ':' at end of group display name but found '\(says hi\) <james@example.com>'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/local/lib/python3.6/email/_header_value_parser.py", line 1734, in get_mailbox
    token, value = get_name_addr(value)
  File "/usr/local/lib/python3.6/email/_header_value_parser.py", line 1720, in get_name_addr
    token, value = get_angle_addr(value)
  File "/usr/local/lib/python3.6/email/_header_value_parser.py", line 1646, in get_angle_addr
    "expected angle-addr but found '{}'".format(value))
email.errors.HeaderParseError: expected angle-addr but found '\(says hi\) <james@example.com>'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "test_email.py", line 12, in <module>
    print(default_obj['from'])
  File "/usr/local/lib/python3.6/email/message.py", line 391, in __getitem__
    return self.get(name)
  File "/usr/local/lib/python3.6/email/message.py", line 471, in get
    return self.policy.header_fetch_parse(k, v)
  File "/usr/local/lib/python3.6/email/policy.py", line 162, in header_fetch_parse
    return self.header_factory(name, value)
  File "/usr/local/lib/python3.6/email/headerregistry.py", line 589, in __call__
    return self[name](name, value)
  File "/usr/local/lib/python3.6/email/headerregistry.py", line 197, in __new__
    cls.parse(value, kwds)
  File "/usr/local/lib/python3.6/email/headerregistry.py", line 340, in parse
    kwds['parse_tree'] = address_list = cls.value_parser(value)
  File "/usr/local/lib/python3.6/email/headerregistry.py", line 331, in value_parser
    address_list, value = parser.get_address_list(value)
  File "/usr/local/lib/python3.6/email/_header_value_parser.py", line 1931, in get_address_list
    token, value = get_address(value)
  File "/usr/local/lib/python3.6/email/_header_value_parser.py", line 1911, in get_address
    token, value = get_mailbox(value)
  File "/usr/local/lib/python3.6/email/_header_value_parser.py", line 1737, in get_mailbox
    token, value = get_addr_spec(value)
  File "/usr/local/lib/python3.6/email/_header_value_parser.py", line 1583, in get_addr_spec
    token, value = get_local_part(value)
  File "/usr/local/lib/python3.6/email/_header_value_parser.py", line 1413, in get_local_part
    obs_local_part, value = get_obs_local_part(str(local_part) + value)
  File "/usr/local/lib/python3.6/email/_header_value_parser.py", line 1454, in get_obs_local_part
    token, value = get_word(value)
  File "/usr/local/lib/python3.6/email/_header_value_parser.py", line 1340, in get_word
    if value[0]=='"':
IndexError: string index out of range

1 Ответ

0 голосов
/ 19 декабря 2018

email.policy.default предназначен для соответствия RFC электронной почты, а ваше сообщение не соответствует RFC 5322 .Если часть в скобках должна быть комментарием, то сообщение должно выглядеть как

raw_mime_msg=b"from: James Mishra (says hi) <james@example.com>"

, чтобы соответствовать.Если это не должен быть комментарий, тогда скобки должны появляться внутри строки в кавычках.Это может выглядеть примерно так:

raw_mime_msg=b'from: "James Mishra (says hi)" <james@example.com>'

Поскольку ваше сообщение не соответствует требованиям, использование политики, которая ожидает соответствия, плохо подходит.Если вы хотите обрабатывать несоответствующие сообщения, email.policy.compat32 - лучший выбор, чем email.policy.default.

...