Преобразование HTML в Markdown с помощью Python: Полное руководство
Python для преобразования HTML в чистый, готовый к использованию с LLM Markdown
Конвертация HTML в Markdown является фундаментальной задачей в современных рабочих процессах разработки, особенно при подготовке веб-контента для крупных языковых моделей (LLM), систем документации или статических генераторов сайтов, таких как Hugo. Это руководство является частью нашего Инструментов документации в 2026 году: Markdown, LaTeX, PDF и рабочие процессы печати хаба.
Хотя HTML разработан для веб-браузеров с богатым стилем и структурой, Markdown предлагает чистый, легко читаемый формат, идеальный для обработки текста, контроля версий и потребления искусственным интеллектом. Если вы новичок в синтаксисе Markdown, ознакомьтесь с нашим Чек-листом Markdown для подробного справочника.

В этом подробном обзоре мы рассмотрим шесть пакетов Python для конвертации HTML в Markdown, предоставим практические примеры кода, тесты производительности и реальные случаи использования. Независимо от того, создаете ли вы пайплайн обучения LLM, мигрируете блог в Hugo или парсите документацию, вы найдете идеальный инструмент для вашего рабочего процесса.
Альтернативный подход: Если вам нужны более интеллектуальные методы извлечения контента с семантическим пониманием, вы также можете рассмотреть конвертацию HTML в Markdown с использованием LLM и Ollama, которая предлагает AI-оптимизированную конвертацию для сложных макетов.
Что вы узнаете:
- Подробное сравнение 6 библиотек с плюсами и минусами каждой
- Тесты производительности с реальными образцами HTML
- Готовые примеры кода для распространенных случаев использования
- Лучшие практики для рабочих процессов предварительной обработки LLM
- Конкретные рекомендации в зависимости от ваших требований
Почему Markdown для предварительной обработки LLM?
Прежде чем перейти к инструментам, давайте разберемся, почему Markdown особенно ценен для рабочих процессов LLM:
- Эффективность токенов: Markdown использует значительно меньше токенов, чем HTML, для одного и того же содержимого
- Семантическая ясность: Markdown сохраняет структуру документа без избыточных тегов
- Читаемость: И люди, и LLM легко могут разобрать синтаксис Markdown
- Согласованность: Стандартизированный формат уменьшает неоднозначность в входных данных модели
- Хранение: Меньшие размеры файлов для данных обучения и окон контекста
Гибкость Markdown выходит за рамки конвертации HTML — вы также можете конвертировать документы Word в Markdown для рабочих процессов документации, или использовать его в системах управления знаниями, таких как Obsidian для личного управления знаниями. Для получения дополнительной информации о конвертации документов и форматировании в Markdown, LaTeX и PDF, см. хаб Инструментов документации.
TL;DR - Матрица быстрого сравнения
Если вы торопитесь, вот подробное сравнение всех шести библиотек на взгляде. Эта таблица поможет вам быстро определить, какой инструмент соответствует вашим конкретным требованиям:
| Функция | html2text | markdownify | html-to-markdown | trafilatura | domscribe | html2md |
|---|---|---|---|---|---|---|
| Поддержка HTML5 | Частичная | Частичная | Полная | Полная | Полная | Полная |
| Типовые подсказки | Нет | Нет | Да | Частичная | Нет | Частичная |
| Пользовательские обработчики | Ограниченная | Отличная | Хорошая | Ограниченная | Хорошая | Ограниченная |
| Поддержка таблиц | Базовая | Базовая | Расширенная | Хорошая | Хорошая | Хорошая |
| Поддержка асинхронности | Нет | Нет | Нет | Нет | Нет | Да |
| Извлечение контента | Нет | Нет | Нет | Отличное | Нет | Хорошее |
| Извлечение метаданных | Нет | Нет | Да | Отличное | Нет | Да |
| Командная утилита | Нет | Нет | Да | Да | Нет | Да |
| Скорость | Средняя | Медленная | Быстрая | Очень быстрая | Средняя | Очень быстрая |
| Активное развитие | Нет | Да | Да | Да | Ограниченное | Да |
| Версия Python | 3.6+ | 3.7+ | 3.9+ | 3.6+ | 3.8+ | 3.10+ |
| Зависимости | Нет | BS4 | lxml | lxml | BS4 | aiohttp |
Быстрое руководство по выбору:
- Нужна скорость? → trafilatura или html2md
- Нужна настраиваемость? → markdownify
- Нужна безопасность типов? → html-to-markdown
- Нужна простота? → html2text
- Нужно извлечение контента? → trafilatura
Соперники: сравнение 6 пакетов Python
Давайте подробно рассмотрим каждую библиотеку с практическими примерами кода, вариантами настройки и реальными инсайтами. Каждый раздел включает инструкции по установке, паттерны использования и честные оценки сильных и слабых сторон.
1. html2text - Классический выбор
Изначально разработанный Аароном Свартцем, html2text является стандартным инструментом в экосистеме Python более десяти лет. Он фокусируется на создании чистого, легко читаемого формата Markdown.
Установка:
pip install html2text
Базовое использование:
import html2text
# Создание экземпляра конвертера
h = html2text.HTML2Text()
# Настройка параметров
h.ignore_links = False
h.ignore_images = False
h.ignore_emphasis = False
h.body_width = 0 # Не обрывать строки
html_content = """
<h1>Добро пожаловать в веб-скрапинг</h1>
<p>Это <strong>комплексное руководство</strong> по извлечению содержимого.</p>
<ul>
<li>Просто в использовании</li>
<li>Проверено временем</li>
<li>Широко используется</li>
</ul>
<a href="https://example.com">Узнайте больше</a>
"""
markdown = h.handle(html_content)
print(markdown)
Выходные данные:
# Добро пожаловать в веб-скрапинг
Это **комплексное руководство** по извлечению содержимого.
* Просто в использовании
* Проверено временем
* Широко используется
[Узнайте больше](https://example.com)
Расширенная настройка:
import html2text
h = html2text.HTML2Text()
# Игнорировать определенные элементы
h.ignore_links = True
h.ignore_images = True
# Управлять форматированием
h.body_width = 80 # Обрывать на 80 символов
h.unicode_snob = True # Использовать символы Unicode
h.emphasis_mark = '*' # Использовать * для выделения вместо _
h.strong_mark = '**'
# Обработка таблиц
h.ignore_tables = False
# Защита предварительно отформатированного текста
h.protect_links = True
Плюсы:
- Матурный и стабильный (более 15 лет разработки)
- Широкие возможности настройки
- Хорошо обрабатывает крайние случаи
- Нет внешних зависимостей
Минусы:
- Ограниченная поддержка HTML5
- Может производить несогласованные промежутки
- Не активно поддерживается (последнее крупное обновление в 2020 году)
- Обработка только в однопоточном режиме
Лучше всего подходит: простым HTML-документам, устаревшим системам, когда стабильность имеет первостепенное значение
2. markdownify - гибкий вариант
markdownify использует BeautifulSoup4 для предоставления гибкой парсинга HTML с настраиваемой обработкой тегов.
Установка:
pip install markdownify
Базовое использование:
from markdownify import markdownify as md
html = """
<article>
<h2>Современное веб-развитие</h2>
<p>Строительство с использованием <code>Python</code> и <em>современных фреймворков</em>.</p>
<blockquote>
<p>Простота — это верхнее совершенство.</p>
</blockquote>
</article>
"""
markdown = md(html)
print(markdown)
Выходные данные:
## Современное веб-развитие
Строительство с использованием `Python` и *современных фреймворков*.
> Простота — это верхнее совершенство.
Расширенное использование с пользовательскими обработчиками:
from markdownify import MarkdownConverter
class CustomConverter(MarkdownConverter):
"""
Создание пользовательского конвертера с конкретной обработкой тегов
"""
def convert_img(self, el, text, convert_as_inline):
"""Пользовательский обработчик изображений с альт-текстом"""
alt = el.get('alt', '')
src = el.get('src', '')
title = el.get('title', '')
if title:
return f''
return f''
def convert_pre(self, el, text, convert_as_inline):
"""Улучшенная обработка кодовых блоков с определением языка"""
code = el.find('code')
if code:
# Извлечь язык из атрибута класса (например, 'language-python')
classes = code.get('class', [''])
language = classes[0].replace('language-', '') if classes else ''
return f'\n```{language}\n{code.get_text()}\n```\n'
return f'\n```\n{text}\n```\n'
# Использовать пользовательский конвертер
html = '<pre><code class="language-python">def hello():\n print("world")</code></pre>'
markdown = CustomConverter().convert(html)
print(markdown)
Для получения дополнительной информации о работе с кодовыми блоками Markdown и подсветке синтаксиса, см. наше руководство по использованию кодовых блоков Markdown.
Выборочная конвертация тегов:
from markdownify import markdownify as md
# Удалить определенные теги полностью
markdown = md(html, strip=['script', 'style', 'nav'])
# Конвертировать только определенные теги
markdown = md(
html,
heading_style="ATX", # Использовать # для заголовков
bullets="-", # Использовать - для маркированных списков
strong_em_symbol="*", # Использовать * для выделения
)
Плюсы:
- Построено на BeautifulSoup4 (надежный парсинг HTML)
- Очень настраиваемо через наследование
- Активная поддержка
- Хорошая документация
Минусы:
- Требуется зависимость BeautifulSoup4
- Может быть медленнее для больших документов
- Ограниченная встроенная поддержка таблиц
Лучше всего подходит: для пользовательской логики конвертации, проектов, уже использующих BeautifulSoup4
3. html-to-markdown - современная мощная библиотека
html-to-markdown — это полностью типизированная, современная библиотека с комплексной поддержкой HTML5 и расширенными возможностями настройки.
Установка:
pip install html-to-markdown
Базовое использование:
from html_to_markdown import convert
html = """
<article>
<h1>Техническая документация</h1>
<table>
<thead>
<tr>
<th>Функция</th>
<th>Поддержка</th>
</tr>
</thead>
<tbody>
<tr>
<td>HTML5</td>
<td>✓</td>
</tr>
<tr>
<td>Таблицы</td>
<td>✓</td>
</tr>
</tbody>
</table>
</article>
"""
markdown = convert(html)
print(markdown)
Расширенная настройка:
from html_to_markdown import convert, Options
# Создать пользовательские параметры
options = Options(
heading_style="ATX",
bullet_style="-",
code_language_default="python",
strip_tags=["script", "style"],
escape_special_chars=True,
table_style="pipe", # Использовать | для таблиц
preserve_whitespace=False,
extract_metadata=True, # Извлечь метатеги
)
markdown = convert(html, options=options)
Командная утилита:
# Конвертировать один файл
html-to-markdown input.html -o output.md
# Конвертировать с параметрами
html-to-markdown input.html \
--heading-style atx \
--strip-tags script,style \
--extract-metadata
# Пакетная конвертация
find ./html_files -name "*.html" -exec html-to-markdown {} -o ./markdown_files/{}.md \;
Плюсы:
- Полная поддержка HTML5, включая семантические элементы
- Типобезопасность с комплексными подсказками типов
- Улучшенная обработка таблиц (объединенные ячейки, выравнивание)
- Возможности извлечения метаданных
- Активное развитие и современный код
Минусы:
- Требуется Python 3.9+
- Более крупная зависимость
- Сложнее кривая обучения
Лучше всего подходит: для сложных документов HTML5, типобезопасных проектов, производственных систем
4. trafilatura - специалист по извлечению контента
trafilatura — это не просто конвертер HTML в Markdown, это интеллектуальная библиотека извлечения контента, специально разработанная для веб-скрапинга и извлечения статей.
Установка:
pip install trafilatura
Базовое использование:
import trafilatura
# Загрузить и извлечь из URL
url = "https://example.com/article"
downloaded = trafilatura.fetch_url(url)
markdown = trafilatura.extract(downloaded, output_format='markdown')
print(markdown)
Примечание: Trafilatura включает встроенную загрузку URL, но для более сложных операций HTTP вы можете найти наш чек-лист cURL полезным при работе с API или аутентифицированными конечными точками.
Расширенное извлечение контента:
import trafilatura
from trafilatura.settings import use_config
# Создать пользовательскую конфигурацию
config = use_config()
config.set("DEFAULT", "EXTRACTION_TIMEOUT", "30")
html = """
<html>
<head><title>Название статьи</title></head>
<body>
<nav>Навигационное меню</nav>
<article>
<h1>Основная статья</h1>
<p>Важный контент здесь.</p>
</article>
<aside>Реклама</aside>
<footer>Контент подвал</footer>
</body>
</html>
"""
# Извлечь только основной контент
markdown = trafilatura.extract(
html,
output_format='markdown',
include_comments=False,
include_tables=True,
include_images=True,
include_links=True,
config=config
)
# Извлечь с метаданными
result = trafilatura.extract(
html,
output_format='markdown',
with_metadata=True
)
if result:
print(f"Заголовок: {result.get('title', 'N/A')}")
print(f"Автор: {result.get('author', 'N/A')}")
print(f"Дата: {result.get('date', 'N/A')}")
print(f"\nКонтент:\n{result.get('text', '')}")
Пакетная обработка:
import trafilatura
from concurrent.futures import ThreadPoolExecutor
from pathlib import Path
def process_url(url):
"""Извлечь Markdown из URL"""
downloaded = trafilatura.fetch_url(url)
if downloaded:
return trafilatura.extract(
downloaded,
output_format='markdown',
include_links=True,
include_images=True
)
return None
# Обработать несколько URL параллельно
urls = [
"https://example.com/article1",
"https://example.com/article2",
"https://example.com/article3",
]
with ThreadPoolExecutor(max_workers=5) as executor:
results = list(executor.map(process_url, urls))
for i, markdown in enumerate(results):
if markdown:
Path(f"article_{i}.md").write_text(markdown, encoding='utf-8')
Плюсы:
- Интеллектуальное извлечение контента (удаляет шаблоны)
- Встроенная загрузка URL с надежной обработкой ошибок
- Извлечение метаданных (заголовок, автор, дата)
- Обнаружение языка
- Оптимизировано для новостных статей и блогов
- Быстрый C-оптимизированный парсинг
Минусы:
- Может слишком много удалять контента для общего HTML
- Фокусируется на извлечении статей (не универсальный)
- Сложность настройки для крайних случаев
Лучше всего подходит: для веб-скрапинга, извлечения статей, подготовки данных для обучения LLM
5. domscribe - сохранитель семантики
domscribe фокусируется на сохранении семантического значения HTML при конвертации в Markdown.
Установка:
pip install domscribe
Базовое использование:
from domscribe import html_to_markdown
html = """
<article>
<header>
<h1>Понимание семантического HTML</h1>
<time datetime="2024-10-24">24 октября 2024 года</time>
</header>
<section>
<h2>Введение</h2>
<p>Семантический HTML добавляет <mark>значение</mark> к содержимому.</p>
</section>
<aside>
<h3>Связанные темы</h3>
<ul>
<li>Доступность</li>
<li>SEO</li>
</ul>
</aside>
</article>
"""
markdown = html_to_markdown(html)
print(markdown)
Пользовательские параметры:
from domscribe import html_to_markdown, MarkdownOptions
options = MarkdownOptions(
preserve_semantic_structure=True,
include_aria_labels=True,
strip_empty_elements=True
)
markdown = html_to_markdown(html, options=options)
Плюсы:
- Сохраняет семантическую структуру HTML5
- Хорошо обрабатывает современные веб-компоненты
- Чистый дизайн API
Минусы:
- Все еще в ранней разработке (API может измениться)
- Ограниченная документация по сравнению с более зрелыми альтернативами
- Меньшее сообщество и меньше примеров доступны
Лучше всего подходит: для семантических документов HTML5, проектов, ориентированных на доступность, когда сохранение семантической структуры HTML5 критично
Примечание: Хотя domscribe новее и менее проверен, чем альтернативы, он заполняет конкретную нишу сохранения семантики HTML, которую другие инструменты не приоритизируют.
6. html2md - асинхронная мощность
html2md разработан для высокопроизводительных пакетных конверсий с асинхронной обработкой.
Установка:
pip install html2md
Командная строка:
# Конвертировать целую директорию
m1f-html2md convert ./website -o ./docs
# С настройками
m1f-html2md convert ./website -o ./docs \
--remove-tags nav,footer \
--heading-offset 1 \
--detect-language
# Конвертировать один файл
m1f-html2md convert index.html -o readme.md
Программное использование:
import asyncio
from html2md import convert_html
async def convert_files():
"""Асинхронная пакетная конвертация"""
html_files = [
'page1.html',
'page2.html',
'page3.html'
]
tasks = [convert_html(file) for file in html_files]
results = await asyncio.gather(*tasks)
return results
# Запустить конвертацию
results = asyncio.run(convert_files())
Плюсы:
- Асинхронная обработка для высокой производительности
- Интеллектуальное обнаружение селектора контента
- Генерация YAML frontmatter (отлично подходит для Hugo!)
- Обнаружение языка кода
- Поддержка параллельной обработки
Минусы:
- Требуется Python 3.10+
- CLI-ориентирован (менее гибкий API)
- Документация могла бы быть более подробной
Лучше всего подходит: для крупномасштабных миграций, пакетных конверсий, миграций Hugo/Jekyll
Тестирование производительности
Производительность важна, особенно при обработке тысяч документов для обучения LLM или крупномасштабных миграций. Понимание относительных различий в скорости между библиотеками помогает вам принимать обоснованные решения для вашего рабочего процесса.
Сравнительный анализ производительности:
На основе типичных паттернов использования вот как эти библиотеки сравниваются в трех реалистичных сценариях:
- Простой HTML: Базовый блог-пост с текстом, заголовками и ссылками (5КБ)
- Сложный HTML: Техническая документация с вложенными таблицами и блоками кода (50КБ)
- Реальный веб-сайт: Полная веб-страница, включающая навигацию, подвал, боковую панель и рекламу (200КБ)
Вот пример кода тестирования, который вы можете использовать для тестирования этих библиотек самостоятельно:
import time
import html2text
from markdownify import markdownify
from html_to_markdown import convert
import trafilatura
def benchmark(html_content, iterations=100):
"""Тестирование скорости конвертации"""
# html2text
start = time.time()
h = html2text.HTML2Text()
for _ in range(iterations):
_ = h.handle(html_content)
html2text_time = time.time() - start
# markdownify
start = time.time()
for _ in range(iterations):
_ = markdownify(html_content)
markdownify_time = time.time() - start
# html-to-markdown
start = time.time()
for _ in range(iterations):
_ = convert(html_content)
html_to_markdown_time = time.time() - start
# trafilatura
start = time.time()
for _ in range(iterations):
_ = trafilatura.extract(html_content, output_format='markdown')
trafilatura_time = time.time() - start
return {
'html2text': html2text_time,
'markdownify': markdownify_time,
'html-to-markdown': html_to_markdown_time,
'trafilatura': trafilatura_time
}
Типичные характеристики производительности (представительные относительные скорости):
| Пакет | Простой (5КБ) | Сложный (50КБ) | Реальный сайт (200КБ) |
|---|---|---|---|
| html2text | Средняя | Медленнее | Медленнее |
| markdownify | Медленнее | Медленнее | Самый медленный |
| html-to-markdown | Быстрый | Быстрый | Быстрый |
| trafilatura | Быстрый | Очень быстрый | Очень быстрый |
| html2md (асинхронный) | Очень быстрый | Очень быстрый | Самый быстрый |
Основные наблюдения:
html2mdиtrafilaturaсамые быстрые для сложных документов, делая их идеальными для пакетной обработкиhtml-to-markdownпредлагает лучшее соотношение скорости и функций для использования в производствеmarkdownifyмедленнее, но более гибкий — компромисс оправдан, когда вам нужны пользовательские обработчикиhtml2textпоказывает свой возраст с медленной производительностью, но остается стабильным для простых случаев использования
Примечание: Различия в производительности становятся значительными только при обработке сотен или тысяч файлов. Для редких конверсий любой инструмент будет работать нормально. Сосредоточьтесь на функциях и настройке вместо этого.
Реальные случаи использования
Теория полезна, но практические примеры демонстрируют, как эти инструменты работают в производстве. Вот четыре распространенных сценария с полным, готовым к использованию кодом, который вы можете адаптировать для своих проектов.
Случай использования 1: Подготовка данных для обучения LLM
Требование: Извлечь чистый текст из тысяч страниц документации
Рекомендуется: trafilatura + параллельная обработка
import trafilatura
from pathlib import Path
from concurrent.futures import ProcessPoolExecutor
def process_html_file(html_path):
"""Конвертировать HTML-файл в Markdown"""
html = Path(html_path).read_text(encoding='utf-8')
markdown = trafilatura.extract(
html,
output_format='markdown',
include_links=False, # Удалить для более чистых данных обучения
include_images=False,
include_comments=False
)
if markdown:
output_path = html_path.replace('.html', '.md')
Path(output_path).write_text(markdown, encoding='utf-8')
return len(markdown)
return 0
# Обработать 10 000 файлов параллельно
html_files = list(Path('./docs').rglob('*.html'))
with ProcessPoolExecutor(max_workers=8) as executor:
token_counts = list(executor.map(process_html_file, html_files))
print(f"Обработано {len(html_files)} файлов")
print(f"Общее количество символов: {sum(token_counts):,}")
Случай использования 2: Миграция блога на Hugo
Требование: Мигрировать блог WordPress на Hugo с frontmatter
Рекомендуется: html2md CLI
Hugo — популярный статический генератор сайтов, использующий Markdown для контента. Для получения дополнительных советов по Hugo, ознакомьтесь с нашим чек-листом Hugo и узнайте о добавлении структурированных данных в Hugo для лучшего SEO. В нашем хабе инструментов документации есть больше руководств по рабочим процессам Markdown и конвертации документов.
# Конвертировать все посты с frontmatter
m1f-html2md convert ./wordpress-export \
-o ./hugo/content/posts \
--generate-frontmatter \
--heading-offset 0 \
--remove-tags script,style,nav,footer
Или программно:
from html_to_markdown import convert, Options
from pathlib import Path
import yaml
def migrate_post(html_file):
"""Конвертировать HTML WordPress в Markdown Hugo"""
html = Path(html_file).read_text()
# Извлечь заголовок и дату из HTML
from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'html.parser')
title = soup.find('h1').get_text() if soup.find('h1') else 'Без названия'
# Конвертировать в Markdown
options = Options(strip_tags=['script', 'style', 'nav', 'footer'])
markdown = convert(html, options=options)
# Добавить frontmatter Hugo
frontmatter = {
'title': title,
'date': '2024-10-24',
'draft': False,
'tags': []
}
output = f"---\n{yaml.dump(frontmatter)}---\n\n{markdown}"
# Сохранить
output_file = html_file.replace('.html', '.md')
Path(output_file).write_text(output, encoding='utf-8')
# Обработать все посты
for html_file in Path('./wordpress-export').glob('*.html'):
migrate_post(html_file)
Случай использования 3: Скрапер документации с пользовательским форматированием
Требование: Скрапировать технические документы с пользовательской обработкой блоков кода
Рекомендуется: markdownify с пользовательским конвертером
Этот подход особенно полезен для миграции документации из wiki-систем. Если вы управляете документацией, вы также можете быть заинтересованы в DokuWiki - саморасполагающийся wiki и альтернативы для решений по саморасполагающейся документации.
from markdownify import MarkdownConverter
import requests
class DocsConverter(MarkdownConverter):
"""Пользовательский конвертер для технической документации"""
def convert_pre(self, el, text, convert_as_inline):
"""Улучшенный кодовый блок с подсветкой синтаксиса"""
code = el.find('code')
if code:
# Извлечь язык из класса
classes = code.get('class', [])
language = next(
(c.replace('language-', '') for c in classes if c.startswith('language-')),
'text'
)
return f'\n```{language}\n{code.get_text()}\n```\n'
return super().convert_pre(el, text, convert_as_inline)
def convert_div(self, el, text, convert_as_inline):
"""Обработка специальных блоков документации"""
classes = el.get('class', [])
# Блоки предупреждений
if 'warning' in classes:
return f'\n> ⚠️ **Предупреждение**: {text}\n'
# Блоки информации
if 'info' in classes or 'note' in classes:
return f'\n> 💡 **Примечание**: {text}\n'
return text
def scrape_docs(url):
"""Скрапировать и конвертировать страницу документации"""
response = requests.get(url)
markdown = DocsConverter().convert(response.text)
return markdown
# Использовать его
docs_url = "https://docs.example.com/api-reference"
markdown = scrape_docs(docs_url)
Path('api-reference.md').write_text(markdown)
Случай использования 4: Архив новостных писем в Markdown
Требование: Конвертировать HTML-письма новостных рассылок в читаемый Markdown
Рекомендуется: html2text с конкретной настройкой
import html2text
import email
from pathlib import Path
def convert_newsletter(email_file):
"""Конвертировать HTML-письмо в Markdown"""
# Парсить письмо
with open(email_file, 'r') as f:
msg = email.message_from_file(f)
# Получить HTML-часть
html_content = None
for part in msg.walk():
if part.get_content_type() == 'text/html':
html_content = part.get_payload(decode=True).decode('utf-8')
break
if not html_content:
return None
# Настроить конвертер
h = html2text.HTML2Text()
h.ignore_images = False
h.images_to_alt = True
h.body_width = 0
h.protect_links = True
h.unicode_snob = True
# Конвертировать
markdown = h.handle(html_content)
# Добавить метаданные
subject = msg.get('Subject', 'Нет темы')
date = msg.get('Date', '')
output = f"# {subject}\n\n*Дата: {date}*\n\n---\n\n{markdown}"
return output
# Обработать архив новостных писем
for email_file in Path('./newsletters').glob('*.eml'):
markdown = convert_newsletter(email_file)
if markdown:
output_file = email_file.with_suffix('.md')
output_file.write_text(markdown, encoding='utf-8')
Рекомендации по сценарию
Еще не уверены, какой библиотеку выбрать? Вот руководство, основанное на конкретных сценариях использования.
Для веб-скрапинга и предварительной обработки LLM
Победитель: trafilatura
Trafilatura отлично справляется с извлечением чистого контента, удаляя шаблоны. Идеально подходит для:
- Создания наборов данных для обучения LLM
- Агрегации контента
- Сбора исследовательских статей
- Извлечения новостных статей
Для миграции на Hugo/Jekyll
Победитель: html2md
Асинхронная обработка и генерация frontmatter делают массовые миграции быстрыми и простыми:
- Пакетная конвертация
- Автоматическое извлечение метаданных
- Генерация YAML frontmatter
- Настройка уровня заголовков
Для пользовательской логики конвертации
Победитель: markdownify
Наследуйте конвертер для полного контроля:
- Пользовательские обработчики тегов
- Доменные специфические конвертации
- Специальные требования к форматированию
- Интеграция с существующим кодом BeautifulSoup
Для типобезопасных производственных систем
Победитель: html-to-markdown
Современный, типобезопасный и функционально полный:
- Полная поддержка HTML5
- Комплексные подсказки типов
- Расширенная обработка таблиц
- Активное обслуживание
Для простых, стабильных конвертаций
Победитель: html2text
Когда вам нужен инструмент, который “просто работает”:
- Нет зависимостей
- Проверен временем
- Широкие возможности настройки
- Широкая поддержка платформ
Лучшие практики предварительной обработки LLM
Независимо от того, какую библиотеку вы выберете, следование этим лучшим практикам обеспечит высококачественный вывод в формате Markdown, оптимизированный для потребления LLM. Эти шаблоны доказали свою эффективность в производственных рабочих процессах, обрабатывающих миллионы документов.
1. Очистка перед преобразованием
Всегда удаляйте нежелательные элементы перед преобразованием, чтобы получить более чистый вывод и повысить производительность:
from bs4 import BeautifulSoup
import trafilatura
def clean_and_convert(html):
"""Удалите нежелательные элементы перед преобразованием"""
soup = BeautifulSoup(html, 'html.parser')
# Удалите нежелательные элементы
for element in soup(['script', 'style', 'nav', 'footer', 'header', 'aside']):
element.decompose()
# Удалите рекламу и отслеживание
for element in soup.find_all(class_=['ad', 'advertisement', 'tracking']):
element.decompose()
# Преобразуйте очищенный HTML
markdown = trafilatura.extract(
str(soup),
output_format='markdown'
)
return markdown
2. Нормализация пробелов
Разные конвертеры обрабатывают пробелы по-разному. Нормализуйте вывод, чтобы обеспечить согласованность по всему вашему корпусу:
import re
def normalize_markdown(markdown):
"""Очистите пространство в markdown"""
# Удалите несколько пустых строк
markdown = re.sub(r'\n{3,}', '\n\n', markdown)
# Удалите конечное пространство
markdown = '\n'.join(line.rstrip() for line in markdown.split('\n'))
# Убедитесь, что в конце одна новая строка
markdown = markdown.rstrip() + '\n'
return markdown
3. Проверка вывода
Контроль качества необходим. Реализуйте проверку, чтобы выявлять ошибки преобразования на ранних этапах:
def validate_markdown(markdown):
"""Проверка качества markdown"""
issues = []
# Проверка на остатки HTML
if '<' in markdown and '>' in markdown:
issues.append("Обнаружены теги HTML")
# Проверка на поврежденные ссылки
if '[' in markdown and ']()' in markdown:
issues.append("Обнаружена пустая ссылка")
# Проверка на избыточные блоки кода
code_block_count = markdown.count('```')
if code_block_count % 2 != 0:
issues.append("Незакрытый блок кода")
return len(issues) == 0, issues
4. Шаблон для пакетной обработки
При обработке больших коллекций документов используйте этот готовый для использования шаблон с правильной обработкой ошибок, логированием и параллельной обработкой:
from pathlib import Path
from concurrent.futures import ProcessPoolExecutor
import trafilatura
import logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
def process_file(html_path):
"""Обработка одного HTML-файла"""
try:
html = Path(html_path).read_text(encoding='utf-8')
markdown = trafilatura.extract(
html,
output_format='markdown',
include_links=True,
include_images=False
)
if markdown:
# Нормализация
markdown = normalize_markdown(markdown)
# Проверка
is_valid, issues = validate_markdown(markdown)
if not is_valid:
logger.warning(f"{html_path}: {', '.join(issues)}")
# Сохранение
output_path = Path(str(html_path).replace('.html', '.md'))
output_path.write_text(markdown, encoding='utf-8')
return True
return False
except Exception as e:
logger.error(f"Ошибка при обработке {html_path}: {e}")
return False
def batch_convert(input_dir, max_workers=4):
"""Конвертировать все HTML-файлы в директории"""
html_files = list(Path(input_dir).rglob('*.html'))
logger.info(f"Найдено {len(html_files)} HTML-файлов")
with ProcessPoolExecutor(max_workers=max_workers) as executor:
results = list(executor.map(process_file, html_files))
success_count = sum(results)
logger.info(f"Успешно сконвертировано {success_count}/{len(html_files)} файлов")
# Использование
batch_convert('./html_docs', max_workers=8)
Заключение
Экосистема Python предлагает зрелые, готовые к использованию инструменты для преобразования HTML в Markdown, каждый из которых оптимизирован для разных сценариев. Ваш выбор должен соответствовать вашим конкретным требованиям:
- Быстрые преобразования: Используйте
html2textиз-за его простоты и отсутствия зависимостей - Пользовательская логика: Используйте
markdownifyдля максимальной гибкости через наследование - Скрапинг с веб-сайтов: Используйте
trafilaturaдля умного извлечения контента с удалением ненужного - Масштабные миграции: Используйте
html2mdдля асинхронной производительности на крупных проектах - Производственные системы: Используйте
html-to-markdownдля типобезопасности и комплексной поддержки HTML5 - Сохранение семантики: Используйте
domscribeдля сохранения семантической структуры HTML5
Рекомендации для рабочих процессов LLM
Для рабочих процессов предварительной обработки LLM рекомендуется двухэтапный подход:
- Начните с
trafilaturaдля извлечения первоначального контента — он умно удаляет навигацию, рекламу и шаблоны, сохраняя основной контент - Перейдите на
html-to-markdownдля сложных документов, требующих точного сохранения структуры, таких как техническая документация с таблицами и блоками кода
Это сочетание эффективно решает 95% реальных сценариев.
Дальнейшие действия
Для получения дополнительных руководств по обработке Markdown, LaTeX, PDF и печати документов см. Инструменты документации 2026: Markdown, LaTeX, PDF и рабочие процессы печати.
Все эти инструменты (кроме html2text) активно поддерживаются и готовы к использованию в производстве. Лучше:
- Установите 2–3 библиотеки, соответствующие вашему случаю использования
- Протестируйте их с вашими реальными образцами HTML
- Проведите тестирование производительности с типичными размерами документов
- Выберите на основе качества вывода, а не только скорости
Экосистема Python для преобразования HTML в Markdown значительно созрела, и вы не ошибетесь с любым из этих выборов для их целевых случаев использования.
Дополнительные ресурсы
- Документация html2text
- markdownify на PyPI
- html-to-markdown на GitHub
- Документация trafilatura
- Документация html2md
- domscribe на PyPI
Примечание: Это сравнение основано на анализе официальной документации, отзывов сообщества и архитектуры библиотек. Характеристики производительности являются представительными для типичных сценариев использования. Для конкретных случаев использования проведите собственные тесты с вашими реальными образцами HTML.
Другие полезные статьи
- Инструменты документации 2026: Markdown, LaTeX, PDF и рабочие процессы печати
- Справочник по Markdown
- Использование блоков кода Markdown
- Преобразование документов Word в Markdown: полное руководство
- Конвертация HTML-содержимого в Markdown с использованием LLM и Ollama
- Справочник по cURL
- Справочник по генератору статических сайтов Hugo
- Dokuwiki - локальный вики и альтернативы
- Использование Obsidian для управления личными знаниями