Skip to main content

Библиотека для парсинга email переписки

Project description

Simple Email Parse

Библиотека для парсинга email-переписок из HTML-файлов. Извлекает структурированную информацию о сообщениях, включая заголовки (From, Sent, To, Subject) и текст сообщений.

Установка

pip install simple-email-parse

Быстрый старт

from simple_email_parser import EmailParser

parser = EmailParser("email.htm", remove_img=True)

messages = parser.get_dict()
print(f"Найдено сообщений: {len(messages)}")

for msg in messages:
    if msg['header']:
        print(f"От: {msg['header']['From']['email']}")
        print(f"Дата: {msg['header']['Sent']}")
    print(f"Текст: {msg['text'][:100]}...")
    print("---")

parser.save_json("output.json")

Архитектура

Библиотека состоит из трех основных компонентов:

1. EmailParser

Главный класс для парсинга email. Последовательно применяет HtmlProcessor и JsonProcessor для извлечения структурированных данных.

Параметры:

  • filepath - путь к HTML-файлу
  • html - HTML-строка (альтернатива filepath)
  • soup - готовый BeautifulSoup объект (альтернатива filepath/html)
  • encoding - кодировка файла (автоопределение: utf-8, windows-1251)
  • remove_img - удалять изображения из текста
  • main_contact - основной контакт для сообщений без заголовка

Методы:

  • get_dict() - возвращает список словарей с сообщениями
  • get_json() - возвращает JSON-строку
  • save_json(filepath) - сохраняет результат в JSON-файл
  • save_html(filepath) - сохраняет обработанный HTML

2. HtmlProcessor

Обрабатывает HTML-код email, нормализуя структуру и выделяя заголовки сообщений.

Алгоритм работы

Этап 1: Инициализация и предобработка

  • Чтение HTML из файла/строки/soup
  • Удаление BOM (\ufeff) и DOCTYPE
  • Обработка изображений: замена <img> на текстовые маркеры
  • Упрощение ссылок: преобразование <a> в span/p с форматом [текст](url)

Этап 2: Очистка HTML

  • Удаление системных тегов (html, body, head, style, script, meta)
  • Удаление пустых тегов (рекурсивно)
  • Сохранение специальных атрибутов (simple-email-parse-attr)
  • Удаление всех остальных атрибутов (class, style, id)

Этап 3: Упрощение структуры

  • Преобразование всех тегов в div/span/br/blockquote/table
  • Блочные теги (p, h1-h6, ul, ol, li) → div
  • Инлайн теги (b, i, strong, em) → span

Этап 4: Обработка сиротных узлов

  • Поиск последовательностей текст + span
  • Оборачивание в div только если содержимое является заголовком
  • Проверка через адаптеры заголовков

Этап 5: Распаковка span

  • Специальные span с quote_header → div
  • Если span содержит div → unwrap
  • Текстовые span → склеиваются с пробелами

Этап 6: Обнаружение заголовков Используются адаптеры для поиска заголовков:

  1. Контекстный поиск:
    • После <hr> (с игнорированием <br>)
    • Перед/внутри <blockquote>
  2. Глобальный поиск: все div, p, span
  3. Сортировка кандидатов по глубине (от вложенных к корневым)
  4. Применение адаптеров: DividerHeader → MultipleDivHeader → KeyValueHeader → OnelineHeader

Этап 7: Обработка пересылаемых сообщений (Fwd)

  • Поиск разделителей "---Пересылаемое сообщение---"
  • Поиск заголовка после разделителя (с игнорированием <br>)
  • Оборачивание в <blockquote> до маркера конца

Этап 8: Улучшение структуры цитат

  1. Превращение div[simple-email-parse-attr="quote"]<blockquote>
  2. Распаковка заголовков из лишних оберток
  3. Распаковка цитат из лишних div (unwrap родителя, если единственный значимый контент)
  4. Перенос заголовков внутрь следующей цитаты
  5. Финальная распаковка пустых оберток

Этап 9: Упрощение div-блоков Выполняется циклически (while changed):

  1. Wrap Orphans: оборачивание сирот (текст, таблицы) в div
  2. Flattening: если div содержит структурные блоки как прямых детей → unwrap
  3. Backward Merge: слияние с предыдущим div или затягивание контента
  4. Forward Suck: затягивание следующего контента

Этап 10: Обеспечение blockquote

  • Оборачивание блоков после quote_header в <blockquote>
  • Жадный захват всех элементов до следующего заголовка

Этап 11: Вложение соседних цитат

  • Обработка снизу вверх
  • Если перед цитатой стоит другая цитата → перемещение внутрь

Этап 12: Перенос остатков

  • Обработка сверху вниз (рекурсивно)
  • Перенос "хвостов" после цитаты в div перед цитатой
  • Объединение с существующим контентом через <br>

Этап 13: Преобразование переносов строк

  • <br>\n
  • SHY (\xad) → удаление
  •   → пробел
  • Схлопывание пробелов
  • Удаление пробелов вокруг \n
  • Ограничение: 2+ \n → \n\n

3. JsonProcessor

Извлекает сообщения из обработанного HTML и парсит заголовки.

Алгоритм работы

Этап 1: Рекурсивное извлечение сообщений

  • Обход дерева blockquote
  • Поиск заголовков (simple-email-parse-attr="quote_header_*")
  • Извлечение текста между заголовком и вложенными цитатами
  • Сохранение HTML-содержимого (включая таблицы)

Этап 2: Парсинг контактов Поддерживаемые форматы:

  • Name <email@example.com>
  • Name [mailto:email@example.com]
  • "Name" <email@example.com>
  • email@example.com

Этап 3: Парсинг даты/времени Поддерживаемые форматы:

  • 14.05.2024, 17:35
  • Вторник, 14 мая 2024, 17:35 +03:00
  • Wednesday, May 08, 2024 1:34 PM
  • пт, 15 апр. 2022 г. в 20:47
  • 8 мая 2024 г., 13:55:58 +03:00

Этап 4: Парсинг заголовков

Блочный формат (KeyValue):

From: Sender <sender@example.com>
Sent: Tuesday, May 14, 2024 5:35 PM
To: Receiver <receiver@example.com>
Subject: Test Subject

Однострочный формат:

21.09.2023, 16:13, 'Name' <email@example.com>:

Этап 5: Разворот порядка сообщений

  • Самое глубокое (старое) сообщение → первое
  • Реверсирование списка

Этап 6: Обработка временных меток Вычисление времени для сообщений без явного указания:

  • Первое сообщение: время следующего минус 1 час
  • Последнее сообщение: время предыдущего плюс 1 час
  • Среднее сообщение: среднее между предыдущим и следующим
  • Поиск ближайших сообщений с реальным временем (не 00:00:00)
  • Согласование timezone (добавление МСК если нужно)

Этап 7: Конвертация в МСК

  • Все временные метки конвертируются в московское время (UTC+3)
  • Если timezone не указан → считается МСК

Этап 8: Формирование результата

[
  {
    "header": {
      "From": {"name": "Sender", "email": "sender@example.com"},
      "Sent": "2024-05-14T17:35:00+03:00",
      "To": {"name": "Receiver", "email": "receiver@example.com"},
      "Subject": "Test"
    },
    "text": "Message text..."
  }
]

Адаптеры заголовков

DividerHeaderAdapter

Обнаруживает разделители пересылаемых сообщений:

---Пересылаемое сообщение---
---Forwarded message---

MultipleDivHeaderAdapter

Обнаруживает многострочные заголовки, разбитые на несколько div:

<div>Кому: email@example.com;</div>
<div>Тема: Test Subject;</div>
<div>29.10.2025, 09:16, "Sender" <email@example.com>:</div>

Правила:

  • Минимум 2 элемента с ключевыми словами
  • Первый div должен начинаться с ключевого слова
  • Не более 5 элементов в группе
  • Общая длина не более 600 символов

KeyValueHeaderAdapter

Обнаруживает блочные заголовки с ключами:

From: sender@example.com
Sent: Tuesday, May 14, 2024
To: receiver@example.com
Subject: Test

Правила:

  • Минимум 2 ключа (From, Sent, To, Subject, Cc)
  • Первый ключ в начале текста (не далее 50 символов)
  • Отсутствие разбиения между соседними элементами

OnelineHeaderAdapter

Обнаруживает однострочные заголовки:

21.09.2023, 16:13, 'Name' <email@example.com>:
Вы писали 8 мая 2024 г., 13:55:58:

Правила:

  • Длина 10-350 символов
  • Не более 3 переносов строк
  • Наличие даты + времени + email/ключевых слов
  • Заканчивается на двоеточие

Особенности и узкие места

Обработка пробелов и переносов

  • При распаковке span всегда добавляются пробелы для предотвращения слипания слов
  • Важно игнорировать <br> при поиске заголовков, так как они часто окружают заголовки
  • Разделители <br> правильно обрабатываются при слиянии div

Обработка заголовков

  • Проверка вложенности: родительские контейнеры отступают, если внутри уже найден заголовок
  • Look Behind: проверка предыдущего соседа для избежания ложных срабатываний на фрагментах заголовков
  • Сортировка кандидатов по глубине позволяет обрабатывать сначала вложенные элементы

Обработка цитат

  • Распаковка цитат выполняется дважды: до и после переноса заголовков
  • Проверка "мусорных" узлов (_is_removable_node) включает пустые текстовые узлы, <br> и пустые div
  • При переносе заголовков используется _is_removable_node для пропуска <br>

Обработка div-блоков

  • Защита от бесконечного цикла: проверка только прямых потомков (children), не всех (descendants)
  • Важно различать: для unwrap_div нужен <br> как контент (ignore_br=False), для process_headers - нет (ignore_br=True)

Обработка временных меток

  • Особый случай: время 00:00:00 без timezone → признак отсутствия времени (только дата)
  • Время 00:00:00 С timezone → реальное время полуночи
  • Сохранение даты при вычислении времени для корректности

Примеры использования

Базовое использование

from simple_email_parser import EmailParser

parser = EmailParser("email.htm")
messages = parser.get_dict()

for msg in messages:
    print(f"Header: {msg['header']}")
    print(f"Text: {msg['text']}")

Использование с HTML-строкой

html = "<div>Email content...</div>"
parser = EmailParser(html=html, remove_img=True)
json_output = parser.get_json()

Использование с основным контактом

from simple_email_parser import EmailParser, Contact

main_contact = Contact(email="me@example.com", name="My Name")
parser = EmailParser("email.htm", main_contact=main_contact)

messages = parser.get_dict()

Раздельное использование процессоров

from simple_email_parser import HtmlProcessor, JsonProcessor

html_proc = HtmlProcessor("email.htm", remove_img=True)
html_proc.process()

json_proc = JsonProcessor(html=html_proc.soup)
messages = json_proc.process()

Лицензия

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

simple_email_parse-0.1.3.tar.gz (24.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

simple_email_parse-0.1.3-py3-none-any.whl (25.6 kB view details)

Uploaded Python 3

File details

Details for the file simple_email_parse-0.1.3.tar.gz.

File metadata

  • Download URL: simple_email_parse-0.1.3.tar.gz
  • Upload date:
  • Size: 24.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.0

File hashes

Hashes for simple_email_parse-0.1.3.tar.gz
Algorithm Hash digest
SHA256 7e1d27577d80e7a6c8f87103e280c7fc1878565bd2db6add7bc7086afe9207c8
MD5 9bf69fbc5e1cc6abe9066397e2539e06
BLAKE2b-256 df3d485b12b4d910e6fe0a84fcfbfc4b7fd9f14ba3b5cc021b1d160deac0f717

See more details on using hashes here.

File details

Details for the file simple_email_parse-0.1.3-py3-none-any.whl.

File metadata

File hashes

Hashes for simple_email_parse-0.1.3-py3-none-any.whl
Algorithm Hash digest
SHA256 f10dd72093ec43c3f6fc998cc95a988cf339a6abc55653e4f547ae89538e4422
MD5 a9791152d53e5f669497191d793ff547
BLAKE2b-256 a10bec1d34324c37475511acf49c4248b67579ec39b4b285faea3ee775fafc76

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page