email.parser: Разбор сообщений электронной почты

Исходный код: Lib/email/parser.py.


Структуры объектов сообщений могут быть созданы одним из двух способов: они могут быть созданы «с чистого листа» путем создания объекта EmailMessage, добавления заголовков с помощью интерфейса словаря и добавления полезной нагрузки с помощью set_content() и связанных методов, или они могут быть созданы путем разбора сериализованного представления почтового сообщения.

Пакет email предоставляет стандартный синтаксический анализатор, который понимает большинство структур почтовых документов, включая документы MIME. Вы можете передать парсеру байтовый, строковый или файловый объект, и парсер вернет вам корневой EmailMessage экземпляр структуры объекта. Для простых, не MIME-сообщений полезной нагрузкой этого корневого объекта, скорее всего, будет строка, содержащая текст сообщения. Для сообщений MIME корневой объект вернет True из своего метода is_multipart(), а доступ к подчасти можно получить с помощью методов манипулирования полезной нагрузкой, таких как get_body(), iter_parts() и walk().

На самом деле существует два интерфейса парсера, доступных для использования: API Parser и инкрементный API FeedParser. API Parser наиболее полезен, если весь текст сообщения находится в памяти, или если все сообщение находится в файле на файловой системе. FeedParser более уместен, когда вы читаете сообщение из потока, который может заблокироваться в ожидании дополнительного ввода (например, чтение сообщения электронной почты из сокета). FeedParser может потреблять и разбирать сообщение инкрементально, и возвращает корневой объект только после закрытия анализатора.

Обратите внимание, что парсер может быть расширен ограниченными способами, и, конечно, вы можете реализовать свой собственный парсер полностью с нуля. Вся логика, связывающая парсер пакета email и класс EmailMessage, воплощена в классе policy, поэтому пользовательский парсер может создавать деревья объектов сообщений любым способом, который он считает необходимым, реализуя пользовательские версии соответствующих методов policy.

API FeedParser

Модуль BytesFeedParser, импортированный из модуля email.feedparser, предоставляет API, способствующий постепенному разбору сообщений электронной почты, например, при чтении текста сообщения электронной почты из источника, который может блокироваться (например, сокета). Конечно, BytesFeedParser можно использовать для разбора сообщения электронной почты, полностью содержащегося в bytes-like object, строке или файле, но API BytesParser может быть более удобным для таких случаев. Семантика и результаты работы двух API парсеров идентичны.

API BytesFeedParser прост: вы создаете экземпляр, передаете ему кучу байтов, пока больше не останется, затем закрываете парсер, чтобы получить корневой объект сообщения. BytesFeedParser чрезвычайно точен при разборе сообщений, соответствующих стандартам, и очень хорошо справляется с разбором сообщений, не соответствующих стандартам, предоставляя информацию о том, как сообщение было признано нарушенным. Он заполнит атрибут defects объекта сообщения списком всех проблем, которые он обнаружил в сообщении. Список дефектов, которые он может найти, см. в модуле email.errors.

Вот API для BytesFeedParser:

class email.parser.BytesFeedParser(_factory=None, *, policy=policy.compat32)

Создать экземпляр BytesFeedParser. Необязательная _factory является вызываемой переменной без аргументов; если она не указана, используйте message_factory из policy. Вызывайте _factory всякий раз, когда требуется новый объект сообщения.

Если указана policy, используйте указанные в ней правила для обновления представления сообщения. Если policy не задана, используйте политику compat32, которая поддерживает обратную совместимость с версией пакета электронной почты Python 3.2 и предоставляет Message в качестве фабрики по умолчанию. Все остальные политики предоставляют EmailMessage в качестве _фабрики по умолчанию. Для получения дополнительной информации о том, чем еще управляет policy, смотрите документацию policy.

Примечание: Ключевое слово policy всегда должно быть указано; В будущей версии Python значение по умолчанию будет изменено на email.policy.default.

Добавлено в версии 3.2.

Изменено в версии 3.3: Добавлено ключевое слово policy.

Изменено в версии 3.6: _factory по умолчанию устанавливает политику message_factory.

feed(data)

Передайте синтаксическому анализатору дополнительные данные. данные должны быть bytes-like object, содержащим одну или несколько строк. Строки могут быть неполными, и синтаксический анализатор будет правильно сшивать такие неполные строки вместе. Строки могут иметь любое из трех обычных окончаний: возврат каретки, новая строка или возврат каретки и новая строка (они могут быть даже смешанными).

close()

Завершить разбор всех ранее переданных данных и вернуть объект корневого сообщения. Не определено, что произойдет, если feed() будет вызван после вызова этого метода.

class email.parser.FeedParser(_factory=None, *, policy=policy.compat32)

Работает как BytesFeedParser, за исключением того, что входные данные для метода feed() должны быть строкой. Это имеет ограниченное применение, поскольку единственным способом сделать такое сообщение действительным является то, что оно содержит только текст ASCII или, если utf8 является True, без двоичных вложений.

Изменено в версии 3.3: Добавлено ключевое слово policy.

API парсера

Класс BytesParser, импортированный из модуля email.parser, предоставляет API, который можно использовать для разбора сообщения, когда полное содержимое сообщения доступно в bytes-like object или файле. Модуль email.parser также предоставляет Parser для разбора строк и анализаторы только заголовков, BytesHeaderParser и HeaderParser, которые можно использовать, если вас интересуют только заголовки сообщения. BytesHeaderParser и HeaderParser могут быть намного быстрее в таких ситуациях, поскольку они не пытаются разобрать тело сообщения, вместо этого устанавливая полезную нагрузку в необработанное тело.

class email.parser.BytesParser(_class=None, *, policy=policy.compat32)

Создайте экземпляр BytesParser. Аргументы _class и policy имеют то же значение и семантику, что и аргументы _factory и policy в BytesFeedParser.

Примечание: Ключевое слово policy всегда должно быть указано; В будущей версии Python значение по умолчанию будет изменено на email.policy.default.

Изменено в версии 3.3: Удален аргумент strict, который был устаревшим в версии 2.4. Добавлено ключевое слово policy.

Изменено в версии 3.6: _class по умолчанию устанавливает политику message_factory.

parse(fp, headersonly=False)

Прочитайте все данные из двоичного файлоподобного объекта fp, разберите полученные байты и верните объект сообщения. fp должен поддерживать оба метода readline() и read().

Байты, содержащиеся в fp, должны быть отформатированы как блок заголовков и продолжений заголовков в стиле RFC 5322 (или, если utf8 равно True, RFC 6532), опционально предваряемый заголовком конверта. Блок заголовков завершается либо концом данных, либо пустой строкой. За блоком заголовков следует тело сообщения (которое может содержать подчасти в MIME-кодировке, включая подчасти с Content-Transfer-Encoding из 8bit).

Необязательный headersonly - это флаг, указывающий, следует ли прекратить разбор после чтения заголовков или нет. По умолчанию стоит False, что означает, что будет разобрано все содержимое файла.

parsebytes(bytes, headersonly=False)

Аналогичен методу parse(), только вместо файлоподобного объекта принимает bytes-like object. Вызов этого метода на bytes-like object эквивалентен тому, чтобы сначала завернуть байты в экземпляр BytesIO и вызвать parse().

Необязательный headersonly - как в методе parse().

Добавлено в версии 3.2.

class email.parser.BytesHeaderParser(_class=None, *, policy=policy.compat32)

Точно так же, как BytesParser, за исключением того, что headersonly по умолчанию имеет значение True.

Добавлено в версии 3.3.

class email.parser.Parser(_class=None, *, policy=policy.compat32)

Этот класс параллелен классу BytesParser, но работает со строковым вводом.

Изменено в версии 3.3: Удален аргумент strict. Добавлено ключевое слово policy.

Изменено в версии 3.6: _class по умолчанию устанавливает политику message_factory.

parse(fp, headersonly=False)

Прочитайте все данные из файлоподобного объекта fp в текстовом режиме, разберите полученный текст и верните корневой объект сообщения. fp должен поддерживать оба метода readline() и read() на файлоподобных объектах.

За исключением требования текстового режима, этот метод работает аналогично BytesParser.parse().

parsestr(text, headersonly=False)

Аналогичен методу parse(), только вместо файлоподобного объекта принимает строковый объект. Вызов этого метода для строки эквивалентен обертыванию текста в экземпляр StringIO и вызову parse().

Необязательный headersonly - как в методе parse().

class email.parser.HeaderParser(_class=None, *, policy=policy.compat32)

Точно так же, как Parser, за исключением того, что headersonly по умолчанию имеет значение True.

Поскольку создание структуры объекта сообщения из строки или объекта файла является такой распространенной задачей, для удобства предоставлены четыре функции. Они доступны в пространстве имен верхнего уровня пакета email.

email.message_from_bytes(s, _class=None, *, policy=policy.compat32)

Возвращает структуру объекта сообщения из bytes-like object. Это эквивалентно BytesParser().parsebytes(s). Необязательные _class и policy интерпретируются как в конструкторе класса BytesParser.

Добавлено в версии 3.2.

Изменено в версии 3.3: Удален аргумент strict. Добавлено ключевое слово policy.

email.message_from_binary_file(fp, _class=None, *, policy=policy.compat32)

Возвращает дерево структуры объектов сообщений из открытого двоичного файла file object. Это эквивалентно BytesParser().parse(fp). _class и policy интерпретируются как в конструкторе класса BytesParser.

Добавлено в версии 3.2.

Изменено в версии 3.3: Удален аргумент strict. Добавлено ключевое слово policy.

email.message_from_string(s, _class=None, *, policy=policy.compat32)

Возвращает структуру объекта сообщения из строки. Это эквивалентно Parser().parsestr(s). _class и policy интерпретируются как в конструкторе класса Parser.

Изменено в версии 3.3: Удален аргумент strict. Добавлено ключевое слово policy.

email.message_from_file(fp, _class=None, *, policy=policy.compat32)

Возвращает дерево структуры объектов сообщений из открытого file object. Это эквивалентно Parser().parse(fp). _class и policy интерпретируются как в конструкторе класса Parser.

Изменено в версии 3.3: Удален аргумент strict. Добавлено ключевое слово policy.

Изменено в версии 3.6: _class по умолчанию устанавливает политику message_factory.

Вот пример того, как можно использовать message_from_bytes() в интерактивном приглашении Python:

>>> import email
>>> msg = email.message_from_bytes(myBytes)  

Дополнительные примечания

Вот некоторые замечания по семантике синтаксического анализа:

  • Большинство несообщений типа multipart анализируются как один объект сообщения со строковой полезной нагрузкой. Эти объекты вернут False для is_multipart(), а iter_parts() даст пустой список.

  • Все сообщения типа multipart будут разобраны как объект контейнерного сообщения со списком объектов подсообщений для их полезной нагрузки. Внешнее контейнерное сообщение вернет True для is_multipart(), а iter_parts() даст список вложенных частей.

  • Большинство сообщений с типом содержимого message/* (такие как message/delivery-status и message/rfc822) также будут разобраны как объект-контейнер, содержащий список полезной нагрузки длины 1. Их метод is_multipart() вернет True. Единственный элемент, выдаваемый методом iter_parts(), будет объектом под-сообщения.

  • Некоторые сообщения, не соответствующие стандартам, могут быть внутренне несогласованными относительно их multipart-едности. Такие сообщения могут иметь заголовок Content-Type типа multipart, но их метод is_multipart() может возвращать False. Если такие сообщения были разобраны с помощью FeedParser, они будут иметь экземпляр класса MultipartInvariantViolationDefect в списке атрибутов defects. Подробности см. в email.errors.

Вернуться на верх