Spec-Zone.ru › Python 2.7

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

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

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

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

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

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

Новое в версии 2.4.

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

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

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

class email.parser.FeedParser([_factory])

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

feed(data)

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

close()

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

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

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

class email.parser.Parser([_class])

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

Необязательный флаг strict игнорируется.

Устарело начиная с версии 2.4: Поскольку класс Parser является обратной совместимой обёрткой API вокруг нового в Python 2.4 класса FeedParser, все разборы фактически нестрогие. Вы просто должны перестать передавать флаг strict конструктору Parser.

Изменено в версии 2.2.2: Флаг strict был добавлен.

Изменено в версии 2.4: Флаг strict был устарел.

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

parse(fp[, headersonly])

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

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

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

Изменено в версии 2.2.2: Флаг headersonly был добавлен.

parsestr(text[, headersonly])

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

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

Изменено в версии 2.2.2: Флаг headersonly был добавлен.

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

email.message_from_string(s[, _class[, strict]])

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

Изменено в версии 2.2.2: Флаг strict был добавлен.

email.message_from_file(fp[, _class[, strict]])

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

Изменено в версии 2.2.2: Флаг strict был добавлен.

Вот пример использования этой функции в интерактивной оболочке 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, в списке атрибутов defects будет экземпляр класса MultipartInvariantViolationDefect. См. 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/2.7/library/email.parser.html

Spec-Zone.ru

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