HTML naar Markdown converteren met Python: Een uitgebreid overzicht
Python voor het converteren van HTML naar nette, LLM-klare Markdown
HTML naar Markdown converteren is een fundamentele taak in moderne ontwikkelingsworkflows, vooral wanneer je webinhoud voor Large Language Models (LLMs), documentatiesystemen of statische sitegeneratoren zoals Hugo voorbereidt.
Hoewel HTML is ontworpen voor webbrowsers met rijke stijl en structuur, biedt Markdown een schone, leesbare indeling die ideaal is voor tekstverwerking, versiebeheer en AI-consumptie. Als je nieuw bent met Markdown-syntaxis, raadpleeg dan onze Markdown Cheatsheet voor een uitgebreid overzicht.

In dit uitgebreide overzicht bespreken we zes Pythonbibliotheken voor het converteren van HTML naar Markdown, met praktische codevoorbeelden, prestatiebenchmarks en reële toepassingen. Of je nu een LLM-trainingspijplijn bouwt, een blog migreert naar Hugo of documentatie scrapes, je vindt hier het juiste gereedschap voor je workflow.
Alternatieve aanpak: Als je intelligentere inhoudsextractie met semantische begrip nodig hebt, kun je ook overwegen HTML naar Markdown converteren met LLM en Ollama, wat AI-gestuurde conversie biedt voor complexe lay-outs.
Wat je leert:
- Gedetailleerde vergelijking van 6 bibliotheken met voor- en nadelen per bibliotheek
- Prestatiebenchmarks met reële HTML-voorbeelden
- Productie-klare codevoorbeelden voor veelvoorkomende toepassingen
- Beste praktijken voor LLM-preprocessing-workflows
- Specifieke aanbevelingen op basis van je eisen
Waarom Markdown voor LLM-preprocessing?
Voor we in de tools duiken, laten we begrijpen waarom Markdown in het bijzonder waardevol is voor LLM-workflows:
- Token-efficiëntie: Markdown gebruikt aanzienlijk minder tokens dan HTML voor dezelfde inhoud
- Semantische duidelijkheid: Markdown behoudt documentstructuur zonder vervelende tags
- Leesbaarheid: Zowel mensen als LLMs kunnen Markdown-syntaxis gemakkelijk parsen
- Consistentie: Standaardindeling vermindert onduidelijkheid in modelinputs
- Opslag: Kleinere bestandsgroottes voor trainingsgegevens en contextvensters
Markdowns flexibiliteit strekt zich uit tot HTML-conversie—je kunt ook Worddocumenten converteren naar Markdown voor documentatieworkflows gebruiken, of het gebruiken in kennisbeheersysteem zoals Obsidian voor persoonlijke kennisbeheer.
TL;DR - Snelle vergelijkingstabel
Als je haast hebt, hier is een overzicht van alle zes de bibliotheken op een blik. Deze tabel helpt je snel te identificeren welk gereedschap overeenkomt met je specifieke eisen:
| Kenmerk | html2text | markdownify | html-to-markdown | trafilatura | domscribe | html2md |
|---|---|---|---|---|---|---|
| HTML5-ondersteuning | Gedeeltelijk | Gedeeltelijk | Volledig | Volledig | Volledig | Volledig |
| Typehints | Nee | Nee | Ja | Gedeeltelijk | Nee | Gedeeltelijk |
| Aangepaste handlers | Beperkt | Uitstekend | Goed | Beperkt | Goed | Beperkt |
| Tabelondersteuning | Basis | Basis | Geavanceerd | Goed | Goed | Goed |
| Asynchrone ondersteuning | Nee | Nee | Nee | Nee | Nee | Ja |
| Inhoudsextractie | Nee | Nee | Nee | Uitstekend | Nee | Goed |
| Metadataverzameling | Nee | Nee | Ja | Uitstekend | Nee | Ja |
| CLI-tool | Nee | Nee | Ja | Ja | Nee | Ja |
| Snelheid | Gemiddeld | Langzaam | Snel | Zeer snel | Gemiddeld | Zeer snel |
| Actieve ontwikkeling | Nee | Ja | Ja | Ja | Beperkt | Ja |
| Pythonversie | 3.6+ | 3.7+ | 3.9+ | 3.6+ | 3.8+ | 3.10+ |
| Afhankelijkheden | Geen | BS4 | lxml | lxml | BS4 | aiohttp |
Snelle keuzegids:
- Nood aan snelheid? → trafilatura of html2md
- Nood aan aanpassing? → markdownify
- Nood aan typesicherheid? → html-to-markdown
- Nood aan eenvoud? → html2text
- Nood aan inhoudsextractie? → trafilatura
De kandidaten: 6 Pythonbibliotheken vergeleken
Laten we dieper ingaan op elke bibliotheek met praktische codevoorbeelden, configuratieopties en reële inzichten. Elke sectie bevat installatieinstructies, gebruiksmogelijkheden en eerlijke beoordelingen van sterktes en beperkingen.
1. html2text - De klassieke keuze
Oorspronkelijk ontwikkeld door Aaron Swartz, is html2text al meer dan tien jaar een standaard in de Python-ecosysteem. Het richt zich op het produceren van schone, leesbare Markdown-uitvoer.
Installatie:
pip install html2text
Basisgebruik:
import html2text
# Maak converterinstantie
h = html2text.HTML2Text()
# Stel opties in
h.ignore_links = False
h.ignore_images = False
h.ignore_emphasis = False
h.body_width = 0 # Geen regels omschrijven
html_content = """
<h1>Welkom bij web scraping</h1>
<p>Dit is een <strong>uitgebreide gids</strong> voor het extraheren van inhoud.</p>
<ul>
<li>Eenvoudig te gebruiken</li>
<li>Bewezen in de praktijk</li>
<li Breed aangenomen</li>
</ul>
<a href="https://example.com">Meer informatie</a>
"""
markdown = h.handle(html_content)
print(markdown)
Uitvoer:
# Welkom bij web scraping
Dit is een **uitgebreide gids** voor het extraheren van inhoud.
* Eenvoudig te gebruiken
* Bewezen in de praktijk
* Breed aangenomen
[Meer informatie](https://example.com)
Geavanceerde configuratie:
import html2text
h = html2text.HTML2Text()
# Overslaan van specifieke elementen
h.ignore_links = True
h.ignore_images = True
# Beheer van opmaak
h.body_width = 80 # Omschrijf op 80 tekens
h.unicode_snob = True # Gebruik Unicode-tekens
h.emphasis_mark = '*' # Gebruik * voor nadruk in plaats van _
h.strong_mark = '**'
# Beheer van tabellen
h.ignore_tables = False
# Bescherm vooraf opgemaakte tekst
h.protect_links = True
Voordelen:
- Volwassen en stabiel (meer dan 15 jaar ontwikkeling)
- Uitgebreide configuratieopties
- Goed met randgevallen
- Geen externe afhankelijkheden
Nadelen:
- Beperkte HTML5-ondersteuning
- Kan onregelmatige spaties produceren
- Niet actief onderhouden (laatste grote update in 2020)
- Alleen single-threaded verwerking
Beste voor: Eenvoudige HTML-documenten, legacy-systemen, wanneer stabiliteit van cruciaal belang is
2. markdownify - De flexibele optie
markdownify maakt gebruik van BeautifulSoup4 om flexibele HTML-parsen met aanpasbare tagbehandeling te bieden.
Installatie:
pip install markdownify
Basisgebruik:
from markdownify import markdownify as md
html = """
<article>
<h2>Modern webontwikkeling</h2>
<p>Bouwen met <code>Python</code> en <em>moderne frameworks</em>.</p>
<blockquote>
<p>Eenvoud is de uiteindelijke sofisticatie.</p>
</blockquote>
</article>
"""
markdown = md(html)
print(markdown)
Uitvoer:
## Modern webontwikkeling
Bouwen met `Python` en *moderne frameworks*.
> Eenvoud is de uiteindelijke sofisticatie.
Geavanceerd gebruik met aangepaste handlers:
from markdownify import MarkdownConverter
class CustomConverter(MarkdownConverter):
"""
Maak aangepaste converter met specifieke tagbehandeling
"""
def convert_img(self, el, text, convert_as_inline):
"""Aangepaste beeldhandler met alternatieve tekst"""
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):
"""Versterkte codeblokbehandeling met taaldetectie"""
code = el.find('code')
if code:
# Extraheer taal uit class-attribuut (bijv. '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'
# Gebruik aangepaste converter
html = '<pre><code class="language-python">def hello():\n print("world")</code></pre>'
markdown = CustomConverter().convert(html)
print(markdown)
Voor meer informatie over het werken met Markdown-codeblokken en syntaxismarkering, zie onze gids over Markdown-codeblokken.
Selectieve tagconversie:
from markdownify import markdownify as md
# Verwijder specifieke tags volledig
markdown = md(html, strip=['script', 'style', 'nav'])
# Converteer alleen specifieke tags
markdown = md(
html,
heading_style="ATX", # Gebruik # voor koppen
bullets="-", # Gebruik - voor lijstitems
strong_em_symbol="*", # Gebruik * voor nadruk
)
Voordelen:
- Gebaseerd op BeautifulSoup4 (robuste HTML-parsen)
- Zeer aanpasbaar via subclassing
- Actief onderhouden
- Goede documentatie
Nadelen:
- Vereist BeautifulSoup4-afhankelijkheid
- Kan trager zijn voor grote documenten
- Beperkte ingebouwde tabelondersteuning
Beste voor: Aangepaste conversielogica, projecten die al BeautifulSoup4 gebruiken
3. html-to-markdown - De moderne powerhouse
html-to-markdown is een volledig getypeerde, moderne bibliotheek met uitgebreide HTML5-ondersteuning en uitgebreide configuratieopties.
Installatie:
pip install html-to-markdown
Basisgebruik:
from html_to_markdown import convert
html = """
<article>
<h1>Tech-documentatie</h1>
<table>
<thead>
<tr>
<th>Kenmerk</th>
<th>Ondersteuning</th>
</tr>
</thead>
<tbody>
<tr>
<td>HTML5</td>
<td>✓</td>
</tr>
<tr>
<td>Tabellen</td>
<td>✓</td>
</tr>
</tbody>
</table>
</article>
"""
markdown = convert(html)
print(markdown)
Geavanceerde configuratie:
from html_to_markdown import convert, Options
# Maak aangepaste opties
options = Options(
heading_style="ATX",
bullet_style="-",
code_language_default="python",
strip_tags=["script", "style"],
escape_special_chars=True,
table_style="pipe", # Gebruik | voor tabellen
preserve_whitespace=False,
extract_metadata=True, # Extraheer meta-tags
)
markdown = convert(html, options=options)
Command-line interface:
# Converteer enkel bestand
html-to-markdown input.html -o output.md
# Converteer met opties
html-to-markdown input.html \
--heading-style atx \
--strip-tags script,style \
--extract-metadata
# Batchconversie
find ./html_files -name "*.html" -exec html-to-markdown {} -o ./markdown_files/{}.md \;
Voordelen:
- Volledige HTML5-ondersteuning inclusief semantische elementen
- Typeveilig met uitgebreide typehints
- Versterkte tabelbehandeling (samengevoegde cellen, uitlijning)
- Mogelijkheid tot metadataextrahering
- Actieve ontwikkeling en moderne codebasis
Nadelen:
- Vereist Python 3.9+
- Grotere afhankelijkheidsvoetafdruk
- Steilere leercurve
Beste voor: Complexe HTML5-documenten, typeveilig projecten, productiesystemen
4. trafilatura - De inhoudsextractie specialist
trafilatura is niet alleen een HTML-naar-Markdown-converter, het is ook een slimme inhoudsextractiebibliotheek die specifiek is ontworpen voor web scraping en artikel extrahering.
Installatie:
pip install trafilatura
Basisgebruik:
import trafilatura
# Download en extraher van URL
url = "https://example.com/artikel"
downloaded = trafilatura.fetch_url(url)
markdown = trafilatura.extract(downloaded, output_format='markdown')
print(markdown)
Opmerking: Trafilatura bevat ingebouwde URL-downloading, maar voor complexere HTTP-acties kan je onze cURL Cheatsheet nuttig vinden wanneer je werkt met APIs of geauthenticeerde eindpunten.
Geavanceerde inhoudsextractie:
import trafilatura
from trafilatura.settings import use_config
# Maak aangepaste configuratie
config = use_config()
config.set("DEFAULT", "EXTRACTION_TIMEOUT", "30")
html = """
<html>
<head><title>Artikel titel</title></head>
<body>
<nav>Navigatiemenu</nav>
<article>
<h1>Hoofdartikel</h1>
<p>Belangrijke inhoud hier.</p>
</article>
<aside>Reclame</aside>
<footer>Voettekst</footer>
</body>
</html>
"""
# Extraher alleen hoofdinhoud
markdown = trafilatura.extract(
html,
output_format='markdown',
include_comments=False,
include_tables=True,
include_images=True,
include_links=True,
config=config
)
# Extraher met metadata
result = trafilatura.extract(
html,
output_format='markdown',
with_metadata=True
)
if result:
print(f"Titel: {result.get('title', 'N/A')}")
print(f"Auteur: {result.get('author', 'N/A')}")
print(f"Datum: {result.get('date', 'N/A')}")
print(f"\nInhoud:\n{result.get('text', '')}")
Batchverwerking:
import trafilatura
from concurrent.futures import ThreadPoolExecutor
from pathlib import Path
def process_url(url):
"""Extraher markdown van URL"""
downloaded = trafilatura.fetch_url(url)
if downloaded:
return trafilatura.extract(
downloaded,
output_format='markdown',
include_links=True,
include_images=True
)
return None
# Verwerk meerdere URLs parallel
urls = [
"https://example.com/artikel1",
"https://example.com/artikel2",
"https://example.com/artikel3",
]
with ThreadPoolExecutor(max_workers=5) as executor:
results = list(executor.map(process_url, urls))
for i, markdown in enumerate(results):
if markdown:
Path(f"artikel_{i}.md").write_text(markdown, encoding='utf-8')
Voordelen:
- Slimme inhoudsextractie (verwijderd boilerplate)
- Ingebouwde URL-downloading met robuuste foutafhandeling
- Metadataextrahering (titel, auteur, datum)
- Taaldetectie
- Optimaliseerd voor nieuwsartikelen en blogposts
- Snel C-gestuurde parsing
Nadelen:
- Kan te veel inhoud verwijderen voor algemene HTML
- Gericht op artikel extrahering (niet algemeen doeleindig)
- Configuratiecomplexiteit voor randgevallen
Beste voor: Web scraping, artikel extrahering, LLM-trainingsgegevens voorbereiding
5. domscribe - De semantische behoudende
domscribe richt zich op het behouden van de semantische betekenis van HTML tijdens het converteren naar Markdown.
Installatie:
pip install domscribe
Basisgebruik:
from domscribe import html_to_markdown
html = """
<article>
<header>
<h1>Verstaan van semantische HTML</h1>
<time datetime="2024-10-24">24 oktober 2024</time>
</header>
<section>
<h2>Inleiding</h2>
<p>Semantische HTML geeft <mark>betekenis</mark> aan inhoud.</p>
</section>
<aside>
<h3>Gerelateerde onderwerpen</h3>
<ul>
<li>Toegankelijkheid</li>
<li>SEO</li>
</ul>
</aside>
</article>
"""
markdown = html_to_markdown(html)
print(markdown)
Aangepaste opties:
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)
Voordelen:
- Behoudt semantische HTML5-structuur
- Goed met moderne webcomponenten
- Sfeerige API-ontwerp
Nadelen:
- Nog in vroege ontwikkeling (API kan veranderen)
- Beperkte documentatie vergeleken met rijpere alternatieven
- Kleiner community en minder voorbeelden beschikbaar
Beste voor: Semantische HTML5-documenten, toegankelijkheidsgerichte projecten, wanneer het behouden van HTML5-structuur van cruciaal belang is
Opmerking: Hoewel domscribe nieuw en minder getest is dan alternatieven, vult het een specifieke niche voor het behouden van semantische HTML die andere tools niet prioriteren.
6. html2md - De asynchrone powerhouse
html2md is ontworpen voor hoge-prestatie batchconversies met asynchrone verwerking.
Installatie:
pip install html2md
Command-line gebruik:
# Converteer hele map
m1f-html2md convert ./website -o ./docs
# Met aangepaste instellingen
m1f-html2md convert ./website -o ./docs \
--remove-tags nav,footer \
--heading-offset 1 \
--detect-language
# Converteer enkel bestand
m1f-html2md convert index.html -o readme.md
Programmatisch gebruik:
import asyncio
from html2md import convert_html
async def convert_files():
"""Asynchrone batchconversie"""
html_files = [
'page1.html',
'page2.html',
'page3.html'
]
tasks = [convert_html(file) for file in html_files]
results = await asyncio.gather(*tasks)
return results
# Voer conversie uit
results = asyncio.run(convert_files())
Voordelen:
- Asynchrone verwerking voor hoge prestaties
- Slimme inhoudsselectie detectie
- YAML frontmatter generatie (uitstekend voor Hugo!)
- Taal detectie
- Ondersteuning voor parallelle verwerking
Nadelen:
- Vereist Python 3.10+
- CLI-gericht (minder flexibele API)
- Documentatie zou uitgebreider kunnen zijn
Beste voor: Grote schaal migraties, batchconversies, Hugo/Jekyll migraties
Prestatiebenchmarks
Prestaties zijn belangrijk, vooral wanneer duizenden documenten worden verwerkt voor LLM-training of grote schaal migraties. Het begrijpen van de relatieve snelheidverschillen tussen bibliotheken helpt je om informele beslissingen te nemen voor je workflow.
Vergelijkende prestatieanalyse:
Op basis van typische gebruiksmogelijkheden, hier is hoe deze bibliotheken zich vergelijken over drie realistische scenario’s:
- Eenvoudige HTML: Basisblogpost met tekst, koppen en links (5KB)
- Complexe HTML: Technische documentatie met geneste tabellen en codeblokken (50KB)
- Echte website: Volledige webpagina inclusief navigatie, voettekst, zijbalk en advertenties (200KB)
Hier is een voorbeeldbenchmarkcode die je kunt gebruiken om deze bibliotheken zelf te testen:
import time
import html2text
from markdownify import markdownify
from html_to_markdown import convert
import trafilatura
def benchmark(html_content, iterations=100):
"""Benchmark conversiesnelheid"""
# 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
}
Typische prestatiekenmerken (representatieve relatieve snelheden):
| Pakket | Eenvoudig (5KB) | Complexe (50KB) | Echte site (200KB) |
|---|---|---|---|
| html2text | Gemiddeld | Langzaam | Langzaam |
| markdownify | Langzaam | Langzaam | Het langst |
| html-to-markdown | Snel | Snel | Snel |
| trafilatura | Snel | Zeer snel | Zeer snel |
| html2md (asynchrone) | Zeer snel | Zeer snel | Snelst |
Belangrijke observaties:
html2mdentrafilaturazijn het snelst voor complexe documenten, waardoor ze ideaal zijn voor batchverwerkinghtml-to-markdownbiedt het beste evenwicht tussen snelheid en functies voor productiegebruikmarkdownifyis trager maar het meest flexibel—de trade-off is waard wanneer je aangepaste handlers nodig hebthtml2texttoont zijn leeftijd met trager prestaties, maar blijft stabiel voor eenvoudige toepassingen
Opmerking: Prestatieverschillen worden aanzienlijk wanneer honderden of duizenden bestanden worden verwerkt. Voor af en toe conversies werkt elke bibliotheek goed. Richt je aandacht op functies en aanpasbaarheid in plaats daarvan.
Real-World Use Cases
Theorie is nuttig, maar praktijkvoorbeelden laten zien hoe deze tools werken in productieomgevingen. Hier zijn vier veelvoorkomende scenario’s met volledige, productie-geoorloofde code die je kunt aanpassen voor je eigen projecten.
Use Case 1: LLM Training Data Preparation
Vereiste: Rein tekst extraheren uit duizenden documentatiepagina’s
Aanbevolen: trafilatura + parallelliseren
import trafilatura
from pathlib import Path
from concurrent.futures import ProcessPoolExecutor
def process_html_file(html_path):
"""Converteer HTML-bestand naar markdown"""
html = Path(html_path).read_text(encoding='utf-8')
markdown = trafilatura.extract(
html,
output_format='markdown',
include_links=False, # Verwijderen voor schoner training data
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
# Verwerk 10.000 bestanden in parallel
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"Verwerkt {len(html_files)} bestanden")
print(f"Totaal aantal tekens: {sum(token_counts):,}")
Use Case 2: Hugo Blog Migration
Vereiste: Migreren van WordPress-blog naar Hugo met frontmatter
Aanbevolen: html2md CLI
Hugo is een populaire statische sitegenerator die Markdown gebruikt voor inhoud. Voor meer Hugo-specifieke tips, bekijk onze Hugo Cheat Sheet en leer over Structured data markup toevoegen aan Hugo voor betere SEO.
# Converteer alle berichten met frontmatter
m1f-html2md convert ./wordpress-export \
-o ./hugo/content/posts \
--generate-frontmatter \
--heading-offset 0 \
--remove-tags script,style,nav,footer
Of programmatisch:
from html_to_markdown import convert, Options
from pathlib import Path
import yaml
def migrate_post(html_file):
"""Converteer WordPress HTML naar Hugo markdown"""
html = Path(html_file).read_text()
# Titel en datum extraheren uit HTML
from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'html.parser')
title = soup.find('h1').get_text() if soup.find('h1') else 'Untitled'
# Converteer naar markdown
options = Options(strip_tags=['script', 'style', 'nav', 'footer'])
markdown = convert(html, options=options)
# Voeg Hugo frontmatter toe
frontmatter = {
'title': title,
'date': '2024-10-24',
'draft': False,
'tags': []
}
output = f"---\n{yaml.dump(frontmatter)}---\n\n{markdown}"
# Opslaan
output_file = html_file.replace('.html', '.md')
Path(output_file).write_text(output, encoding='utf-8')
# Verwerk alle berichten
for html_file in Path('./wordpress-export').glob('*.html'):
migrate_post(html_file)
Use Case 3: Documentatie Scraper met Aangepaste Opmaak
Vereiste: Scrape technische documentatie met aangepaste codeblokkenbehandeling
Aanbevolen: markdownify met aangepaste converter
Deze aanpak is vooral handig bij het migreren van documentatie van wiki-systemen. Als je documentatie beheert, zou je ook geïnteresseerd kunnen zijn in DokuWiki - zelfgehost wiki en alternatieven voor oplossingen voor zelfgehoste documentatie.
from markdownify import MarkdownConverter
import requests
class DocsConverter(MarkdownConverter):
"""Aangepaste converter voor technische documentatie"""
def convert_pre(self, el, text, convert_as_inline):
"""Versterkte codeblokken met syntax highlighting"""
code = el.find('code')
if code:
# Taal extraheren uit klasse
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):
"""Behandel speciale documentatieblokken"""
classes = el.get('class', [])
# Waarschuwingsblokken
if 'warning' in classes:
return f'\n> ⚠️ **Waarschuwing**: {text}\n'
# Info-blokken
if 'info' in classes or 'note' in classes:
return f'\n> 💡 **Opmerking**: {text}\n'
return text
def scrape_docs(url):
"""Scrape en converteer documentatiepagina"""
response = requests.get(url)
markdown = DocsConverter().convert(response.text)
return markdown
# Gebruik
docs_url = "https://docs.example.com/api-reference"
markdown = scrape_docs(docs_url)
Path('api-reference.md').write_text(markdown)
Use Case 4: Nieuwsbrief naar Markdown Archief
Vereiste: Converteer HTML-nieuwsbrieven naar leesbare markdown
Aanbevolen: html2text met specifieke configuratie
import html2text
import email
from pathlib import Path
def convert_newsletter(email_file):
"""Converteer HTML-nieuwsbrief naar markdown"""
# Email parsen
with open(email_file, 'r') as f:
msg = email.message_from_file(f)
# HTML-deel ophalen
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
# Converter configureren
h = html2text.HTML2Text()
h.ignore_images = False
h.images_to_alt = True
h.body_width = 0
h.protect_links = True
h.unicode_snob = True
# Converteer
markdown = h.handle(html_content)
# Metadata toevoegen
subject = msg.get('Subject', 'Geen onderwerp')
date = msg.get('Date', '')
output = f"# {subject}\n\n*Datum: {date}*\n\n---\n\n{markdown}"
return output
# Nieuwsbriefarchief verwerken
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')
Aanbevelingen per Scenario
Nog steeds onzeker welk bibliotheek je moet kiezen? Hier is mijn definitieve gids gebaseerd op specifieke gebruiksscenario’s. Deze aanbevelingen komen uit praktijkervaring met elke bibliotheek in productieomgevingen.
Voor Web Scraping & LLM Voorverwerking
Winnaar: trafilatura
Trafilatura is uitstekend in het extraheren van schone inhoud terwijl boilerplate wordt verwijderd. Ideaal voor:
- Bouwen van LLM training datasets
- Inhoudsaggregatie
- Onderzoeksrapporten verzamelen
- Nieuwsartikel extractie
Voor Hugo/Jekyll Migraties
Winnaar: html2md
Asynchrone verwerking en frontmattergeneratie maken bulkmigraties snel en eenvoudig:
- Batchconversies
- Automatische metadataextractie
- YAML frontmattergeneratie
- Aanpassen van kopniveaus
Voor Aangepaste Conversie Logica
Winnaar: markdownify
Subklasseer de converter voor volledige controle:
- Aangepaste taghandlers
- Domein-specifieke conversies
- Specifieke opmaakvereisten
- Integratie met bestaande BeautifulSoup code
Voor Typeveilig Productiesystemen
Winnaar: html-to-markdown
Moderne, typeveilig en functievol:
- Volledige HTML5-ondersteuning
- Uitgebreide typehints
- Geavanceerde tabelbehandeling
- Actieve onderhoud
Voor Eenvoudige, Stabiele Conversies
Winnaar: html2text
Wanneer je iets nodig hebt dat “gewoon werkt”:
- Geen afhankelijkheden
- Getest in de strijd
- Uitgebreide configuratie
- Breed platformondersteuning
Beste Praktijken voor LLM Voorverwerking
Ongeacht welke bibliotheek je kiest, het volgen van deze beste praktijken zorgt ervoor dat de uitvoer van de Markdown van hoge kwaliteit is en geoptimaliseerd is voor LLM-consumptie. Deze patronen zijn essentieel geweest in productie workflows die miljoenen documenten verwerken.
1. Reinig voor het converteren
Verwijder altijd ongewenste elementen voor conversie om schoner output en betere prestaties te krijgen:
from bs4 import BeautifulSoup
import trafilatura
def clean_and_convert(html):
"""Verwijder ongewenste elementen voor conversie"""
soup = BeautifulSoup(html, 'html.parser')
# Verwijder ongewenste elementen
for element in soup(['script', 'style', 'nav', 'footer', 'header', 'aside']):
element.decompose()
# Verwijder advertenties en tracking
for element in soup.find_all(class_=['ad', 'advertisement', 'tracking']):
element.decompose()
# Converteer opgeschoonde HTML
markdown = trafilatura.extract(
str(soup),
output_format='markdown'
)
return markdown
2. Witruimte Normaliseren
Verschillende converters behandelen witruimte op verschillende manieren. Normaliseer de uitvoer om consistentie te waarborgen over je corpus:
import re
def normalize_markdown(markdown):
"""Reinig markdown spaties"""
# Verwijder meerdere lege lijnen
markdown = re.sub(r'\n{3,}', '\n\n', markdown)
# Verwijder achterliggende witruimte
markdown = '\n'.join(line.rstrip() for line in markdown.split('\n'))
# Zorg voor enkele newline aan het einde
markdown = markdown.rstrip() + '\n'
return markdown
3. Uitvoer Valideren
Kwaliteitscontrole is essentieel. Implementeer validatie om conversiefouten vroegtijdig te detecteren:
def validate_markdown(markdown):
"""Valideer markdown kwaliteit"""
issues = []
# Controleer op HTML restanten
if '<' in markdown and '>' in markdown:
issues.append("HTML tags gedetecteerd")
# Controleer op gebroken links
if '[' in markdown and ']()' in markdown:
issues.append("Lege link gedetecteerd")
# Controleer op te veel codeblokken
code_block_count = markdown.count('```')
if code_block_count % 2 != 0:
issues.append("Niet gesloten codeblok")
return len(issues) == 0, issues
4. Batchverwerkingstemplate
Bij het verwerken van grote documentcollecties, gebruik deze productie-geoorloofde template met juiste foutafhandeling, logboekregistratie en parallelliseren:
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):
"""Verwerk enkel HTML-bestand"""
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:
# Normaliseer
markdown = normalize_markdown(markdown)
# Valideer
is_valid, issues = validate_markdown(markdown)
if not is_valid:
logger.warning(f"{html_path}: {', '.join(issues)}")
# Opslaan
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"Fout bij verwerken van {html_path}: {e}")
return False
def batch_convert(input_dir, max_workers=4):
"""Converteer alle HTML-bestanden in map"""
html_files = list(Path(input_dir).rglob('*.html'))
logger.info(f"Gevonden {len(html_files)} HTML-bestanden")
with ProcessPoolExecutor(max_workers=max_workers) as executor:
results = list(executor.map(process_file, html_files))
success_count = sum(results)
logger.info(f"Met succes geconverteerd {success_count}/{len(html_files)} bestanden")
# Gebruik
batch_convert('./html_docs', max_workers=8)
Conclusie
Het Python-ecosysteem biedt rijpe, productie-geoorloofde tools voor HTML-naar-Markdown-conversie, elk geoptimaliseerd voor verschillende scenario’s. Je keuze moet overeenkomen met je specifieke vereisten:
- Snelle conversies: Gebruik
html2textvanwege zijn eenvoud en nul afhankelijkheden - Aangepaste logica: Gebruik
markdownifyvoor maximale flexibiliteit via subclassing - Web scraping: Gebruik
trafilaturavoor slimme inhoudsextractie met boilerplateverwijdering - Bulkmigraties: Gebruik
html2mdvoor asynchrone prestaties op grote schaalprojecten - Productiesystemen: Gebruik
html-to-markdownvoor typeveiligheid en uitgebreide HTML5-ondersteuning - Semantische behoud: Gebruik
domscribevoor het behouden van HTML5-semantische structuur
Aanbevelingen voor LLM Workflows
Voor LLM-voorverwerking workflows wordt een tweestapsaanpak aanbevolen:
- Begin met
trafilaturavoor initiële inhoudsextractie – het verwijdert slim navigatie, advertenties en boilerplate terwijl het de hoofdinhoud behoudt - Val terug op
html-to-markdownvoor complexe documenten die nauwkeurige structuurbehoud vereisen, zoals technische documentatie met tabellen en codeblokken
Deze combinatie behandelt 95% van de echte wereldscenario’s effectief.
Volgende stappen
Alleze tools (behalve html2text) worden actief onderhouden en zijn productie-geoorloofd. Het is beter om:
- 2-3 bibliotheekken te installeren die overeenkomen met je gebruiksscenario
- Ze testen met je eigen HTML-voorbeelden
- Prestaties te benchmarken met je typische documentgroottes
- Kiezen op basis van uitvoerkwaliteit, niet alleen snelheid
Het Python-ecosysteem voor HTML-naar-Markdown-conversie is aanzienlijk volwassen geworden, en je kan geen fout doen met welke van deze keuzes ook voor hun bedoelde gebruiksscenario’s.
Extra Resources
- html2text Documentatie
- markdownify op PyPI
- html-to-markdown GitHub
- trafilatura Documentatie
- html2md Documentatie
- domscribe op PyPI
Opmerking: Deze vergelijking is gebaseerd op analyse van officiële documentatie, community feedback en bibliotheekarchitectuur. Prestatiekenmerken zijn representatief voor typische gebruiksmogelijkheden. Voor specifieke gebruiksscenario’s, voer je eigen benchmarks uit met je eigen HTML-voorbeelden.
Andere Nuttige Artikelen
- Markdown Cheatsheet
- Markdown Codeblokken gebruiken
- Worddocumenten converteren naar Markdown: Een volledige gids
- HTML-inhoud converteren naar Markdown met LLM en Ollama
- cURL Cheatsheet
- Hugo Statische Sitegenerator Cheatsheet
- Structured data markup toevoegen aan Hugo
- Dokuwiki - zelfgehost wiki en alternatieven
- Obsidian gebruiken voor persoonlijk kennisbeheer