Spec-Zone.ru › Python 3.5

email.parser: Парсинг сообщений электронной почты

Исходный код: Lib/email/parser.py

Структуры объектов сообщений можно создать двумя способами: создать их с нуля, используя объекты Message и соединяя их с помощью вызовов attach() и set_payload(), или создать их, разобрав плоское текстовое представление сообщения электронной почты.

Пакет email предоставляет стандартный парсер, понимающий большинство структур документов электронной почты, включая MIME-документы. Вы можете передать парсеру строку или объект файла, и парсер вернёт вам корневой объект Message структуры объекта. Для простых, не-MIME сообщений содержимое этого корневого объекта, скорее всего, будет строкой, содержащей текст сообщения. Для MIME-сообщений корневой объект вернёт значение True из его метода is_multipart(), а к подчастям можно получить доступ с помощью методов get_payload() и walk().

На самом деле доступны два интерфейса парсеров: классический интерфейс Parser и инкрементальный интерфейс FeedParser. Классический интерфейс Parser подходит, если у вас есть весь текст сообщения в памяти как строка или если всё сообщение хранится в файле на файловой системе. FeedParser более уместен, когда вы читаете сообщение из потока, который может блокироваться в ожидании большего ввода (например, чтение сообщения электронной почты из сокета). FeedParser может потреблять и анализировать сообщение по частям и возвращает корневой объект только при закрытии парсера [1].

Обратите внимание, что парсер можно расширить ограниченным способом, и, конечно, вы можете реализовать свой собственный парсер полностью с нуля. Нет никакой магической связи между парсером, входящим в пакет email, и классом Message, поэтому ваш пользовательский парсер может создавать деревья объектов сообщений любым необходимым ему способом.

1. Интерфейс FeedParser

Класс FeedParser, импортированный из модуля email.feedparser, предоставляет интерфейс, который подходит для инкрементального парсинга сообщений электронной почты, такого как это необходимо при чтении текста сообщения электронной почты из источника, который может блокироваться (например, сокета). Класс FeedParser, конечно же, может использоваться для анализа сообщения электронной почты, полностью содержащегося в строке или файле, но классический интерфейс Parser может быть более удобным для таких случаев. Семантика и результаты двух интерфейсов парсеров идентичны.

Интерфейс класса FeedParser прост: вы создаёте экземпляр, передаёте ему набор текста до тех пор, пока нет большего количества, затем закрываете парсер для получения корневого объекта сообщения. Класс FeedParser очень точно анализирует сообщения, соответствующие стандартам, и хорошо справляется с анализом несоответствующих сообщений, предоставляя информацию о том, как сообщение было признано некорректным. Он заполняет атрибут defects объекта сообщения списком всех обнаруженных проблем в сообщении. См. модуль email.errors для списка дефектов, которые он может обнаружить.

Вот интерфейс класса FeedParser:

class email.parser.FeedParser(_factory=email.message.Message, *, policy=policy.compat32)

Создаёт экземпляр FeedParser. Необязательный аргумент _factory — это вызываемый объект без аргументов, который будет вызываться всякий раз, когда требуется новый объект сообщения. По умолчанию он равен классу email.message.Message.

Если указан параметр policy (он должен быть экземпляром класса policy), используйте правила, которые он задаёт, для обновления представления сообщения. Если параметр policy не задан, используйте политику compat32, которая поддерживает обратную совместимость с версией пакета email Python 3.2. Более подробную информацию см. в документации policy.

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

feed(data)

Передаёт классу FeedParser дополнительные данные. data должна быть строкой, содержащей одну или несколько строк. Строки могут быть частичными, и FeedParser будет правильно соединять такие частичные строки. Строки в строке могут иметь любые из обычных трёх символов конца строки: возврат каретки, новая строка или возврат каретки и новая строка (они даже могут быть смешаны).

close()

Закрытие класса FeedParser завершает анализ всех ранее предоставленных данных и возвращает корневой объект сообщения. Не определено, что произойдёт, если вы передадите больше данных закрытому классу FeedParser.

class email.parser.BytesFeedParser(_factory=email.message.Message)

Работает точно так же, как FeedParser, за исключением того, что вход в метод feed() должен быть байтами, а не строкой.

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

2. Интерфейс класса Parser

Класс Parser, импортированный из модуля email.parser, предоставляет интерфейс, который можно использовать для анализа сообщения, когда все содержимое сообщения доступно в строке или файле. Модуль email.parser также предоставляет парсеры только для заголовков, называемые HeaderParser и BytesHeaderParser, которые можно использовать, если вас интересуют только заголовки сообщения. HeaderParser и BytesHeaderParser могут быть значительно быстрее в этих ситуациях, поскольку они не пытаются проанализировать тело сообщения, вместо этого устанавливая содержимое в исходное тело как строку. Они имеют тот же интерфейс, что и классы Parser и BytesParser.

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

class email.parser.Parser(_class=email.message.Message, *, policy=policy.compat32)

Конструктор класса Parser принимает необязательный аргумент _class. Он должен быть вызываемым фабричным объектом (например, функцией или классом), который используется при необходимости создания объекта подсообщения. По умолчанию используется Message (см. email.message). Фабричная функция вызывается без аргументов.

Если задан параметр policy (должен быть экземпляром класса policy), используются правила, определённые в нём, для обновления представления сообщения. Если policy не задан, используется политика compat32, обеспечивающая обратную совместимость с версией email-пакета Python 3.2. Дополнительная информация содержится в документации policy.

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

Другие общедоступные методы класса Parser:

parse(fp, headersonly=False)

Считывает все данные из объекта fp, подобного файлу, анализирует полученный текст и возвращает корневой объект сообщения. Объект fp должен поддерживать методы readline() и read() для объектов, подобных файлам.

Текст в fp должен быть отформатирован как блок заголовков в стиле RFC 2822 и продолжения заголовков, необязательно предваряемых заголовком конверта. Блок заголовков завершается либо концом данных, либо пустой строкой. После блока заголовков следует тело сообщения (которое может содержать закодированные MIME-подчасти).

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

parsestr(text, headersonly=False)

Аналогичен методу parse(), но принимает строковый объект вместо объекта, подобного файлу. Вызов этого метода для строки эквивалентен предварительному обертыванию text в экземпляр StringIO и вызову parse().

Необязательный параметр headersonly такой же, как в методе parse().

class email.parser.BytesParser(_class=email.message.Message, *, policy=policy.compat32)

Этот класс аналогичен Parser, но обрабатывает байтовый ввод. Аргументы _class и strict интерпретируются так же, как и в конструкторе Parser.

Если задан параметр policy (должен быть экземпляром класса policy), используются правила, определённые в нём, для обновления представления сообщения. Если policy не задан, используется политика compat32, обеспечивающая обратную совместимость с версией email-пакета Python 3.2. Дополнительная информация содержится в документации policy.

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

parse(fp, headersonly=False)

Считывает все данные из бинарного объекта fp, подобного файлу, анализирует полученные байты и возвращает объект сообщения. Объект fp должен поддерживать методы readline() и read() для объектов, подобных файлам.

Байты в fp должны быть отформатированы как блок заголовков в стиле RFC 2822 и продолжения заголовков, необязательно предваряемых заголовком конверта. Блок заголовков завершается либо концом данных, либо пустой строкой. После блока заголовков следует тело сообщения (которое может содержать закодированные MIME-подчасти, в том числе подчасти с Content-Transfer-Encoding 8bit).

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

parsebytes(text, headersonly=False)

Аналогичен методу parse(), но принимает объект типа «подобный байтам» вместо объекта, подобного файлу. Вызов этого метода эквивалентен предварительному обертыванию text в экземпляр BytesIO и вызову parse().

Необязательный параметр headersonly такой же, как в методе parse().

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

Поскольку создание структуры объекта сообщения из строки или объекта, подобного файлу, — частая задача, предоставляются четыре функции для удобства. Они доступны в пространстве имён верхнего уровня пакета email.

email.message_from_string(s, _class=email.message.Message, *, policy=policy.compat32)

Возвращает структуру объекта сообщения из строки. Это точно эквивалентно Parser().parsestr(s). Параметры _class и policy интерпретируются так же, как и в конструкторе класса Parser.

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

email.message_from_bytes(s, _class=email.message.Message, *, policy=policy.compat32)

Возвращает структуру объекта сообщения из объекта типа «подобный байтам». Это точно эквивалентно BytesParser().parsebytes(s). Необязательные параметры _class и strict интерпретируются так же, как и в конструкторе класса Parser.

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

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

email.message_from_file(fp, _class=email.message.Message, *, policy=policy.compat32)

Возвращает структуру дерева объекта сообщения из открытого объекта объекта файла. Это точно эквивалентно Parser().parse(fp). Параметры _class и policy интерпретируются так же, как и в конструкторе класса Parser.

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

email.message_from_binary_file(fp, _class=email.message.Message, *, policy=policy.compat32)

Возвращает структуру дерева объекта сообщения из открытого бинарного объекта объекта файла. Это точно эквивалентно BytesParser().parse(fp). Параметры _class и policy интерпретируются так же, как и в конструкторе класса Parser.

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

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

Вот пример использования в интерактивной оболочке Python:

>>> import email
>>> msg = email.message_from_string(myString)  

3. Дополнительные заметки

Вот несколько заметок по семантике разбора:

  • Большинство сообщений типа multipart не являются, разбираются как один объект сообщения со строковым содержимым. Эти объекты вернут False для is_multipart(). Их метод get_payload() вернёт строковый объект.
  • Все сообщения типа multipart будут разобраны как контейнерный объект сообщения со списком дочерних объектов сообщений в качестве содержимого. Внешний контейнерный объект вернёт True для is_multipart(), а их метод get_payload() вернёт список Message подчастей.
  • Большинство сообщений с типом содержимого message/* (например, message/delivery-status и message/rfc822) также будут разобраны как контейнерный объект, содержащий список содержимого длиной 1. Их метод is_multipart() вернёт True. Единственный элемент в списке содержимого будет объектом подсообщения.
  • Некоторые сообщения, не соответствующие стандартам, могут быть внутренне не согласованы относительно своего multipart-состояния. Такие сообщения могут иметь заголовок Content-Type типа multipart, но их метод is_multipart() может вернуть False. Если такие сообщения были обработаны с помощью FeedParser, у них будет экземпляр класса MultipartInvariantViolationDefect в списке атрибутов defects. Подробности см. в email.errors.

Примечания

[1] Начиная с версии пакета email 3.0, представленной в Python 2.4, классический Parser был повторно реализован с точки зрения FeedParser, поэтому семантика и результаты идентичны для обоих парсеров.

© 2001–2020 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.5/library/email.parser.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API