email.parser
: Разбор сообщений электронной почты¶
Источник: Lib/email/parser.py
Объектные структуры сообщений могут быть созданы одним из двух способов: они могут быть созданы с нуля путем создания объекта EmailMessage
, добавления заголовков с помощью интерфейса словаря и добавления полезной нагрузки с помощью set_content()
и связанных методов, или они могут быть созданы путем разбора сериализованного представления почтового сообщения.
Пакет email
предоставляет стандартный парсер, который понимает большинство структур почтовых документов, включая документы MIME. Вы можете передать парсеру байтовый, строковый или файловый объект, и парсер вернет вам корневой EmailMessage
экземпляр структуры объекта. Для простых, не MIME-сообщений полезной нагрузкой этого корневого объекта, скорее всего, будет строка, содержащая текст сообщения. Для MIME-сообщений корневой объект вернет True
из своего метода is_multipart()
, а доступ к вложенным частям можно получить с помощью методов манипулирования полезной нагрузкой, таких как get_body()
, iter_parts()
и walk()
.
На самом деле существует два интерфейса парсера, доступных для использования: Parser
API и инкрементный FeedParser
API. API Parser
API наиболее полезен, если весь текст сообщения находится в памяти или если все сообщение хранится в файле на файловой системе. API FeedParser
больше подходит для чтения сообщения из потока, который может заблокироваться в ожидании дополнительного ввода (например, чтение сообщения электронной почты из сокета). FeedParser
может потреблять и разбирать сообщение постепенно, и возвращает корневой объект только после закрытия парсера.
Обратите внимание, что парсер может быть расширен ограниченными способами, и, конечно, вы можете реализовать свой собственный парсер полностью с нуля. Вся логика, связывающая парсер из пакета email
и класс EmailMessage
, воплощена в классе Policy
, поэтому пользовательский парсер может создавать деревья объектов сообщений любым способом, который сочтет нужным, реализуя собственные версии соответствующих методов Policy
.
API FeedParser¶
Модуль BytesFeedParser
, импортированный из модуля email.feedparser
, предоставляет API, позволяющий выполнять инкрементный разбор почтовых сообщений, например, при чтении текста почтового сообщения из источника, который может блокироваться (например, сокета). Конечно, BytesFeedParser
можно использовать для разбора почтового сообщения, полностью содержащегося в bytes-like object, строке или файле, но BytesParser
может быть более удобным для такого использования. API может быть более удобным для таких случаев. Семантика и результаты работы двух 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
.Added in version 3.2.
Изменено в версии 3.3: Добавлено ключевое слово policy.
Изменено в версии 3.6: По умолчанию _factory устанавливает политику
message_factory
.- feed(data)¶
Передайте парсеру дополнительные данные. data должна представлять собой bytes-like object, содержащий одну или несколько строк. Строки могут быть неполными, и парсер будет правильно сшивать такие неполные строки. Строки могут иметь любое из трех обычных окончаний: возврат каретки, новая строка или возврат каретки и новая строка (они даже могут быть смешанными).
- 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()
.Опционально лично - как при использовании метода
parse()
.
Added in version 3.2.
- class email.parser.BytesHeaderParser(_class=None, *, policy=policy.compat32)¶
Точно так же, как и
BytesParser
, за исключением того, что по умолчанию для headersonly используется значениеTrue
.Added in version 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()
, только вместо файлоподобного объекта принимает строковый объект. Вызов этого метода для строки эквивалентен тому, чтобы сначала обернуть text в экземплярStringIO
и вызватьparse()
.Опционально лично - как при использовании метода
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
.Added in version 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
.Added in version 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)
Дополнительные примечания¶
Вот некоторые замечания по семантике разбора:
Большинство сообщений типа non-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
, то в списке атрибутов defects у них будет экземпляр классаMultipartInvariantViolationDefect
. Подробности см. в разделеemail.errors
.