Документация Python неофициальный перевод

email.parser.md

155 строк · 27.0 КБ · обычная страница · сырой текст · скачать

1> **Источник:** https://python-all.ru/3.5/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.5/library/email.parser.html#module-email.parser): Разбор сообщений электронной почты89**Исходный код:** [Lib/email/parser.py](https://python-all.ru/src/3.5/Lib/email/parser.py)1011---1213Структуры объектов сообщений можно создать двумя способами: создать с нуля, создавая объекты [`Message`](https://python-all.ru/3.5/library/email.message.html#email.message.Message) и соединяя их вызовами [`attach()`](https://python-all.ru/3.5/library/email.message.html#email.message.Message.attach) и [`set_payload()`](https://python-all.ru/3.5/library/email.message.html#email.message.Message.set_payload), или разобрать плоское текстовое представление сообщения электронной почты.1415Пакет [`email`](https://python-all.ru/3.5/library/email.html#module-email) предоставляет стандартный анализатор, который понимает большинство структур документов электронной почты, включая MIME-документы. Анализатору можно передать строку или файловый объект, и он вернёт корневой экземпляр [`Message`](https://python-all.ru/3.5/library/email.message.html#email.message.Message) объектной структуры. Для простых не-MIME сообщений полезная нагрузка этого корневого объекта, скорее всего, будет строкой, содержащей текст сообщения. Для MIME-сообщений корневой объект вернёт `True` из своего метода [`is_multipart()`](https://python-all.ru/3.5/library/email.message.html#email.message.Message.is_multipart), а вложенные части можно получить через методы [`get_payload()`](https://python-all.ru/3.5/library/email.message.html#email.message.Message.get_payload) и [`walk()`](https://python-all.ru/3.5/library/email.message.html#email.message.Message.walk).1617Фактически доступны два интерфейса анализатора: классический API [`Parser`](https://python-all.ru/3.5/library/email.parser.html#email.parser.Parser) и инкрементальный API [`FeedParser`](https://python-all.ru/3.5/library/email.parser.html#email.parser.FeedParser). Классический API [`Parser`](https://python-all.ru/3.5/library/email.parser.html#email.parser.Parser) подходит, если всё текстовое сообщение находится в памяти в виде строки или хранится в файле файловой системы. [`FeedParser`](https://python-all.ru/3.5/library/email.parser.html#email.parser.FeedParser) лучше подходит при чтении сообщения из потока, который может блокироваться в ожидании новых данных (например, при чтении из сокета). [`FeedParser`](https://python-all.ru/3.5/library/email.parser.html#email.parser.FeedParser) может потреблять и анализировать сообщение инкрементально, возвращая корневой объект только после закрытия анализатора [\[1\]](https://python-all.ru/3.5/library/email.parser.html#id2).1819Обратите внимание, что анализатор можно ограниченно расширять, и, конечно, вы можете полностью реализовать свой собственный анализатор с нуля. Между встроенным анализатором пакета [`email`](https://python-all.ru/3.5/library/email.html#module-email) и классом [`Message`](https://python-all.ru/3.5/library/email.message.html#email.message.Message) нет никакой магической связи, поэтому ваш собственный анализатор может создавать деревья объектов сообщений любым подходящим ему способом.2021## 19.1.2.1. API FeedParser2223[`FeedParser`](https://python-all.ru/3.5/library/email.parser.html#email.parser.FeedParser), импортируемый из модуля `email.feedparser`, предоставляет API, удобный для инкрементального разбора сообщений электронной почты, например при чтении текста сообщения из источника, который может блокироваться (например, сокета). [`FeedParser`](https://python-all.ru/3.5/library/email.parser.html#email.parser.FeedParser), конечно, можно использовать и для разбора сообщения, полностью содержащегося в строке или файле, но классический API [`Parser`](https://python-all.ru/3.5/library/email.parser.html#email.parser.Parser) может быть удобнее в таких случаях. Семантика и результаты обоих API анализаторов идентичны.2425API [`FeedParser`](https://python-all.ru/3.5/library/email.parser.html#email.parser.FeedParser) прост: создайте экземпляр, подавайте на вход текст, пока не закончится, затем закройте анализатор, чтобы получить корневой объект сообщения. [`FeedParser`](https://python-all.ru/3.5/library/email.parser.html#email.parser.FeedParser) чрезвычайно точен при разборе сообщений, соответствующих стандартам, и отлично справляется с несоответствующими сообщениями, предоставляя информацию о том, почему сообщение было признано некорректным. Он заполняет атрибут *defects* объекта сообщения списком всех найденных проблем. Список дефектов, которые он может найти, см. в модуле [`email.errors`](https://python-all.ru/3.5/library/email.errors.html#module-email.errors).2627Вот API для [`FeedParser`](https://python-all.ru/3.5/library/email.parser.html#email.parser.FeedParser):2829#### `class email.parser.FeedParser(_factory=email.message.Message, *, policy=policy.compat32)`3031Создаёт экземпляр [`FeedParser`](https://python-all.ru/3.5/library/email.parser.html#email.parser.FeedParser). Необязательный параметр *\_factory* – это вызываемый объект без аргументов, который будет вызываться при необходимости создания нового объекта сообщения. По умолчанию используется класс [`email.message.Message`](https://python-all.ru/3.5/library/email.message.html#email.message.Message).3233Если указан *policy* (он должен быть экземпляром класса [`policy`](https://python-all.ru/3.5/library/email.policy.html#module-email.policy)), используйте заданные им правила для обновления представления сообщения. Если *policy* не задан, применяется политика [`compat32`](https://python-all.ru/3.5/library/email.policy.html#email.policy.Compat32), которая обеспечивает обратную совместимость с версией пакета email для Python 3.2. Дополнительную информацию см. в документации [`policy`](https://python-all.ru/3.5/library/email.policy.html#module-email.policy).3435Изменено в версии 3.3: Добавлен параметр *policy*.3637#### `feed(data)`3839Передаёт дополнительные данные анализатору [`FeedParser`](https://python-all.ru/3.5/library/email.parser.html#email.parser.FeedParser). *data* должна быть строкой, содержащей одну или несколько строк. Строки могут быть неполными, и [`FeedParser`](https://python-all.ru/3.5/library/email.parser.html#email.parser.FeedParser) правильно соберёт такие части строк. Строки могут иметь любые из трёх распространённых окончаний: возврат каретки, перевод строки или возврат каретки и перевод строки (допускается смешивание).4041#### `close()`4243Закрытие [`FeedParser`](https://python-all.ru/3.5/library/email.parser.html#email.parser.FeedParser) завершает разбор всех ранее переданных данных и возвращает корневой объект сообщения. Что произойдёт при передаче дополнительных данных закрытому [`FeedParser`](https://python-all.ru/3.5/library/email.parser.html#email.parser.FeedParser), не определено.4445#### `class email.parser.BytesFeedParser(_factory=email.message.Message)`4647Работает точно так же, как [`FeedParser`](https://python-all.ru/3.5/library/email.parser.html#email.parser.FeedParser), за исключением того, что входные данные для метода [`feed()`](https://python-all.ru/3.5/library/email.parser.html#email.parser.FeedParser.feed) должны быть байтами, а не строкой.4849Новое в версии 3.2.5051## 19.1.2.2. API класса Parser5253Класс [`Parser`](https://python-all.ru/3.5/library/email.parser.html#email.parser.Parser), импортируемый из модуля [`email.parser`](https://python-all.ru/3.5/library/email.parser.html#module-email.parser), предоставляет API для разбора сообщения, когда полное содержимое сообщения доступно в виде строки или файла. Модуль [`email.parser`](https://python-all.ru/3.5/library/email.parser.html#module-email.parser) также предоставляет анализаторы только для заголовков, называемые `HeaderParser` и `BytesHeaderParser`, которые можно использовать, если интересуют только заголовки сообщения. `HeaderParser` и `BytesHeaderParser` могут быть значительно быстрее в таких ситуациях, поскольку они не пытаются разобрать тело сообщения, а вместо этого устанавливают полезную нагрузку в виде необработанного тела как строку. Их API совпадает с API классов [`Parser`](https://python-all.ru/3.5/library/email.parser.html#email.parser.Parser) и [`BytesParser`](https://python-all.ru/3.5/library/email.parser.html#email.parser.BytesParser).5455Новое в версии 3.3: Класс BytesHeaderParser.5657#### `class email.parser.Parser(_class=email.message.Message, *, policy=policy.compat32)`5859Конструктор класса [`Parser`](https://python-all.ru/3.5/library/email.parser.html#email.parser.Parser) принимает необязательный аргумент *\_class*. Это должен быть вызываемый объект-фабрика (например, функция или класс), используемый при необходимости создания подобъекта сообщения. По умолчанию используется [`Message`](https://python-all.ru/3.5/library/email.message.html#email.message.Message) (см. [`email.message`](https://python-all.ru/3.5/library/email.message.html#module-email.message)). Фабрика вызывается без аргументов.6061Если указан *policy* (он должен быть экземпляром класса [`policy`](https://python-all.ru/3.5/library/email.policy.html#module-email.policy)), используйте заданные им правила для обновления представления сообщения. Если *policy* не задан, применяется политика [`compat32`](https://python-all.ru/3.5/library/email.policy.html#email.policy.Compat32), которая обеспечивает обратную совместимость с версией пакета email для Python 3.2. Дополнительную информацию см. в документации [`policy`](https://python-all.ru/3.5/library/email.policy.html#module-email.policy).6263Изменено в версии 3.3: Удалён аргумент *strict*, устаревший в версии 2.4. Добавлен параметр *policy*.6465Другие открытые методы [`Parser`](https://python-all.ru/3.5/library/email.parser.html#email.parser.Parser):6667#### `parse(fp, headersonly=False)`6869Читает все данные из файлоподобного объекта *fp*, разбирает полученный текст и возвращает корневой объект сообщения. *fp* должен поддерживать как метод [`readline()`](https://python-all.ru/3.5/library/io.html#io.TextIOBase.readline), так и метод [`read()`](https://python-all.ru/3.5/library/io.html#io.TextIOBase.read), характерные для файлоподобных объектов.7071Текст, содержащийся в *fp*, должен быть отформатирован как блок заголовков и строк продолжения заголовков в стиле [**RFC 2822**](https://python-all.ru/3.5/library/email.parser.html), при необходимости перед которым может идти конвертный заголовок. Блок заголовков завершается либо концом данных, либо пустой строкой. После блока заголовков следует тело сообщения (которое может содержать MIME-кодированные вложенные части).7273Необязательный параметр *headersonly* – флаг, указывающий, следует ли остановить разбор после чтения заголовков. По умолчанию `False`, то есть разбирается всё содержимое файла.7475#### `parsestr(text, headersonly=False)`7677Аналогичен методу [`parse()`](https://python-all.ru/3.5/library/email.parser.html#email.parser.Parser.parse), за исключением того, что принимает строковый объект вместо файлоподобного. Вызов этого метода для строки эквивалентен предварительной обёртке *text* в экземпляр [`StringIO`](https://python-all.ru/3.5/library/io.html#io.StringIO) с последующим вызовом [`parse()`](https://python-all.ru/3.5/library/email.parser.html#email.parser.Parser.parse).7879Необязательный параметр *headersonly* действует так же, как в методе [`parse()`](https://python-all.ru/3.5/library/email.parser.html#email.parser.Parser.parse).8081#### `class email.parser.BytesParser(_class=email.message.Message, *, policy=policy.compat32)`8283Этот класс полностью аналогичен [`Parser`](https://python-all.ru/3.5/library/email.parser.html#email.parser.Parser), но работает с байтовыми входными данными. Аргументы *\_class* и *strict* интерпретируются так же, как в конструкторе [`Parser`](https://python-all.ru/3.5/library/email.parser.html#email.parser.Parser).8485Если указан *policy* (он должен быть экземпляром класса [`policy`](https://python-all.ru/3.5/library/email.policy.html#module-email.policy)), используйте заданные им правила для обновления представления сообщения. Если *policy* не задан, применяется политика [`compat32`](https://python-all.ru/3.5/library/email.policy.html#email.policy.Compat32), которая обеспечивает обратную совместимость с версией пакета email для Python 3.2. Дополнительную информацию см. в документации [`policy`](https://python-all.ru/3.5/library/email.policy.html#module-email.policy).8687Изменено в версии 3.3: Удалён аргумент *strict*. Добавлен ключевой аргумент *policy*.8889#### `parse(fp, headersonly=False)`9091Читает все данные из двоичного файлоподобного объекта *fp*, разбирает полученные байты и возвращает объект сообщения. *fp* должен поддерживать как метод [`readline()`](https://python-all.ru/3.5/library/io.html#io.IOBase.readline), так и метод `read()` файлоподобных объектов.9293Содержащиеся в *fp* байты должны быть отформатированы как блок заголовков в стиле [**RFC 2822**](https://python-all.ru/3.5/library/email.parser.html) и строк продолжения заголовков, необязательно перед которыми может идти заголовок конверта. Блок заголовков завершается либо концом данных, либо пустой строкой. За блоком заголовков следует тело сообщения (которое может содержать MIME-кодированные подчасти, включая подчасти с *Content-Transfer-Encoding*, равным `8bit`).9495Необязательный параметр *headersonly* – флаг, указывающий, следует ли остановить разбор после чтения заголовков. По умолчанию `False`, то есть разбирается всё содержимое файла.9697#### `parsebytes(text, headersonly=False)`9899Аналогично методу [`parse()`](https://python-all.ru/3.5/library/email.parser.html#email.parser.BytesParser.parse), за исключением того, что принимает [байтоподобный объект](https://python-all.ru/3.5/glossary.html#term-bytes-like-object) вместо файлоподобного объекта. Вызов этого метода эквивалентен предварительной обёртке *text* в экземпляр [`BytesIO`](https://python-all.ru/3.5/library/io.html#io.BytesIO) и последующему вызову [`parse()`](https://python-all.ru/3.5/library/email.parser.html#email.parser.BytesParser.parse).100101Необязательный параметр *headersonly* действует так же, как в методе [`parse()`](https://python-all.ru/3.5/library/email.parser.html#email.parser.BytesParser.parse).102103Новое в версии 3.2.104105Поскольку создание структуры объекта сообщения из строки или файлового объекта является распространённой задачей, для удобства предоставляются четыре функции. Они доступны в пространстве имён пакета верхнего уровня [`email`](https://python-all.ru/3.5/library/email.html#module-email).106107#### `email.message_from_string(s, _class=email.message.Message, *, policy=policy.compat32)`108109Возвращает структуру объекта сообщения из строки. Это в точности эквивалентно `Parser().parsestr(s)`. *\_class* и *policy* интерпретируются так же, как в конструкторе класса [`Parser`](https://python-all.ru/3.5/library/email.parser.html#email.parser.Parser).110111Изменено в версии 3.3: Удалён аргумент *strict*. Добавлен ключевой аргумент *policy*.112113#### `email.message_from_bytes(s, _class=email.message.Message, *, policy=policy.compat32)`114115Возвращает структуру объекта сообщения из [байтоподобного объекта](https://python-all.ru/3.5/glossary.html#term-bytes-like-object). Это в точности эквивалентно `BytesParser().parsebytes(s)`. Необязательные *\_class* и *strict* интерпретируются так же, как в конструкторе класса [`Parser`](https://python-all.ru/3.5/library/email.parser.html#email.parser.Parser).116117Новое в версии 3.2.118119Изменено в версии 3.3: Удалён аргумент *strict*. Добавлен ключевой аргумент *policy*.120121#### `email.message_from_file(fp, _class=email.message.Message, *, policy=policy.compat32)`122123Возвращает дерево структуры объекта сообщения из открытого [файлового объекта](https://python-all.ru/3.5/glossary.html#term-file-object). Это в точности эквивалентно `Parser().parse(fp)`. *\_class* и *policy* интерпретируются так же, как в конструкторе класса [`Parser`](https://python-all.ru/3.5/library/email.parser.html#email.parser.Parser).124125Изменено в версии 3.3: Удалён аргумент *strict*. Добавлен ключевой аргумент *policy*.126127#### `email.message_from_binary_file(fp, _class=email.message.Message, *, policy=policy.compat32)`128129Возвращает дерево структуры объекта сообщения из открытого двоичного [файлового объекта](https://python-all.ru/3.5/glossary.html#term-file-object). Это в точности эквивалентно `BytesParser().parse(fp)`. *\_class* и *policy* интерпретируются так же, как в конструкторе класса [`Parser`](https://python-all.ru/3.5/library/email.parser.html#email.parser.Parser).130131Новое в версии 3.2.132133Изменено в версии 3.3: Удалён аргумент *strict*. Добавлен ключевой аргумент *policy*.134135Вот пример использования этого в интерактивном приглашении Python:136137```python138>>> import email139>>> msg = email.message_from_string(myString)  140```141142## 19.1.2.3. Дополнительные примечания143144Вот некоторые замечания по семантике разбора:145146- Большинство сообщений, не являющихся *multipart*, разбираются как одиночный объект сообщения со строковым содержимым. Такие объекты будут возвращать `False` для [`is_multipart()`](https://python-all.ru/3.5/library/email.message.html#email.message.Message.is_multipart). Их метод [`get_payload()`](https://python-all.ru/3.5/library/email.message.html#email.message.Message.get_payload) будет возвращать строковый объект.147- Все сообщения типа *multipart* будут разбираться как объект-контейнер со списком объектов-подсообщений в качестве содержимого. Внешний контейнер будет возвращать `True` для [`is_multipart()`](https://python-all.ru/3.5/library/email.message.html#email.message.Message.is_multipart), а его метод [`get_payload()`](https://python-all.ru/3.5/library/email.message.html#email.message.Message.get_payload) вернёт список из [`Message`](https://python-all.ru/3.5/library/email.message.html#email.message.Message) подчастей.148- Большинство сообщений с типом содержимого *message/\** (например, *message/delivery-status* и *message/rfc822*) также будут разбираться как объект-контейнер, содержащий полезную нагрузку в виде списка длиной 1. Их метод [`is_multipart()`](https://python-all.ru/3.5/library/email.message.html#email.message.Message.is_multipart) вернёт `True`. Единственный элемент в списке будет объектом-подсообщением.149- Некоторые сообщения, не соответствующие стандартам, могут быть внутренне несогласованы относительно своей *multipart*-ности. Такие сообщения могут иметь заголовок *Content-Type* типа *multipart*, но их метод [`is_multipart()`](https://python-all.ru/3.5/library/email.message.html#email.message.Message.is_multipart) может возвращать `False`. Если такие сообщения были разобраны с помощью [`FeedParser`](https://python-all.ru/3.5/library/email.parser.html#email.parser.FeedParser), они будут содержать экземпляр класса `MultipartInvariantViolationDefect` в списке атрибутов *defects*. Подробнее см. [`email.errors`](https://python-all.ru/3.5/library/email.errors.html#module-email.errors).150151Сноски152153| [\[1\]](https://python-all.ru/3.5/library/email.parser.html#id1) | Начиная с версии 3.0 пакета email, представленной в Python 2.4, классический [`Parser`](https://python-all.ru/3.5/library/email.parser.html#email.parser.Parser) был перереализован на основе [`FeedParser`](https://python-all.ru/3.5/library/email.parser.html#email.parser.FeedParser), поэтому семантика и результаты двух парсеров идентичны. |154| --- | --- |155