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 конечно же, может использоваться для разбора сообщения электронной почты, полностью содержащегося в объекте типа байты, строке или файле, но 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, которая обеспечивает обратную совместимость с версией пакета email Python 3.2 и предоставляетMessageв качестве значения по умолчанию для factory. Все остальные политики предоставляютEmailMessageв качестве значения по умолчанию для _factory. Для получения дополнительной информации о том, что ещё контролирует policy, см. документациюpolicy.Примечание: ключевое слово policy всегда должно быть указано; значение по умолчанию будет изменено на
email.policy.defaultв будущей версии Python.Новое в версии 3.2.
Изменено в версии 3.3: Добавлено ключевое слово policy.
Изменено в версии 3.6: _factory по умолчанию равно политике
message_factory.-
feed(data) -
Передать парсеру дополнительные данные. data должен быть объектом типа байты, содержащим одну или несколько строк. Строки могут быть неполными, и парсер будет правильно соединять такие неполные строки. Строки могут иметь любой из трёх распространённых символов конца строки: возврат каретки, новая строка или возврат каретки и новая строка (они могут даже быть смешаны).
-
close() -
Завершить разбор всех ранее переданных данных и вернуть корневой объект сообщения. Не определено, что произойдёт, если
feed()будет вызван после вызова этого метода.
-
-
class email.parser.FeedParser(_factory=None, *, policy=policy.compat32) -
Действует как
BytesFeedParser, за исключением того, что вход для методаfeed()должен быть строкой. Это имеет ограниченное применение, так как единственный способ для такого сообщения быть корректным — это содержать только текст ASCII или, еслиutf8—True, никаких бинарных вложений.Изменено в версии 3.3: Добавлено ключевое слово policy.
API Parser
Класс BytesParser, импортированный из модуля email.parser, предоставляет API, который можно использовать для разбора сообщения, когда всё содержимое сообщения доступно в виде объекта типа bytes или файла. Модуль email.parser также предоставляет класс Parser для разбора строк и парсеры только для заголовков, BytesHeaderParser и HeaderParser, которые можно использовать, если вас интересуют только заголовки сообщения. BytesHeaderParser и HeaderParser могут быть значительно быстрее в таких ситуациях, так как они не пытаются разобрать тело сообщения, вместо этого устанавливая содержимое в исходное тело.
-
class email.parser.BytesParser(_class=None, *, policy=policy.compat32) -
Создаёт экземпляр класса
BytesParser. Аргументы _class и policy имеют то же значение и семантику, что и аргументы _factory и policy классаBytesFeedParser.Примечание: Ключевое слово policy должно всегда указываться; значение по умолчанию будет изменено на
email.policy.defaultв будущих версиях Python.Изменено в версии 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. Вызов этого метода на объекте типа bytes эквивалентен первому обертыванию bytes в экземпляр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().
-
-
class email.parser.HeaderParser(_class=None, *, policy=policy.compat32) -
Точно так же, как и
Parser, за исключением того, что headersonly имеет значение по умолчаниюTrue.
Так как создание структуры объекта сообщения из строки или объекта файла — это очень распространённая задача, предоставляются четыре функции для удобства. Они доступны в пространстве имён верхнего уровня пакета email.
-
email.message_from_bytes(s, _class=None, *, policy=policy.compat32) -
Возвращает структуру объекта сообщения из объекта типа bytes. Это эквивалентно
BytesParser().parsebytes(s). Необязательные аргументы _class и policy интерпретируются так же, как и в конструкторе классаBytesParser.Добавлена в версии 3.2.
Изменено в версии 3.3: Удалён аргумент strict. Добавлен ключевой аргумент policy.
-
email.message_from_binary_file(fp, _class=None, *, policy=policy.compat32) -
Возвращает структуру дерева объекта сообщения из открытого бинарного объекта файла. Это эквивалентно
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) -
Возвращает структуру дерева объекта сообщения из открытого объекта файла. Это эквивалентно
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.
© 2001–2020 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.7/library/email.parser.html