Konwersja HTML na Markdown za pomocą Pythona: Kompletny przewodnik
Python do konwersji HTML na czysty, gotowy do przetwarzania przez LLM Markdown
Konwersja HTML na Markdown to fundamentalna czynność w nowoczesnych przepływach pracy programistycznych, szczególnie przygotowując treści sieciowe do Large Language Models (LLM), systemów dokumentacji lub generatorów stron statycznych takich jak Hugo. Niniejszy przewodnik jest częścią naszego Narzędzi do Dokumentacji w 2026: Markdown, LaTeX, PDF i Pracy z Drukowaniem.
Choć HTML jest zaprojektowany dla przeglądarek internetowych z bogatym stylizowaniem i strukturą, Markdown oferuje czysty, czytelny format idealny do przetwarzania tekstu, kontroli wersji i konsumpcji przez AI. Jeśli jesteś nowy w składni Markdown, sprawdź nasz Podręcznik skrótów Markdown dla kompletnego odniesienia.

W tej szczegółowej recenzji omówimy sześć pakietów Pythona do konwersji HTML na Markdown, dostarczając praktyczne przykłady kodu, wyniki testów wydajności i rzeczywiste przypadki użycia. Niezależnie od tego, czy budujesz pipeline treningowy LLM, czy migrujesz bloga do Hugoa, czy skrapujesz dokumentację, znajdziesz idealne narzędzie dla swojego przepływu pracy.
Alternatywny podejście: Jeśli potrzebujesz bardziej inteligentnego wyodrębniania treści z zrozumieniem semantycznym, rozważ również konwersję HTML na Markdown za pomocą LLM i Ollama, która oferuje AI-powered konwersję dla złożonych układów.
Nauczysz się:
- Szczegółowa analiza 6 bibliotek z zaletami i wadami każdej
- Wyniki testów wydajności z rzeczywistymi przykładami HTML
- Przykłady kodu gotowe do produkcji dla typowych przypadków użycia
- Najlepsze praktyki dla przepływów pracy przygotowania danych do LLM
- Konkretnych rekomendacji na podstawie Twoich wymagań
Dlaczego Markdown dla przygotowania danych do LLM?
Przed zanurzeniem się w narzędziach, zrozummy dlaczego Markdown jest szczególnie wartościowy dla przepływów pracy LLM:
- Efektywność tokenów: Markdown zużywa znacznie mniej tokenów niż HTML dla tej samej treści
- Jasność semantyczna: Markdown zachowuje strukturę dokumentu bez zbędnych tagów
- Czytelność: zarówno ludzie, jak i LLM mogą łatwo przetwarzać składnię Markdown
- Spójność: standardowy format zmniejsza niejednoznaczność we wejściach modelu
- Przechowywanie: mniejsze rozmiary plików dla danych treningowych i okien kontekstowych
Wersatylność Markdown rozciąga się poza konwersję HTML – możesz również konwertować dokumenty Word na Markdown dla przepływów pracy dokumentacji, lub używać go w systemach zarządzania wiedzą takich jak Obsidian do zarządzania osobistą wiedzą. Aby dowiedzieć się więcej o konwersji dokumentów i formatowaniu w Markdown, LaTeX i PDF, zobacz Hub Narzędzi do Dokumentacji.
TL;DR - Macierz szybkiego porównania
Jeśli jesteś w pośpiechu, oto kompletny przegląd wszystkich sześciu bibliotek w jednym wzorcu. Ta tabela pomoże Ci szybko zidentyfikować, które narzędzie pasuje do Twoich konkretnych wymagań:
| Funkcja | html2text | markdownify | html-to-markdown | trafilatura | domscribe | html2md |
|---|---|---|---|---|---|---|
| Wsparcie HTML5 | Częściowe | Częściowe | Pełne | Pełne | Pełne | Pełne |
| Wskazówki typu | Brak | Brak | Tak | Częściowe | Brak | Częściowe |
| Niestandardowe procedury | Ograniczone | Wspaniałe | Dobre | Ograniczone | Dobre | Ograniczone |
| Wsparcie dla tabel | Podstawowe | Podstawowe | Zaawansowane | Dobre | Dobre | Dobre |
| Wsparcie asynchroniczne | Brak | Brak | Brak | Brak | Brak | Tak |
| Wyodrębnianie treści | Brak | Brak | Brak | Wspaniałe | Brak | Dobre |
| Wyodrębnianie metadanych | Brak | Brak | Tak | Wspaniałe | Brak | Tak |
| Narzędzie CLI | Brak | Brak | Tak | Tak | Brak | Tak |
| Szybkość | Średnia | Wolna | Szybka | Bardzo szybka | Średnia | Bardzo szybka |
| Aktywne rozwijanie | Brak | Tak | Tak | Tak | Ograniczone | Tak |
| Wersja Pythona | 3.6+ | 3.7+ | 3.9+ | 3.6+ | 3.8+ | 3.10+ |
| Zależności | Brak | BS4 | lxml | lxml | BS4 | aiohttp |
Szybki przewodnik wyboru:
- Potrzebujesz szybkości? → trafilatura lub html2md
- Potrzebujesz dostosowania? → markdownify
- Potrzebujesz bezpieczeństwa typu? → html-to-markdown
- Potrzebujesz prostoty? → html2text
- Potrzebujesz wyodrębniania treści? → trafilatura
Konkurenci: 6 porównanych pakietów Pythona
Zanurzmy się głęboko w każdy z bibliotek z praktycznymi przykładami kodu, opcjami konfiguracji i rzeczywistymi wglądami. Każda sekcja zawiera instrukcje instalacji, wzorce użycia i szczere oceny zalet i ograniczeń.
1. html2text - Klasyczna opcja
Oryginalnie opracowany przez Aaron Swartza, html2text był stalowym elementem w ekosystemie Pythona przez ponad dekadę. Skupia się na generowaniu czystego, czytelnego wyjścia w formacie Markdown.
Instalacja:
pip install html2text
Podstawowe użycie:
import html2text
# Utwórz instancję konwertera
h = html2text.HTML2Text()
# Skonfiguruj opcje
h.ignore_links = False
h.ignore_images = False
h.ignore_emphasis = False
h.body_width = 0 # Nie zapisuj linii
html_content = """
<h1>Witaj w Web Scraping</h1>
<p>To jest <strong>kompleksowy przewodnik</strong> po wyodrębnianiu treści.</p>
<ul>
<li>Łatwe w użyciu</li>
<li>Przetestowane w praktyce</li>
<li>Szeroko stosowane</li>
</ul>
<a href="https://example.com">Dowiedz się więcej</a>
"""
markdown = h.handle(html_content)
print(markdown)
Wyjście:
# Witaj w Web Scraping
To jest **kompleksowy przewodnik** po wyodrębnianiu treści.
* Łatwe w użyciu
* Przetestowane w praktyce
* Szeroko stosowane
[Wyświetl więcej](https://example.com)
Zaawansowana konfiguracja:
import html2text
h = html2text.HTML2Text()
# Pominięcie określonych elementów
h.ignore_links = True
h.ignore_images = True
# Kontrola formatowania
h.body_width = 80 # Zapisuj przy 80 znakach
h.unicode_snob = True # Użyj znaków unicode
h.emphasis_mark = '*' # Użyj * do podkreślania zamiast _
h.strong_mark = '**'
# Obsługa tabel
h.ignore_tables = False
# Ochrona tekstu sformatowanego
h.protect_links = True
Zalety:
- Dojrzała i stabilna (15+ lat rozwoju)
- Rozszerzona konfiguracja opcji
- Dobrze radzi sobie z przypadkami granicznymi
- Brak zależności zewnętrznych
Wady:
- Ograniczone wsparcie dla HTML5
- Może generować niezgodne odstępy
- Nie jest aktywnie utrzymywany (ostatnia większa aktualizacja w 2020 roku)
- Tylko przetwarzanie w jednym wątku
Najlepsze do: Prostych dokumentów HTML, systemów legacy, gdy stabilność jest najważniejsza
2. markdownify - Opcja elastyczna
markdownify wykorzystuje BeautifulSoup4, aby zapewnić elastyczne parsowanie HTML z niestandardowymi procedurami obsługi tagów.
Instalacja:
pip install markdownify
Podstawowe użycie:
from markdownify import markdownify as md
html = """
<article>
<h2>Nowoczesne Web Development</h2>
<p>Budowanie z <code>Python</code> i <em>nowoczesnymi frameworkami</em>.</p>
<blockquote>
<p>Prostota to ostateczna elegancja.</p>
</blockquote>
</article>
"""
markdown = md(html)
print(markdown)
Wyjście:
## Nowoczesne Web Development
Budowanie z `Python` i *nowoczesnymi frameworkami*.
> Prostota to ostateczna elegancja.
Zaawansowane użycie z niestandardowymi procedurami:
from markdownify import MarkdownConverter
class CustomConverter(MarkdownConverter):
"""
Utwórz niestandardowy konwerter z konkretnym obsługą tagów
"""
def convert_img(self, el, text, convert_as_inline):
"""Niestandardowa obsługa obrazu z tekstem alternatywnym"""
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):
"""Zwiększone obsługa bloków kodu z wykrywaniem języka"""
code = el.find('code')
if code:
# Wyodrębnij język z atrybutu klasy (np. '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'
# Użyj niestandardowego konwertera
html = '<pre><code class="language-python">def hello():\n print("world")</code></pre>'
markdown = CustomConverter().convert(html)
print(markdown)
Dla więcej szczegółów na temat pracy z blokami kodu w Markdown i podświetlania składni, zobacz nasz przewodnik Użycie bloków kodu w Markdown.
Wybór konwersji tagów:
from markdownify import markdownify as md
# Usuń określone tagi całkowicie
markdown = md(html, strip=['script', 'style', 'nav'])
# Konwertuj tylko określone tagi
markdown = md(
html,
heading_style="ATX", # Użyj # dla nagłówków
bullets="-", # Użyj - dla punktów
strong_em_symbol="*", # Użyj * dla podkreślania
)
Zalety:
- Oparty na BeautifulSoup4 (solidne parsowanie HTML)
- Bardzo elastyczny dzięki dziedziczeniu
- Aktywne utrzymanie
- Dobra dokumentacja
Wady:
- Wymaga zależności BeautifulSoup4
- Może być wolniejszy dla dużych dokumentów
- Ograniczone wsparcie dla tabel
Najlepsze do: Niestandardowej konwersji, projektów już korzystających z BeautifulSoup4
3. html-to-markdown - Nowoczesna potęga
html-to-markdown to kompletnie typowana, nowoczesna biblioteka z wszechstronnym wsparciem HTML5 i szerokimi opcjami konfiguracji.
Instalacja:
pip install html-to-markdown
Podstawowe użycie:
from html_to_markdown import convert
html = """
<article>
<h1>Dokumentacja techniczna</h1>
<table>
<thead>
<tr>
<th>Funkcja</th>
<th>Wsparcie</th>
</tr>
</thead>
<tbody>
<tr>
<td>HTML5</td>
<td>✓</td>
</tr>
<tr>
<td>Tabele</td>
<td>✓</td>
</tr>
</tbody>
</table>
</article>
"""
markdown = convert(html)
print(markdown)
Zaawansowana konfiguracja:
from html_to_markdown import convert, Options
# Utwórz niestandardowe opcje
options = Options(
heading_style="ATX",
bullet_style="-",
code_language_default="python",
strip_tags=["script", "style"],
escape_special_chars=True,
table_style="pipe", # Użyj | dla tabel
preserve_whitespace=False,
extract_metadata=True, # Wyodrębnij tagi meta
)
markdown = convert(html, options=options)
Interfejs wiersza poleceń:
# Konwertuj pojedynczy plik
html-to-markdown input.html -o output.md
# Konwertuj z opcjami
html-to-markdown input.html \
--heading-style atx \
--strip-tags script,style \
--extract-metadata
# Konwersja wsadowa
find ./html_files -name "*.html" -exec html-to-markdown {} -o ./markdown_files/{}.md \;
Zalety:
- Pełne wsparcie HTML5 w tym elementy semantyczne
- Typowo bezpieczne z komprehensywnymi wskazówkami typu
- Zwiększone obsługa tabel (scalane komórki, wyrównanie)
- Możliwość wyodrębniania metadanych
- Aktywne rozwijanie i nowoczesna baza kodu
Wady:
- Wymaga Pythona 3.9+
- Większa ilość zależności
- Wysoki poziom nauczania
Najlepsze do: Złożonych dokumentów HTML5, projektów typowo bezpiecznych, systemów produkcyjnych
4. trafilatura - Specjalista do wyodrębniania treści
trafilatura to nie tylko konwerter HTML na Markdown – to inteligentna biblioteka do wyodrębniania treści specjalnie zaprojektowana do skrapowania sieci i ekstrakcji artykułów.
Instalacja:
pip install trafilatura
Podstawowe użycie:
import trafilatura
# Pobierz i wyodrębnij z URL
url = "https://example.com/article"
downloaded = trafilatura.fetch_url(url)
markdown = trafilatura.extract(downloaded, output_format='markdown')
print(markdown)
Uwaga: Trafilatura zawiera wbudowane pobieranie URL, ale dla bardziej złożonych operacji HTTP, możesz znaleźć pomocny nasz Podręcznik cURL przy pracy z API lub punktami końcowymi uwierzytelnionymi.
Zaawansowane wyodrębnianie treści:
import trafilatura
from trafilatura.settings import use_config
# Utwórz niestandardową konfigurację
config = use_config()
config.set("DEFAULT", "EXTRACTION_TIMEOUT", "30")
html = """
<html>
<head><title>Tytuł artykułu</title></head>
<body>
<nav>Menu nawigacyjne</nav>
<article>
<h1>Główny artykuł</h1>
<p>Ważna treść tutaj.</p>
</article>
<aside>Reklama</aside>
<footer>Treść stopki</footer>
</body>
</html>
"""
# Wyodrębnij tylko główną treść
markdown = trafilatura.extract(
html,
output_format='markdown',
include_comments=False,
include_tables=True,
include_images=True,
include_links=True,
config=config
)
# Wyodrębnij z metadane
result = trafilatura.extract(
html,
output_format='markdown',
with_metadata=True
)
if result:
print(f"Tytuł: {result.get('title', 'N/A')}")
print(f"Autor: {result.get('author', 'N/A')}")
print(f"Data: {result.get('date', 'N/A')}")
print(f"\nTreść:\n{result.get('text', '')}")
Przetwarzanie wsadowe:
import trafilatura
from concurrent.futures import ThreadPoolExecutor
from pathlib import Path
def process_url(url):
"""Wyodrębnij markdown z URL"""
downloaded = trafilatura.fetch_url(url)
if downloaded:
return trafilatura.extract(
downloaded,
output_format='markdown',
include_links=True,
include_images=True
)
return None
# Przetwarzanie wielu URL w równoległości
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')
Zalety:
- Inteligentne wyodrębnianie treści (usuwa boilerplate)
- Wbudowane pobieranie URL z solidnymi mechanizmami obsługi błędów
- Wyodrębnianie metadanych (tytuł, autor, data)
- Wykrywanie języka
- Optymalizacja dla artykułów i blogów
- Szybkie przetwarzanie w C
Wady:
- Może zbyt dużo usuwać treści dla ogólnego HTML
- Skupiony na ekstrakcji artykułów (nie ogólne)
- Złożoność konfiguracji dla przypadków granicznych
Najlepsze do: Skrapowania sieci, ekstrakcji artykułów, przygotowania danych treningowych dla LLM
5. domscribe - Przechowujący znaczenie semantyczne
domscribe skupia się na zachowaniu znaczenia semantycznego HTML podczas konwersji na Markdown.
Instalacja:
pip install domscribe
Podstawowe użycie:
from domscribe import html_to_markdown
html = """
<article>
<header>
<h1>Zrozumienie semantycznego HTML</h1>
<time datetime="2024-10-24">24 października 2024</time>
</header>
<section>
<h2>Wprowadzenie</h2>
<p>Semantyczne HTML nadaje <mark>znaczenie</mark> treści.</p>
</section>
<aside>
<h3>Powiązane tematy</h3>
<ul>
<li>Dostępność</li>
<li>SEO</li>
</ul>
</aside>
</article>
"""
markdown = html_to_markdown(html)
print(markdown)
Niestandardowe opcje:
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)
Zalety:
- Zachowuje strukturę HTML5 semantyczną
- Dobrze radzi sobie z nowoczesnymi komponentami sieciowymi
- Czysty projekt API
Wady:
- Nadal w wczesnym rozwoju (API może się zmienić)
- Ograniczona dokumentacja w porównaniu do dojrzałych alternatyw
- Mniejsza społeczność i mniej dostępnych przykładów
Najlepsze do: Dokumentów HTML5 semantycznych, projektów skupionych na dostępności, gdy zachowanie struktury semantycznej HTML5 jest krytyczne
Uwaga: Choć domscribe jest nowszy i mniej testowany niż alternatywy, wypełnia konkretny niszowy wymóg dla zachowania semantycznego HTML, którego inne narzędzia nie priorytetyzują.
6. html2md - Potęga asynchroniczna
html2md jest zaprojektowany do wysokiej wydajności wsadowej konwersji z asynchronicznym przetwarzaniem.
Instalacja:
pip install html2md
Użycie wiersza poleceń:
# Konwertuj całą katalog
m1f-html2md convert ./website -o ./docs
# Z niestandardowymi ustawieniami
m1f-html2md convert ./website -o ./docs \
--remove-tags nav,footer \
--heading-offset 1 \
--detect-language
# Konwertuj pojedynczy plik
m1f-html2md convert index.html -o readme.md
Użycie programistyczne:
import asyncio
from html2md import convert_html
async def convert_files():
"""Asynchroniczna konwersja wsadowa"""
html_files = [
'page1.html',
'page2.html',
'page3.html'
]
tasks = [convert_html(file) for file in html_files]
results = await asyncio.gather(*tasks)
return results
# Uruchom konwersję
results = asyncio.run(convert_files())
Zalety:
- Asynchroniczne przetwarzanie dla wysokiej wydajności
- Inteligentne wykrywanie selektorów treści
- Generowanie YAML frontmatter (wspaniałe dla Hugoa!)
- Wykrywanie języka kodu
- Wsparcie dla przetwarzania równoległego
Wady:
- Wymaga Pythona 3.10+
- CLI-orientowane (mniej elastyczny API)
- Dokumentacja mogła być bardziej kompletna
Najlepsze do: Dużych migracji, konwersji wsadowych, migracji Hugo/Jekyll
Testowanie wydajności
Wydajność ma znaczenie, szczególnie przy przetwarzaniu tysięcy dokumentów do treningu LLM lub dużych migracji. Zrozumienie różnic w prędkości między bibliotekami pomaga w podejmowaniu świadomych decyzji dla Twojego przepływu pracy.
Porównanie wydajności:
Na podstawie typowych wzorców użycia, oto jak te biblioteki porównują się w trzech realistycznych scenariuszach:
- Prosty HTML: Podstawowy wpis blogowy z tekstem, nagłówkami i linkami (5KB)
- Złożony HTML: Dokumentacja techniczna z zagnieżdżonymi tabelami i blokami kodu (50KB)
- Rzeczywista strona internetowa: Pełna strona internetowa zawierająca nawigację, stopkę, sidebar i reklamy (200KB)
Oto przykład kodu testowego, który możesz użyć, aby samodzielnie przetestować te biblioteki:
import time
import html2text
from markdownify import markdownify
from html_to_markdown import convert
import trafilatura
def benchmark(html_content, iterations=100):
"""Testowanie szybkości konwersji"""
# 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': html2线时间,
'markdownify': markdownify_time,
'html-to-markdown': html_to_markdown_time,
'trafilatura': trafilatura_time
}
Typowe cechy wydajności (przykładowe względne prędkości):
| Pakiet | Prosty (5KB) | Złożony (50KB) | Rzeczywista strona (200KB) |
|---|---|---|---|
| html2text | Średnia | Wolniejsza | Wolniejsza |
| markdownify | Wolniejsza | Wolniejsza | Najwolniejsza |
| html-to-markdown | Szybka | Szybka | Szybka |
| trafilatura | Szybka | Bardzo szybka | Bardzo szybka |
| html2md (asynchronicznie) | Bardzo szybka | Bardzo szybka | Najbardziej szybka |
Główne obserwacje:
html2mditrafilaturasą najszybsze dla złożonych dokumentów, czyniąc je idealnymi do przetwarzania wsadowegohtml-to-markdownoferuje najlepszy zrównoważony stosunek szybkości i funkcji dla użycia produkcyjnegomarkdownifyjest wolniejszy, ale najbardziej elastyczny – poświęcenie jest warte, gdy potrzebujesz niestandardowych procedurhtml2textpokazuje swoje wiekowe powolność, ale nadal jest stabilny dla prostych przypadków użycia
Uwaga: Różnice w wydajności stają się znaczące tylko przy przetwarzaniu setek lub tysięcy plików. Dla rzadkich konwersji, dowolna biblioteka zadziała dobrze. Skup się na funkcjach i opcjach dostosowania zamiast tego.
Przypadki użycia w praktyce
Teoria jest pomocna, ale praktyczne przykłady pokazują, jak te narzędzia działają w produkcji. Oto cztery typowe scenariusze z kompletnym, gotowym do produkcji kodem, który możesz dostosować do swoich własnych projektów.
Przypadek użycia 1: Przygotowanie danych treningowych dla LLM
Wymagania: Wyodrębnienie czystego tekstu z tysięcy stron dokumentacji
Zalecany: trafilatura + przetwarzanie równoległe
import trafilatura
from pathlib import Path
from concurrent.futures import ProcessPoolExecutor
def process_html_file(html_path):
"""Konwertuj plik HTML na markdown"""
html = Path(html_path).read_text(encoding='utf-8')
markdown = trafilatura.extract(
html,
output_format='markdown',
include_links=False, # Usuń dla czystszych danych treningowych
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
# Przetwarzanie 10 000 plików równolegle
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"Przetworzono {len(html_files)} plików")
print(f"Łączna liczba znaków: {sum(token_counts):,}")
Przypadek użycia 2: Migracja bloga Hugo
Wymagania: Migracja bloga WordPress do Hugoa z frontmatter
Zalecany: html2md CLI
Hugo to popularny generator stron statycznych, który używa Markdown do treści. Dla więcej wskazówek specyficznych dla Hugoa, sprawdź nasz Podręcznik Hugoa i dowiedz się, jak Dodawać strukturalne znaczniki do Hugoa dla lepszego SEO. Nasz Hub Narzędzi do Dokumentacji zawiera więcej przewodników na temat przepływów pracy Markdown i konwersji dokumentów.
# Konwertuj wszystkie wpisy z frontmatter
m1f-html2md convert ./wordpress-export \
-o ./hugo/content/posts \
--generate-frontmatter \
--heading-offset 0 \
--remove-tags script,style,nav,footer
Lub programowo:
from html_to_markdown import convert, Options
from pathlib import Path
import yaml
def migrate_post(html_file):
"""Konwertuj HTML WordPress na Markdown Hugoa"""
html = Path(html_file).read_text()
# Wyodrębnij tytuł i datę z HTML
from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'html.parser')
title = soup.find('h1').get_text() if soup.find('h1') else 'Bez tytułu'
# Konwertuj na Markdown
options = Options(strip_tags=['script', 'style', 'nav', 'footer'])
markdown = convert(html, options=options)
# Dodaj frontmatter Hugoa
frontmatter = {
'title': title,
'date': '2024-10-24',
'draft': False,
'tags': []
}
output = f"---\n{yaml.dump(frontmatter)}---\n\n{markdown}"
# Zapisz
output_file = html_file.replace('.html', '.md')
Path(output_file).write_text(output, encoding='utf-8')
# Przetwarzaj wszystkie wpisy
for html_file in Path('./wordpress-export').glob('*.html'):
migrate_post(html_file)
Przypadek użycia 3: Skraper dokumentacji z niestandardowym formatowaniem
Wymagania: Skrapowanie dokumentacji technicznych z niestandardowym formatowaniem bloków kodu
Zalecany: markdownify z niestandardowym konwerterem
Ten podejście jest szczególnie przydatny przy migracji dokumentacji z systemów wiki. Jeśli zarządzasz dokumentacją, możesz być również zainteresowany DokuWiki - samozhostowany wiki i alternatywy dla rozwiązań samozhostowanych dokumentacji.
from markdownify import MarkdownConverter
import requests
class DocsConverter(MarkdownConverter):
"""Niestandardowy konwerter dla dokumentacji technicznej"""
def convert_pre(self, el, text, convert_as_inline):
"""Zwiększone bloki kodu z podświetlaniem składni"""
code = el.find('code')
if code:
# Wyodrębnij język z klasy
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):
"""Obsługa specjalnych bloków dokumentacji"""
classes = el.get('class', [])
# Bloki ostrzeżeń
if 'warning' in classes:
return f'\n> ⚠️ **Ostrzeżenie**: {text}\n'
# Bloki informacji
if 'info' in classes or 'note' in classes:
return f'\n> 💡 **Uwaga**: {text}\n'
return text
def scrape_docs(url):
"""Skrapuj i konwertuj stronę dokumentacji"""
response = requests.get(url)
markdown = DocsConverter().convert(response.text)
return markdown
# Użyj
docs_url = "https://docs.example.com/api-reference"
markdown = scrape_docs(docs_url)
Path('api-reference.md').write_text(markdown)
Przypadek użycia 4: Konwersja newsletterów na archiwum Markdown
Wymagania: Konwersja HTML newsletterów na czytelny Markdown
Zalecany: html2text z konkretną konfiguracją
import html2text
import email
from pathlib import Path
def convert_newsletter(email_file):
"""Konwertuj HTML e-mail na Markdown"""
# Parsuj e-mail
with open(email_file, 'r') as f:
msg = email.message_from_file(f)
# Pobierz część 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
# Skonfiguruj konwerter
h = html2text.HTML2Text()
h.ignore_images = False
h.images_to_alt = True
h.body_width = 0
h.protect_links = True
h.unicode_snob = True
# Konwertuj
markdown = h.handle(html_content)
# Dodaj metadane
subject = msg.get('Subject', 'Brak tytułu')
date = msg.get('Date', '')
output = f"# {subject}\n\n*Data: {date}*\n\n---\n\n{markdown}"
return output
# Przetwarzaj archiwum newsletterów
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')
Rekomendacje według scenariusza
Dalej nie jesteś pewien, który pakiet wybrać? Oto przewodnik oparty na konkretnych przypadkach użycia.
Dla skrapowania sieci i przygotowania danych do LLM
Zwycięzca: trafilatura
Trafilatura wyróżnia się w ekstrakcji czystej treści, usuwając boilerplate. Idealny do:
- Budowania zestawów danych treningowych LLM
- Agregacji treści
- Zbierania artykułów naukowych
- Ekstrakcji artykułów nowin
Dla migracji Hugo/Jekyll
Zwycięzca: html2md
Asynchroniczne przetwarzanie i generowanie frontmatter sprawia, że duże migracje są szybkie i łatwe:
- Konwersje wsadowe
- Automatyczne wyodrębnianie metadanych
- Generowanie frontmatter YAML
- Dostosowanie poziomu nagłówka
Dla niestandardowej konwersji
Zwycięzca: markdownify
Dziedziczenie konwertera umożliwia pełną kontrolę:
- Niestandardowe procedury obsługi tagów
- Konwersje specyficzne dla dziedziny
- Specjalne wymagania formatowania
- Integracja z istniejącym kodem BeautifulSoup
Dla bezpiecznych systemów produkcyjnych
Zwycięzca: html-to-markdown
Nowoczesny, typowo bezpieczny i pełny funkcjonalności:
- Pełne wsparcie HTML5
- Komprehensywne wskazówki typu
- Zaawansowana obsługa tabel
- Aktywne utrzymanie
Dla prostych, stabilnych konwersji
Zwycięzca: html2text
Gdy potrzebujesz czegoś, co „prosto działa”:
- Brak zależności
- Przetestowane w praktyce
- Rozszerzona konfiguracja
- Szeroka obsługa platform
Najlepsze praktyki przygotowania danych dla LLM
Niezależnie od wyboru biblioteki, przestrzeganie tych najlepszych praktyk zapewni wysokiej jakości wynik w formacie Markdown zoptymalizowany do przetwarzania przez modele językowe. Te wzorce udowodniły swoje znaczenie w produkcyjnych przepływach pracy przetwarzających miliony dokumentów.
1. Oczyszczanie przed konwersją
Zawsze usuwaj niechciane elementy przed konwersją, aby uzyskać czystszy wynik i lepszą wydajność:
from bs4 import BeautifulSoup
import trafilatura
def clean_and_convert(html):
"""Usuń niechciane elementy przed konwersją"""
soup = BeautifulSoup(html, 'html.parser')
# Usuń niechciane elementy
for element in soup(['script', 'style', 'nav', 'footer', 'header', 'aside']):
element.decompose()
# Usuń reklamy i śledzenie
for element in soup.find_all(class_=['ad', 'advertisement', 'tracking']):
element.decompose()
# Konwertuj oczyszczony HTML
markdown = trafilatura.extract(
str(soup),
output_format='markdown'
)
return markdown
2. Normalizacja białych znaków
Różne konwertery obsługują białe znaki inaczej. Normalizuj wynik, aby zapewnić spójność w całym zbiorze danych:
import re
def normalize_markdown(markdown):
"""Oczyszczanie odstępow w markdownie"""
# Usuń wielokrotne puste linie
markdown = re.sub(r'\n{3,}', '\n\n', markdown)
# Usuń końcowe białe znaki
markdown = '\n'.join(line.rstrip() for line in markdown.split('\n'))
# Upewnij się, że jest tylko jedna linia na końcu
markdown = markdown.rstrip() + '\n'
return markdown
3. Walidacja wyników
Kontrola jakości jest kluczowa. Zaimplementuj walidację, aby wczesnie wykrywać błędy konwersji:
def validate_markdown(markdown):
"""Walidacja jakości markdownu"""
issues = []
# Sprawdź pozostałe fragmenty HTML
if '<' in markdown and '>' in markdown:
issues.append("Wykryto tagi HTML")
# Sprawdź uszkodzone linki
if '[' in markdown and ']()' in markdown:
issues.append("Wykryto pusty link")
# Sprawdź nadmiarowe bloki kodu
code_block_count = markdown.count('```')
if code_block_count % 2 != 0:
issues.append("Nie zamknięty blok kodu")
return len(issues) == 0, issues
4. Szablon przetwarzania w partii
Przy przetwarzaniu dużych zbiorów dokumentów, użyj tego gotowego do produkcji szablonu z odpowiednim obsługą błędów, logowaniem i przetwarzaniem równoległym:
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):
"""Przetwarzanie pojedynczego pliku 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:
# Normalizacja
markdown = normalize_markdown(markdown)
# Walidacja
is_valid, issues = validate_markdown(markdown)
if not is_valid:
logger.warning(f"{html_path}: {', '.join(issues)}")
# Zapis
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"Błąd podczas przetwarzania {html_path}: {e}")
return False
def batch_convert(input_dir, max_workers=4):
"""Konwersja wszystkich plików HTML w katalogu"""
html_files = list(Path(input_dir).rglob('*.html'))
logger.info(f"Znaleziono {len(html_files)} plików HTML")
with ProcessPoolExecutor(max_workers=max_workers) as executor:
results = list(executor.map(process_file, html_files))
success_count = sum(results)
logger.info(f"Pomyślnie przekonwertowano {success_count}/{len(html_files)} plików")
# Użycie
batch_convert('./html_docs', max_workers=8)
Podsumowanie
Eko system Pythona oferuje dojrzałe, gotowe do produkcji narzędzia do konwersji HTML na Markdown, każde zoptymalizowane dla różnych scenariuszy. Twój wybór powinien być zgodny z Twoimi konkretnymi wymaganiami:
- Szybkie konwersje: Użyj
html2textz powodu jego prostoty i braku zależności - Własna logika: Użyj
markdownifydla maksymalnej elastyczności poprzez dziedziczenie - Przeglądanie stron internetowych: Użyj
trafilaturadla inteligentnego wydobycia treści z usuwaniem zbędnych elementów - Wielkoskalowe migracje: Użyj
html2mddla asynchronicznej wydajności przy dużych projektach - Systemy produkcyjne: Użyj
html-to-markdowndla bezpieczeństwa typów i pełnego wsparcia dla HTML5 - Zachowanie znaczenia: Użyj
domscribedla zachowania struktury semantycznej HTML5
Zalecenia dla przepływów pracy LLM
Dla przepływów pracy przygotowania danych do LLM zaleca się podejście dwuetapowe:
- Zacznij od
trafilaturadla początkowego wydobycia treści – inteligentnie usuwa nawigację, reklamy i zbędne elementy, zachowując główną treść - Zwróć się do
html-to-markdowndla skomplikowanych dokumentów wymagających dokładnego zachowania struktury, takich jak dokumentacja techniczna z tabelami i blokami kodu
Ta kombinacja skutecznie radzi sobie z 95% rzeczywistych scenariuszy.
Kolejne kroki
Aby uzyskać więcej porad dotyczących Markdown, LaTeX, przetwarzania PDF i przepływów pracy druku dokumentów, zobacz Narzędzia dokumentacyjne w 2026: Markdown, LaTeX, PDF i przepływy pracy druku.
Wszystkie te narzędzia (z wyjątkiem html2text) są aktywnie utrzymywane i gotowe do produkcji. Lepszym wyborem jest:
- Zainstalowanie 2–3 bibliotek pasujących do Twojego przypadku użycia
- Testowanie ich przy użyciu Twoich rzeczywistych przykładów HTML
- Testowanie wydajności przy typowych rozmiarach dokumentów
- Wybieranie na podstawie jakości wyników, a nie tylko prędkości
Eko system Pythona dla konwersji HTML na Markdown dojrzał znacznie, i nie zrobisz błędu wybierając dowolne z tych narzędzi dla ich przeznaczenia.
Dodatkowe zasoby
- Dokumentacja html2text
- markdownify na PyPI
- html-to-markdown na GitHub
- Dokumentacja trafilatura
- Dokumentacja html2md
- domscribe na PyPI
Uwaga: Ta analiza opiera się na analizie oficjalnej dokumentacji, opinii społeczności i architekturze bibliotek. Charakterystyka wydajności jest reprezentatywna dla typowych wzorców użycia. Dla konkretnych przypadków użycia przeprowadź własne testy wydajnościowe przy użyciu rzeczywistych przykładów HTML.
Inne przydatne artykuły
- Narzędzia dokumentacyjne w 2026: Markdown, LaTeX, PDF i przepływy pracy druku
- Poradnik Markdown
- Użycie bloków kodu w Markdown
- Konwertowanie dokumentów Word na Markdown: Kompletny przewodnik
- Konwertowanie treści HTML na Markdown za pomocą LLM i Ollama
- Poradnik cURL
- Poradnik dla generatora stron statycznych Hugo
- Dokuwiki – lokalny wiki i alternatywy
- Użycie Obsidian do zarządzania wiedzą osobistą