email.parser.md
1> **Источник:** https://python-all.ru/3.4/library/email.parser.html2>3> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.45---67# 19.1.2. [`email.parser`](https://python-all.ru/3.4/library/email.parser.html#module-email.parser): Разбор сообщений электронной почты89Структуры объектов сообщений можно создать одним из двух способов: создать с нуля, создав экземпляры объектов [`Message`](https://python-all.ru/3.4/library/email.message.html#email.message.Message) и связав их с помощью вызовов [`attach()`](https://python-all.ru/3.4/library/email.message.html#email.message.Message.attach) и [`set_payload()`](https://python-all.ru/3.4/library/email.message.html#email.message.Message.set_payload), или же разобрав плоское текстовое представление сообщения электронной почты.1011Пакет [`email`](https://python-all.ru/3.4/library/email.html#module-email) предоставляет стандартный парсер, который понимает большинство структур документов электронной почты, включая MIME-документы. Парсеру можно передать строку или файловый объект, и он вернёт корневой экземпляр [`Message`](https://python-all.ru/3.4/library/email.message.html#email.message.Message) структуры объекта. Для простых сообщений, не являющихся MIME, полезная нагрузка этого корневого объекта, скорее всего, будет строкой, содержащей текст сообщения. Для MIME-сообщений корневой объект вернёт `True` из своего метода [`is_multipart()`](https://python-all.ru/3.4/library/email.message.html#email.message.Message.is_multipart), а доступ к вложенным частям можно получить через методы [`get_payload()`](https://python-all.ru/3.4/library/email.message.html#email.message.Message.get_payload) и [`walk()`](https://python-all.ru/3.4/library/email.message.html#email.message.Message.walk).1213На самом деле доступны два интерфейса парсера: классический API [`Parser`](https://python-all.ru/3.4/library/email.parser.html#email.parser.Parser) и инкрементальный API [`FeedParser`](https://python-all.ru/3.4/library/email.parser.html#email.parser.FeedParser). Классический API [`Parser`](https://python-all.ru/3.4/library/email.parser.html#email.parser.Parser) подходит, если весь текст сообщения находится в памяти в виде строки или если всё сообщение хранится в файле в файловой системе. [`FeedParser`](https://python-all.ru/3.4/library/email.parser.html#email.parser.FeedParser) больше подходит для ситуаций, когда сообщение читается из потока, который может блокироваться в ожидании дополнительных данных (например, чтение сообщения электронной почты из сокета). [`FeedParser`](https://python-all.ru/3.4/library/email.parser.html#email.parser.FeedParser) может потреблять и анализировать сообщение инкрементально, возвращая корневой объект только после закрытия парсера [\[1\]](https://python-all.ru/3.4/library/email.parser.html#id2).1415Обратите внимание, что парсер можно расширять ограниченными способами, и, конечно, можно реализовать собственный парсер полностью с нуля. Нет никакой магической связи между встроенным парсером пакета [`email`](https://python-all.ru/3.4/library/email.html#module-email) и классом [`Message`](https://python-all.ru/3.4/library/email.message.html#email.message.Message), поэтому ваш собственный парсер может создавать деревья объектов сообщений любым способом, который сочтёт необходимым.1617## 19.1.2.1. API FeedParser1819[`FeedParser`](https://python-all.ru/3.4/library/email.parser.html#email.parser.FeedParser), импортируемый из модуля `email.feedparser`, предоставляет API, подходящий для инкрементального разбора сообщений электронной почты, например, когда текст сообщения читается из источника, который может блокироваться (например, сокет). [`FeedParser`](https://python-all.ru/3.4/library/email.parser.html#email.parser.FeedParser), конечно, можно использовать для разбора сообщения, полностью содержащегося в строке или файле, но для таких случаев может быть удобнее классический API [`Parser`](https://python-all.ru/3.4/library/email.parser.html#email.parser.Parser). Семантика и результаты работы двух парсеров API идентичны.2021API [`FeedParser`](https://python-all.ru/3.4/library/email.parser.html#email.parser.FeedParser) прост: создаёте экземпляр, подаёте ему текст, пока есть что подавать, затем закрываете парсер, чтобы получить корневой объект сообщения. [`FeedParser`](https://python-all.ru/3.4/library/email.parser.html#email.parser.FeedParser) чрезвычайно точен при разборе сообщений, соответствующих стандартам, и очень хорошо справляется с сообщениями, не соответствующими стандартам, предоставляя информацию о том, как сообщение было признано некорректным. Он заполняет атрибут *defects* объекта сообщения списком всех проблем, найденных в сообщении. Список дефектов, которые можно найти, приведён в модуле [`email.errors`](https://python-all.ru/3.4/library/email.errors.html#module-email.errors).2223Вот API для [`FeedParser`](https://python-all.ru/3.4/library/email.parser.html#email.parser.FeedParser):2425#### `class email.parser.FeedParser(_factory=email.message.Message, *, policy=policy.compat32)`2627Создаёт экземпляр [`FeedParser`](https://python-all.ru/3.4/library/email.parser.html#email.parser.FeedParser). Необязательный параметр *\_factory* – это вызываемый объект без аргументов, который будет вызываться всякий раз, когда потребуется новый объект сообщения. По умолчанию используется класс [`email.message.Message`](https://python-all.ru/3.4/library/email.message.html#email.message.Message).2829Если указан *policy* (должен быть экземпляром класса [`policy`](https://python-all.ru/3.4/library/email.policy.html#module-email.policy)), используйте указанные им правила для обновления представления сообщения. Если *policy* не задан, используется политика [`compat32`](https://python-all.ru/3.4/library/email.policy.html#email.policy.Compat32), которая обеспечивает обратную совместимость с версией пакета email для Python 3.2. Дополнительные сведения см. в документации [`policy`](https://python-all.ru/3.4/library/email.policy.html#module-email.policy).3031Изменено в версии 3.3: Добавлен параметр *policy*.3233#### `feed(data)`3435Передаёт парсеру [`FeedParser`](https://python-all.ru/3.4/library/email.parser.html#email.parser.FeedParser) дополнительные данные. *data* должна быть строкой, содержащей одну или несколько строк. Строки могут быть неполными, и [`FeedParser`](https://python-all.ru/3.4/library/email.parser.html#email.parser.FeedParser) правильно склеит такие неполные строки. Строки в строке могут иметь любой из трёх распространённых концевых символов: возврат каретки, перевод строки или возврат каретки с переводом строки (они могут даже быть смешаны).3637#### `close()`3839Закрытие [`FeedParser`](https://python-all.ru/3.4/library/email.parser.html#email.parser.FeedParser) завершает разбор всех ранее переданных данных и возвращает корневой объект сообщения. Поведение при попытке передать дополнительные данные закрытому [`FeedParser`](https://python-all.ru/3.4/library/email.parser.html#email.parser.FeedParser) не определено.4041#### `class email.parser.BytesFeedParser(_factory=email.message.Message)`4243Работает точно так же, как [`FeedParser`](https://python-all.ru/3.4/library/email.parser.html#email.parser.FeedParser), за исключением того, что входные данные для метода [`feed()`](https://python-all.ru/3.4/library/email.parser.html#email.parser.FeedParser.feed) должны быть байтами, а не строкой.4445Новое в версии 3.2.4647## 19.1.2.2. API класса Parser4849Класс [`Parser`](https://python-all.ru/3.4/library/email.parser.html#email.parser.Parser), импортируемый из модуля [`email.parser`](https://python-all.ru/3.4/library/email.parser.html#module-email.parser), предоставляет API, который можно использовать для разбора сообщения, когда полное содержимое сообщения доступно в виде строки или файла. Модуль [`email.parser`](https://python-all.ru/3.4/library/email.parser.html#module-email.parser) также предоставляет парсеры только для заголовков, называемые `HeaderParser` и `BytesHeaderParser`, которые можно использовать, если интересуют только заголовки сообщения. `HeaderParser` и `BytesHeaderParser` могут быть значительно быстрее в таких ситуациях, поскольку они не пытаются разобрать тело сообщения, а вместо этого устанавливают полезную нагрузку в виде необработанного тела как строки. Они имеют тот же API, что и классы [`Parser`](https://python-all.ru/3.4/library/email.parser.html#email.parser.Parser) и [`BytesParser`](https://python-all.ru/3.4/library/email.parser.html#email.parser.BytesParser).5051Новое в версии 3.3: Класс BytesHeaderParser.5253#### `class email.parser.Parser(_class=email.message.Message, *, policy=policy.compat32)`5455Конструктор класса [`Parser`](https://python-all.ru/3.4/library/email.parser.html#email.parser.Parser) принимает необязательный аргумент *\_class*. Это должна быть вызываемая фабрика (например, функция или класс), которая используется всякий раз, когда необходимо создать объект вложенного сообщения. По умолчанию используется [`Message`](https://python-all.ru/3.4/library/email.message.html#email.message.Message) (см. [`email.message`](https://python-all.ru/3.4/library/email.message.html#module-email.message)). Фабрика будет вызываться без аргументов.5657Если указан *policy* (должен быть экземпляром класса [`policy`](https://python-all.ru/3.4/library/email.policy.html#module-email.policy)), используйте указанные им правила для обновления представления сообщения. Если *policy* не задан, используется политика [`compat32`](https://python-all.ru/3.4/library/email.policy.html#email.policy.Compat32), которая обеспечивает обратную совместимость с версией пакета email для Python 3.2. Дополнительные сведения см. в документации [`policy`](https://python-all.ru/3.4/library/email.policy.html#module-email.policy).5859Изменено в версии 3.3: Удалён аргумент *strict*, устаревший в версии 2.4. Добавлен параметр *policy*.6061Другие публичные методы [`Parser`](https://python-all.ru/3.4/library/email.parser.html#email.parser.Parser):6263#### `parse(fp, headersonly=False)`6465Читает все данные из объекта, подобного файлу, *fp*, разбирает полученный текст и возвращает корневой объект сообщения. *fp* должен поддерживать как метод [`readline()`](https://python-all.ru/3.4/library/io.html#io.TextIOBase.readline), так и метод [`read()`](https://python-all.ru/3.4/library/io.html#io.TextIOBase.read), характерные для объектов, подобных файлам.6667Текст, содержащийся в *fp*, должен быть отформатирован как блок заголовков и строк продолжения заголовков в стиле [**RFC 2822**](https://python-all.ru/3.4/library/email.parser.html), при необходимости перед которым может идти конвертный заголовок. Блок заголовков завершается либо концом данных, либо пустой строкой. После блока заголовков следует тело сообщения (которое может содержать MIME-кодированные вложенные части).6869Необязательный параметр *headersonly* – это флаг, указывающий, следует ли остановить разбор после чтения заголовков. Значение по умолчанию – `False`, то есть разбирается всё содержимое файла.7071#### `parsestr(text, headersonly=False)`7273Аналогичен методу [`parse()`](https://python-all.ru/3.4/library/email.parser.html#email.parser.Parser.parse), но принимает строковый объект вместо объекта, подобного файлу. Вызов этого метода для строки полностью эквивалентен тому, чтобы сначала обернуть *text* в экземпляр [`StringIO`](https://python-all.ru/3.4/library/io.html#io.StringIO), а затем вызвать [`parse()`](https://python-all.ru/3.4/library/email.parser.html#email.parser.Parser.parse).7475Необязательный параметр *headersonly* действует так же, как в методе [`parse()`](https://python-all.ru/3.4/library/email.parser.html#email.parser.Parser.parse).7677#### `class email.parser.BytesParser(_class=email.message.Message, *, policy=policy.compat32)`7879Этот класс полностью аналогичен [`Parser`](https://python-all.ru/3.4/library/email.parser.html#email.parser.Parser), но обрабатывает входные данные в виде байтов. Аргументы *\_class* и *strict* интерпретируются так же, как для конструктора [`Parser`](https://python-all.ru/3.4/library/email.parser.html#email.parser.Parser).8081Если указан *policy* (должен быть экземпляром класса [`policy`](https://python-all.ru/3.4/library/email.policy.html#module-email.policy)), используйте указанные им правила для обновления представления сообщения. Если *policy* не задан, используется политика [`compat32`](https://python-all.ru/3.4/library/email.policy.html#email.policy.Compat32), которая обеспечивает обратную совместимость с версией пакета email для Python 3.2. Дополнительные сведения см. в документации [`policy`](https://python-all.ru/3.4/library/email.policy.html#module-email.policy).8283Изменено в версии 3.3: Удалён аргумент *strict*. Добавлен ключевой аргумент *policy*.8485#### `parse(fp, headersonly=False)`8687Считывает все данные из двоичного файлоподобного объекта *fp*, разбирает полученные байты и возвращает объект сообщения. *fp* должен поддерживать как метод [`readline()`](https://python-all.ru/3.4/library/io.html#io.IOBase.readline), так и метод `read()` для файлоподобных объектов.8889Байты, содержащиеся в *fp*, должны быть отформатированы как блок заголовков в стиле [**RFC 2822**](https://python-all.ru/3.4/library/email.parser.html) и строк продолжения заголовков, возможно, с предшествующим конвертным заголовком. Блок заголовков завершается либо концом данных, либо пустой строкой. После блока заголовков следует тело сообщения (которое может содержать MIME-кодированные подчасти, в том числе подчасти с *Content-Transfer-Encoding*, равным `8bit`).9091Необязательный параметр *headersonly* – это флаг, указывающий, нужно ли остановить разбор после чтения заголовков. Значение по умолчанию – `False`, то есть разбирается всё содержимое файла.9293#### `parsebytes(bytes, headersonly=False)`9495Аналогичен методу [`parse()`](https://python-all.ru/3.4/library/email.parser.html#email.parser.BytesParser.parse), но принимает объект байтовой строки вместо файлоподобного объекта. Вызов этого метода для байтовой строки полностью эквивалентен тому, чтобы сначала обернуть *text* в экземпляр [`BytesIO`](https://python-all.ru/3.4/library/io.html#io.BytesIO), а затем вызвать [`parse()`](https://python-all.ru/3.4/library/email.parser.html#email.parser.BytesParser.parse).9697Необязательный параметр *headersonly* работает так же, как в методе [`parse()`](https://python-all.ru/3.4/library/email.parser.html#email.parser.BytesParser.parse).9899Новое в версии 3.2.100101Поскольку создание структуры объекта сообщения из строки или файлового объекта является довольно распространённой задачей, для удобства предоставлены четыре функции. Они доступны в пространстве имён пакета верхнего уровня [`email`](https://python-all.ru/3.4/library/email.html#module-email).102103#### `email.message_from_string(s, _class=email.message.Message, *, policy=policy.compat32)`104105Возвращает структуру объекта сообщения из строки. Это полностью эквивалентно `Parser().parsestr(s)`. Параметры *\_class* и *policy* интерпретируются так же, как в конструкторе класса [`Parser`](https://python-all.ru/3.4/library/email.parser.html#email.parser.Parser).106107Изменено в версии 3.3: Удалён аргумент *strict*. Добавлен ключевой аргумент *policy*.108109#### `email.message_from_bytes(s, _class=email.message.Message, *, policy=policy.compat32)`110111Возвращает структуру объекта сообщения из байтовой строки. Это полностью эквивалентно `BytesParser().parsebytes(s)`. Необязательные параметры *\_class* и *strict* интерпретируются так же, как в конструкторе класса [`Parser`](https://python-all.ru/3.4/library/email.parser.html#email.parser.Parser).112113Новое в версии 3.2.114115Изменено в версии 3.3: Удалён аргумент *strict*. Добавлен ключевой аргумент *policy*.116117#### `email.message_from_file(fp, _class=email.message.Message, *, policy=policy.compat32)`118119Возвращает дерево структуры объекта сообщения из открытого [*файлового объекта*](https://python-all.ru/3.4/glossary.html#term-file-object). Это полностью эквивалентно вызову `Parser().parse(fp)`. Параметры *\_class* и *policy* интерпретируются так же, как в конструкторе класса [`Parser`](https://python-all.ru/3.4/library/email.parser.html#email.parser.Parser).120121Изменено в версии Removed: аргумент *strict* удалён. Добавлено ключевое слово *policy*.122123#### `email.message_from_binary_file(fp, _class=email.message.Message, *, policy=policy.compat32)`124125Возвращает дерево структуры объекта сообщения из открытого двоичного [*файлового объекта*](https://python-all.ru/3.4/glossary.html#term-file-object). Это полностью эквивалентно вызову `BytesParser().parse(fp)`. Параметры *\_class* и *policy* интерпретируются так же, как в конструкторе класса [`Parser`](https://python-all.ru/3.4/library/email.parser.html#email.parser.Parser).126127Новое в версии 3.2.128129Изменено в версии 3.3: Удалён аргумент *strict*. Добавлен ключевой аргумент *policy*.130131Вот пример использования этого в интерактивном приглашении Python:132133```python134>>> import email135>>> msg = email.message_from_string(myString) 136```137138## 19.1.2.3. Дополнительные примечания139140Вот некоторые замечания по семантике разбора:141142- Большинство сообщений типа non-*multipart* разбираются как единый объект сообщения со строковой полезной нагрузкой. У таких объектов метод [`is_multipart()`](https://python-all.ru/3.4/library/email.message.html#email.message.Message.is_multipart) вернёт `False`. Их метод [`get_payload()`](https://python-all.ru/3.4/library/email.message.html#email.message.Message.get_payload) вернёт строковый объект.143- Все сообщения типа *multipart* разбираются как объект-контейнер со списком объектов-подсообщений в качестве полезной нагрузки. Внешний контейнерный объект вернёт `True` для [`is_multipart()`](https://python-all.ru/3.4/library/email.message.html#email.message.Message.is_multipart), а его метод [`get_payload()`](https://python-all.ru/3.4/library/email.message.html#email.message.Message.get_payload) вернёт список подчастей [`Message`](https://python-all.ru/3.4/library/email.message.html#email.message.Message).144- Большинство сообщений с типом содержимого *message/\** (например, *message/delivery-status* и *message/rfc822*) также разбираются как объект-контейнер, содержащий полезную нагрузку в виде списка длиной 1. Их метод [`is_multipart()`](https://python-all.ru/3.4/library/email.message.html#email.message.Message.is_multipart) вернёт `True`. Единственный элемент в списке полезной нагрузки будет объектом-подсообщением.145- Some non-standards compliant messages may not be internally consistent about their *multipart*-edness. Such messages may have a *Content-Type* header of type *multipart*, but their [`is_multipart()`](https://python-all.ru/3.4/library/email.message.html#email.message.Message.is_multipart) method may return `False`. If such messages were parsed with the [`FeedParser`](https://python-all.ru/3.4/library/email.parser.html#email.parser.FeedParser), they will have an instance of the `MultipartInvariantViolationDefect` class in their *defects* attribute list. See [`email.errors`](https://python-all.ru/3.4/library/email.errors.html#module-email.errors) for details.146147Сноски148149| [\[1\]](https://python-all.ru/3.4/library/email.parser.html#id1) | Начиная с версии 3.0 пакета email, введённой в Python 2.4, классический [`Parser`](https://python-all.ru/3.4/library/email.parser.html#email.parser.Parser) был перереализован на основе [`FeedParser`](https://python-all.ru/3.4/library/email.parser.html#email.parser.FeedParser), поэтому семантика и результаты у обоих парсеров идентичны. |150| --- | --- |151