> **Источник:** https://python-all.ru/3/library/email.parser.html
>
> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.

---

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

**Исходный код:** [Lib/email/parser.py](https://python-all.ru/src/3.14/Lib/email/parser.py)

---

Структуры объектов сообщений можно создать одним из двух способов: их можно создать с нуля, создав объект [`EmailMessage`](https://python-all.ru/3/library/email.message.html#email.message.EmailMessage), добавляя заголовки через интерфейс словаря и добавляя содержимое (payload) с помощью [`set_content()`](https://python-all.ru/3/library/email.message.html#email.message.EmailMessage.set_content) и связанных методов, или их можно создать путём разбора сериализованного представления сообщения электронной почты.

Пакет [`email`](https://python-all.ru/3/library/email.html#module-email) предоставляет стандартный анализатор, который понимает большинство структур документов электронной почты, включая MIME-документы. Можно передать анализатору объект bytes, строку или файл, и анализатор вернёт корневой экземпляр [`EmailMessage`](https://python-all.ru/3/library/email.message.html#email.message.EmailMessage) структуры объекта. Для простых, не-MIME сообщений содержимое (payload) этого корневого объекта, скорее всего, будет строкой, содержащей текст сообщения. Для MIME-сообщений корневой объект вернёт `True` из своего метода [`is_multipart()`](https://python-all.ru/3/library/email.message.html#email.message.EmailMessage.is_multipart), а к подчастям можно получить доступ через методы манипуляции содержимым, такие как [`get_body()`](https://python-all.ru/3/library/email.message.html#email.message.EmailMessage.get_body), [`iter_parts()`](https://python-all.ru/3/library/email.message.html#email.message.EmailMessage.iter_parts) и [`walk()`](https://python-all.ru/3/library/email.message.html#email.message.EmailMessage.walk).

На самом деле доступны два интерфейса анализатора: [`Parser`](https://python-all.ru/3/library/email.parser.html#email.parser.Parser) API и инкрементальный [`FeedParser`](https://python-all.ru/3/library/email.parser.html#email.parser.FeedParser) API. `Parser` API наиболее полезен, если всё сообщение находится в памяти или если всё сообщение хранится в файле в файловой системе. `FeedParser` больше подходит, когда сообщение читается из потока, который может заблокироваться в ожидании новых данных (например, чтение сообщения электронной почты из сокета). `FeedParser` может потреблять и анализировать сообщение инкрементально и возвращает корневой объект только после закрытия анализатора.

Обратите внимание, что анализатор можно расширить ограниченными способами, и, конечно, можно реализовать собственный анализатор полностью с нуля. Вся логика, связывающая встроенный анализатор пакета [`email`](https://python-all.ru/3/library/email.html#module-email) и класс [`EmailMessage`](https://python-all.ru/3/library/email.message.html#email.message.EmailMessage), воплощена в классе [`Policy`](https://python-all.ru/3/library/email.policy.html#email.policy.Policy), поэтому пользовательский анализатор может создавать деревья объектов сообщений любым необходимым способом, реализуя пользовательские версии соответствующих методов `Policy`.

## FeedParser API

[`BytesFeedParser`](https://python-all.ru/3/library/email.parser.html#email.parser.BytesFeedParser), импортированный из модуля `email.feedparser`, предоставляет API, подходящий для инкрементального разбора сообщений электронной почты, например, когда необходимо читать текст сообщения из источника, который может блокироваться (например, сокет). `BytesFeedParser`, конечно, можно использовать для разбора сообщения, полностью содержащегося в [байтоподобном объекте](https://python-all.ru/3/glossary.html#term-bytes-like-object), строке или файле, но API [`BytesParser`](https://python-all.ru/3/library/email.parser.html#email.parser.BytesParser) может быть удобнее для таких случаев. Семантика и результаты двух API анализаторов идентичны.

API [`BytesFeedParser`](https://python-all.ru/3/library/email.parser.html#email.parser.BytesFeedParser) прост: создаётся экземпляр, в него подаётся набор байтов, пока больше нечего подавать, затем анализатор закрывается, чтобы получить корневой объект сообщения. `BytesFeedParser` чрезвычайно точен при разборе сообщений, соответствующих стандартам, и очень хорошо справляется с разбором несоответствующих сообщений, предоставляя информацию о том, почему сообщение было признано некорректным. Он заполняет атрибут [`defects`](https://python-all.ru/3/library/email.message.html#email.message.EmailMessage.defects) объекта сообщения списком любых проблем, найденных в сообщении. Смотрите модуль [`email.errors`](https://python-all.ru/3/library/email.errors.html#module-email.errors) для получения списка дефектов, которые он может найти.

Вот API для [`BytesFeedParser`](https://python-all.ru/3/library/email.parser.html#email.parser.BytesFeedParser):

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

Создаёт экземпляр `BytesFeedParser`. Необязательный параметр *\_factory* – это вызываемый объект без аргументов; если не указан, используется [`message_factory`](https://python-all.ru/3/library/email.policy.html#email.policy.Policy.message_factory) из *policy*. Вызов *\_factory* производится каждый раз, когда требуется новый объект сообщения.

Если указан *policy*, используются заданные им правила для обновления представления сообщения. Если *policy* не задан, используется политика [`compat32`](https://python-all.ru/3/library/email.policy.html#email.policy.Compat32), которая обеспечивает обратную совместимость с версией Python 3.2 пакета email и предоставляет [`Message`](https://python-all.ru/3/library/email.compat32-message.html#email.message.Message) в качестве фабрики по умолчанию. Все остальные политики предоставляют [`EmailMessage`](https://python-all.ru/3/library/email.message.html#email.message.EmailMessage) в качестве *\_factory* по умолчанию. Дополнительную информацию о том, что ещё контролирует *policy*, см. в документации [`policy`](https://python-all.ru/3/library/email.policy.html#module-email.policy).

Примечание: **Параметр policy всегда следует указывать**; значение по умолчанию изменится на [`email.policy.default`](https://python-all.ru/3/library/email.policy.html#email.policy.default) в будущей версии Python.

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

Изменено в версии 3.3: Добавлен параметр *policy*.

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

#### `feed(data)`

Подайте анализатору ещё данные. *data* должен быть [байтоподобным объектом](https://python-all.ru/3/glossary.html#term-bytes-like-object), содержащим одну или несколько строк. Строки могут быть неполными, и анализатор правильно склеит такие неполные строки вместе. Строки могут иметь любой из трёх распространённых окончаний строк: возврат каретки, перевод строки или возврат каретки и перевод строки (они даже могут быть смешаны).

#### `close()`

Завершает разбор всех ранее переданных данных и возвращает корневой объект сообщения. Не определено, что произойдёт, если [`feed()`](https://python-all.ru/3/library/email.parser.html#email.parser.BytesFeedParser.feed) будет вызван после вызова этого метода.

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

Работает как [`BytesFeedParser`](https://python-all.ru/3/library/email.parser.html#email.parser.BytesFeedParser), за исключением того, что входные данные для метода [`feed()`](https://python-all.ru/3/library/email.parser.html#email.parser.BytesFeedParser.feed) должны быть строкой. Это имеет ограниченную полезность, поскольку единственный способ сделать такое сообщение допустимым – чтобы оно содержало только текст ASCII или, если [`utf8`](https://python-all.ru/3/library/email.policy.html#email.policy.EmailPolicy.utf8) равно `True`, не содержало двоичных вложений.

Изменено в версии 3.3: Добавлен параметр *policy*.

## Parser API

Класс [`BytesParser`](https://python-all.ru/3/library/email.parser.html#email.parser.BytesParser), импортированный из модуля `email.parser`, предоставляет API, который можно использовать для разбора сообщения, когда полное содержимое сообщения доступно в виде [байтоподобного объекта](https://python-all.ru/3/glossary.html#term-bytes-like-object) или файла. Модуль `email.parser` также предоставляет [`Parser`](https://python-all.ru/3/library/email.parser.html#email.parser.Parser) для разбора строк, а также анализаторы только заголовков, [`BytesHeaderParser`](https://python-all.ru/3/library/email.parser.html#email.parser.BytesHeaderParser) и [`HeaderParser`](https://python-all.ru/3/library/email.parser.html#email.parser.HeaderParser), которые можно использовать, если интересуют только заголовки сообщения. `BytesHeaderParser` и `HeaderParser` могут быть значительно быстрее в таких ситуациях, поскольку они не пытаются разобрать тело сообщения, а вместо этого устанавливают содержимое (payload) как сырое тело.

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

Создаёт экземпляр `BytesParser`. Аргументы *\_class* и *policy* имеют тот же смысл и семантику, что и аргументы *\_factory* и *policy* в [`BytesFeedParser`](https://python-all.ru/3/library/email.parser.html#email.parser.BytesFeedParser).

Примечание: **Параметр policy всегда следует указывать**; значение по умолчанию изменится на [`email.policy.default`](https://python-all.ru/3/library/email.policy.html#email.policy.default) в будущей версии Python.

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

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

#### `parse(fp, headersonly=False)`

Читает все данные из двоичного файлоподобного объекта *fp*, разбирает полученные байты и возвращает объект сообщения. *fp* должен поддерживать оба метода: [`readline()`](https://python-all.ru/3/library/io.html#io.IOBase.readline) и [`read()`](https://python-all.ru/3/library/io.html#io.BufferedIOBase.read).

Байты, содержащиеся в *fp*, должны быть отформатированы как блок [**RFC 5322**](https://python-all.ru/3/library/email.parser.html) (или, если [`utf8`](https://python-all.ru/3/library/email.policy.html#email.policy.EmailPolicy.utf8) равно `True`, [**RFC 6532**](https://python-all.ru/3/library/email.parser.html)) заголовков и строк продолжения заголовков, возможно, с предшествующим конвертным заголовком. Блок заголовков завершается либо концом данных, либо пустой строкой. После блока заголовков следует тело сообщения (которое может содержать MIME-кодированные подчасти, включая подчасти с *Content-Transfer-Encoding* равным `8bit`).

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

#### `parsebytes(bytes, headersonly=False)`

Аналогичен методу [`parse()`](https://python-all.ru/3/library/email.parser.html#email.parser.BytesParser.parse), но вместо файлоподобного объекта принимает [байтоподобный объект](https://python-all.ru/3/glossary.html#term-bytes-like-object). Вызов этого метода для байтоподобного объекта эквивалентен предварительной обёртке *bytes* в экземпляр [`BytesIO`](https://python-all.ru/3/library/io.html#io.BytesIO) и вызову `parse()`.

Необязательный параметр *headersonly* действует так же, как в методе [`parse()`](https://python-all.ru/3/library/email.parser.html#email.parser.BytesParser.parse).

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

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

Точно как [`BytesParser`](https://python-all.ru/3/library/email.parser.html#email.parser.BytesParser), за исключением того, что *headersonly* по умолчанию равен `True`.

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

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

Этот класс аналогичен [`BytesParser`](https://python-all.ru/3/library/email.parser.html#email.parser.BytesParser), но работает с строковыми входными данными.

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

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

#### `parse(fp, headersonly=False)`

Читает все данные из файлоподобного объекта в текстовом режиме *fp*, разбирает полученный текст и возвращает корневой объект сообщения. *fp* должен поддерживать как метод [`readline()`](https://python-all.ru/3/library/io.html#io.TextIOBase.readline), так и метод [`read()`](https://python-all.ru/3/library/io.html#io.TextIOBase.read) для файлоподобных объектов.

За исключением требования текстового режима, этот метод работает как [`BytesParser.parse()`](https://python-all.ru/3/library/email.parser.html#email.parser.BytesParser.parse).

#### `parsestr(text, headersonly=False)`

Аналогичен методу [`parse()`](https://python-all.ru/3/library/email.parser.html#email.parser.Parser.parse), но принимает строковый объект вместо файлоподобного. Вызов этого метода для строки eквивалентен предварительной обёртке *text* в экземпляр [`StringIO`](https://python-all.ru/3/library/io.html#io.StringIO) и вызову `parse()`.

Необязательный параметр *headersonly* действует так же, как в методе [`parse()`](https://python-all.ru/3/library/email.parser.html#email.parser.Parser.parse).

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

Точно как [`Parser`](https://python-all.ru/3/library/email.parser.html#email.parser.Parser), за исключением того, что *headersonly* по умолчанию равен `True`.

Поскольку создание структуры объекта сообщения из строки или файлового объекта является распространённой задачей, для удобства предоставляются четыре функции. Они доступны в пространстве имён пакета верхнего уровня [`email`](https://python-all.ru/3/library/email.html#module-email).

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

Return a message object structure from a [bytes-like object](https://python-all.ru/3/glossary.html#term-bytes-like-object). This is equivalent to `BytesParser().parsebytes(s)`. Optional *\_class* and *policy* are interpreted as with the [`BytesParser`](https://python-all.ru/3/library/email.parser.html#email.parser.BytesParser) class constructor.

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

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

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

Return a message object structure tree from an open binary [file object](https://python-all.ru/3/glossary.html#term-file-object). This is equivalent to `BytesParser().parse(fp)`. *\_class* and *policy* are interpreted as with the [`BytesParser`](https://python-all.ru/3/library/email.parser.html#email.parser.BytesParser) class constructor.

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

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

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

Возвращает структуру объекта сообщения из строки. Это эквивалентно `Parser().parsestr(s)`. Параметры *\_class* и *policy* интерпретируются как в конструкторе класса [`Parser`](https://python-all.ru/3/library/email.parser.html#email.parser.Parser).

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

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

Return a message object structure tree from an open [file object](https://python-all.ru/3/glossary.html#term-file-object). This is equivalent to `Parser().parse(fp)`. *\_class* and *policy* are interpreted as with the [`Parser`](https://python-all.ru/3/library/email.parser.html#email.parser.Parser) class constructor.

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

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

Вот пример использования [`message_from_bytes()`](https://python-all.ru/3/library/email.parser.html#email.message_from_bytes) в интерактивной подсказке Python:

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

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

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

- Большинство сообщений, не являющихся *multipart*, разбираются как одиночный объект сообщения с строковой полезной нагрузкой. Такие объекты возвращают `False` для [`is_multipart()`](https://python-all.ru/3/library/email.message.html#email.message.EmailMessage.is_multipart), а [`iter_parts()`](https://python-all.ru/3/library/email.message.html#email.message.EmailMessage.iter_parts) возвращает пустой список.
- Все сообщения типа *multipart* разбираются как контейнерное сообщение с полезной нагрузкой в виде списка объектов-подсообщений. Внешнее контейнерное сообщение возвращает `True` для [`is_multipart()`](https://python-all.ru/3/library/email.message.html#email.message.EmailMessage.is_multipart), а [`iter_parts()`](https://python-all.ru/3/library/email.message.html#email.message.EmailMessage.iter_parts) возвращает список подчастей.
- Большинство сообщений с типом содержимого *message/\** (такие как *message/delivery-status* и *message/rfc822*) также разбираются как контейнерный объект, содержащий полезную нагрузку в виде списка из одного элемента. Их метод [`is_multipart()`](https://python-all.ru/3/library/email.message.html#email.message.EmailMessage.is_multipart) возвращает `True`. Единственный элемент, возвращаемый [`iter_parts()`](https://python-all.ru/3/library/email.message.html#email.message.EmailMessage.iter_parts), будет объектом-подсообщением.
- Некоторые сообщения, не соответствующие стандартам, могут быть внутренне непоследовательны в отношении своей *multipart*-ности. Такие сообщения могут иметь заголовок *Content-Type* типа *multipart*, но их метод [`is_multipart()`](https://python-all.ru/3/library/email.message.html#email.message.EmailMessage.is_multipart) может возвращать `False`. Если такие сообщения были разобраны с помощью [`FeedParser`](https://python-all.ru/3/library/email.parser.html#email.parser.FeedParser), они будут содержать экземпляр класса [`MultipartInvariantViolationDefect`](https://python-all.ru/3/library/email.errors.html#email.errors.MultipartInvariantViolationDefect) в своем списке атрибутов *defects*. Подробнее см. [`email.errors`](https://python-all.ru/3/library/email.errors.html#module-email.errors).
