Convertir HTML en Markdown avec Python : Un guide complet
Python pour convertir HTML en Markdown propre et prêt à l'usage avec un LLM
Conversion de HTML en Markdown est une tâche fondamentale dans les workflows de développement modernes, particulièrement lors de la préparation du contenu web pour les grands modèles de langage (LLM), les systèmes de documentation ou les générateurs de sites statiques comme Hugo. Ce guide fait partie de notre Outils de Documentation en 2026 : Markdown, LaTeX, PDF et workflows d’impression hub.
Bien que le HTML ait été conçu pour les navigateurs web avec un rich styling et une structure, le Markdown offre un format propre et lisible idéal pour le traitement de texte, le contrôle de version et la consommation par l’IA. Si vous débutez avec la syntaxe Markdown, consultez notre Feuille de triche Markdown pour une référence complète.

Dans cette revue complète, nous explorerons six packages Python pour la conversion HTML-to-Markdown, en fournissant des exemples de code pratiques, des benchmarks de performance et des cas d’utilisation réels. Que vous construisez un pipeline de formation LLM, migrez un blog vers Hugo ou extrayez des documents, vous trouverez le meilleur outil pour votre workflow.
Approche alternative : Si vous avez besoin d’une extraction de contenu plus intelligente avec une compréhension sémantique, vous pourriez également envisager conversion de HTML en Markdown en utilisant LLM et Ollama, qui propose une conversion alimentée par l’IA pour les mises en page complexes.
Ce que vous apprendrez :
- Comparaison détaillée de 6 bibliothèques avec les avantages/inconvénients de chacune
- Benchmarks de performance avec des échantillons HTML réels
- Exemples de code prêts à la production pour les cas d’utilisation courants
- Bonnes pratiques pour les workflows de prétraitement LLM
- Recommandations spécifiques selon vos besoins
Pourquoi le Markdown pour le prétraitement LLM ?
Avant de plonger dans les outils, comprenons pourquoi le Markdown est particulièrement précieux pour les workflows LLM :
- Efficacité des tokens : Le Markdown utilise nettement moins de tokens que le HTML pour le même contenu
- Clarté sémantique : Le Markdown préserve la structure du document sans balises verbeuses
- Lisibilité : Les humains et les LLM peuvent facilement analyser la syntaxe Markdown
- Consistance : Le format standardisé réduit l’ambiguïté dans les entrées du modèle
- Stockage : Tailles de fichiers plus petites pour les données de formation et les fenêtres de contexte
La polyvalence du Markdown dépasse la conversion HTML : vous pouvez également convertir des documents Word en Markdown pour les workflows de documentation, ou l’utiliser dans des systèmes de gestion de connaissances comme Obsidian pour la gestion de connaissances personnelle. Pour plus d’informations sur la conversion de documents et la mise en forme entre Markdown, LaTeX et PDF, consultez le hub d’outils de documentation.
TL;DR - Matrice de comparaison rapide
Si vous êtes pressé, voici une comparaison complète des six bibliothèques à un coup d’œil. Ce tableau vous aidera à identifier rapidement quel outil correspond à vos besoins spécifiques :
| Fonctionnalité | html2text | markdownify | html-to-markdown | trafilatura | domscribe | html2md |
|---|---|---|---|---|---|---|
| Support HTML5 | Partiel | Partiel | Complet | Complet | Complet | Complet |
| Indications de type | Non | Non | Oui | Partiel | Non | Partiel |
| Gestionnaires personnalisés | Limité | Excellent | Bon | Limité | Bon | Limité |
| Support des tableaux | Basique | Basique | Avancé | Bon | Bon | Bon |
| Support asynchrone | Non | Non | Non | Non | Non | Oui |
| Extraction de contenu | Non | Non | Non | Excellent | Non | Bon |
| Extraction de métadonnées | Non | Non | Oui | Excellent | Non | Oui |
| Outil CLI | Non | Non | Oui | Oui | Non | Oui |
| Vitesse | Moyenne | Lente | Rapide | Très rapide | Moyenne | Très rapide |
| Développement actif | Non | Oui | Oui | Oui | Limité | Oui |
| Version Python | 3.6+ | 3.7+ | 3.9+ | 3.6+ | 3.8+ | 3.10+ |
| Dépendances | Aucune | BS4 | lxml | lxml | BS4 | aiohttp |
Guide de sélection rapide :
- Besoin de vitesse ? → trafilatura ou html2md
- Besoin de personnalisation ? → markdownify
- Besoin de sécurité de type ? → html-to-markdown
- Besoin de simplicité ? → html2text
- Besoin d’extraction de contenu ? → trafilatura
Les candidats : 6 packages Python comparés
Plongeons profondément dans chaque bibliothèque avec des exemples de code pratiques, des options de configuration et des insights du monde réel. Chaque section inclut des instructions d’installation, des modèles d’utilisation et des évaluations honnêtes des forces et des limites.
1. html2text - Le choix classique
Initialement développé par Aaron Swartz, html2text a été un pilier dans l’écosystème Python depuis plus d’une décennie. Il se concentre sur la production de sortie Markdown propre et lisible.
Installation :
pip install html2text
Utilisation de base :
import html2text
# Créer une instance de convertisseur
h = html2text.HTML2Text()
# Configurer les options
h.ignore_links = False
h.ignore_images = False
h.ignore_emphasis = False
h.body_width = 0 # Ne pas couper les lignes
html_content = """
<h1>Bienvenue au Web Scraping</h1>
<p>Ce est un <strong>guide complet</strong> pour extraire du contenu.</p>
<ul>
<li>Facile à utiliser</li>
<li>Battu en test</li>
<li>Très adopté</li>
</ul>
<a href="https://example.com">En savoir plus</a>
"""
markdown = h.handle(html_content)
print(markdown)
Sortie :
# Bienvenue au Web Scraping
Ce est un **guide complet** pour extraire du contenu.
* Facile à utiliser
* Battu en test
* Très adopté
[En savoir plus](https://example.com)
Configuration avancée :
import html2text
h = html2text.HTML2Text()
# Ignorer certains éléments
h.ignore_links = True
h.ignore_images = True
# Contrôler le formatage
h.body_width = 80 # Couper à 80 caractères
h.unicode_snob = True # Utiliser les caractères unicode
h.emphasis_mark = '*' # Utiliser * pour l'accentuation au lieu de _
h.strong_mark = '**'
# Gérer les tableaux
h.ignore_tables = False
# Protéger le texte pré-formaté
h.protect_links = True
Avantages :
- Mature et stable (plus de 15 ans de développement)
- Options de configuration extensives
- Gère bien les cas limites
- Aucune dépendance externe
Inconvénients :
- Support HTML5 limité
- Peut produire un espacement incohérent
- Non maintenu activement (dernière mise à jour majeure en 2020)
- Traitement mono-thread uniquement
Meilleur pour : Documents HTML simples, systèmes hérités, lorsque la stabilité est primordiale
2. markdownify - L’option flexible
markdownify utilise BeautifulSoup4 pour offrir un parsing HTML flexible avec une gestion personnalisée des balises.
Installation :
pip install markdownify
Utilisation de base :
from markdownify import markdownify as md
html = """
<article>
<h2>Développement web moderne</h2>
<p>Construction avec <code>Python</code> et <em>frameworks modernes</em>.</p>
<blockquote>
<p>La simplicité est la sophistication ultime.</p>
</blockquote>
</article>
"""
markdown = md(html)
print(markdown)
Sortie :
## Développement web moderne
Construction avec `Python` et *frameworks modernes*.
> La simplicité est la sophistication ultime.
Utilisation avancée avec gestionnaires personnalisés :
from markdownify import MarkdownConverter
class CustomConverter(MarkdownConverter):
"""
Créer un convertisseur personnalisé avec une gestion spécifique des balises
"""
def convert_img(self, el, text, convert_as_inline):
"""Gestionnaire personnalisé d'images avec texte alternatif"""
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):
"""Gestion améliorée des blocs de code avec détection de langue"""
code = el.find('code')
if code:
# Extraire la langue à partir de l'attribut de classe (ex. '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'
# Utiliser le convertisseur personnalisé
html = '<pre><code class="language-python">def hello():\n print("world")</code></pre>'
markdown = CustomConverter().convert(html)
print(markdown)
Pour plus de détails sur l’utilisation des blocs de code Markdown et la mise en surbrillance de la syntaxe, consultez notre guide sur Utilisation des blocs de code Markdown.
Conversion sélective des balises :
from markdownify import markdownify as md
# Supprimer entièrement certaines balises
markdown = md(html, strip=['script', 'style', 'nav'])
# Convertir uniquement certaines balises
markdown = md(
html,
heading_style="ATX", # Utiliser # pour les titres
bullets="-", # Utiliser - pour les éléments de liste
strong_em_symbol="*", # Utiliser * pour l'accentuation
)
Avantages :
- Construit sur BeautifulSoup4 (analyse HTML robuste)
- Très personnalisable via l’héritage
- Maintenance active
- Bonne documentation
Inconvénients :
- Dépendance BeautifulSoup4 requise
- Peut être plus lent pour les documents volumineux
- Support des tableaux limité
Meilleur pour : Logique de conversion personnalisée, projets utilisant déjà BeautifulSoup4
3. html-to-markdown - La puissance moderne
html-to-markdown est une bibliothèque moderne, entièrement typée, avec un support complet de HTML5 et des options de configuration étendues.
Installation :
pip install html-to-markdown
Utilisation de base :
from html_to_markdown import convert
html = """
<article>
<h1>Documentation technique</h1>
<table>
<thead>
<tr>
<th>Fonctionnalité</th>
<th>Support</th>
</tr>
</thead>
<tbody>
<tr>
<td>HTML5</td>
<td>✓</td>
</tr>
<tr>
<td>Tableaux</td>
<td>✓</td>
</tr>
</tbody>
</table>
</article>
"""
markdown = convert(html)
print(markdown)
Configuration avancée :
from html_to_markdown import convert, Options
# Créer des options personnalisées
options = Options(
heading_style="ATX",
bullet_style="-",
code_language_default="python",
strip_tags=["script", "style"],
escape_special_chars=True,
table_style="pipe", # Utiliser | pour les tableaux
preserve_whitespace=False,
extract_metadata=True, # Extraire les balises meta
)
markdown = convert(html, options=options)
Interface en ligne de commande :
# Convertir un seul fichier
html-to-markdown input.html -o output.md
# Convertir avec des options
html-to-markdown input.html \
--heading-style atx \
--strip-tags script,style \
--extract-metadata
# Conversion en lots
find ./html_files -name "*.html" -exec html-to-markdown {} -o ./markdown_files/{}.md \;
Avantages :
- Support complet de HTML5, y compris les éléments sémantiques
- Sécurité de type avec des indications de type complètes
- Gestion améliorée des tableaux (cellules fusionnées, alignement)
- Capacités d’extraction de métadonnées
- Développement actif et codebase moderne
Inconvénients :
- Requiert Python 3.9+
- Plus grande empreinte de dépendance
- Courbe d’apprentissage plus raide
Meilleur pour : Documents HTML5 complexes, projets typés, systèmes de production
4. trafilatura - L’expert de l’extraction de contenu
trafilatura n’est pas seulement un convertisseur HTML-to-Markdown — c’est une bibliothèque intelligente d’extraction de contenu spécifiquement conçue pour le scraping web et l’extraction d’articles.
Installation :
pip install trafilatura
Utilisation de base :
import trafilatura
# Télécharger et extraire à partir d'une URL
url = "https://example.com/article"
downloaded = trafilatura.fetch_url(url)
markdown = trafilatura.extract(downloaded, output_format='markdown')
print(markdown)
Note : Trafilatura inclut un téléchargement intégré d’URL, mais pour des opérations HTTP plus complexes, vous trouverez peut-être notre Feuille de triche cURL utile lors de l’utilisation d’API ou de points de terminaison authentifiés.
Extraction avancée de contenu :
import trafilatura
from trafilatura.settings import use_config
# Créer une configuration personnalisée
config = use_config()
config.set("DEFAULT", "EXTRACTION_TIMEOUT", "30")
html = """
<html>
<head><title>Titre de l'article</title></head>
<body>
<nav>Menu de navigation</nav>
<article>
<h1>Article principal</h1>
<p>Contenu important ici.</p>
</article>
<aside>Publicité</aside>
<footer>Contenu du pied de page</footer>
</body>
</html>
"""
# Extraire uniquement le contenu principal
markdown = trafilatura.extract(
html,
output_format='markdown',
include_comments=False,
include_tables=True,
include_images=True,
include_links=True,
config=config
)
# Extraire avec les métadonnées
result = trafilatura.extract(
html,
output_format='markdown',
with_metadata=True
)
if result:
print(f"Titre : {result.get('title', 'N/A')}")
print(f"Auteur : {result.get('author', 'N/A')}")
print(f"Date : {result.get('date', 'N/A')}")
print(f"\nContenu : \n{result.get('text', '')}")
Traitement en lots :
import trafilatura
from concurrent.futures import ThreadPoolExecutor
from pathlib import Path
def process_url(url):
"""Extraire du markdown à partir d'une URL"""
downloaded = trafilatura.fetch_url(url)
if downloaded:
return trafilatura.extract(
downloaded,
output_format='markdown',
include_links=True,
include_images=True
)
return None
# Traiter plusieurs URLs en parallèle
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')
Avantages :
- Extraction intelligente de contenu (supprime les éléments superflus)
- Téléchargement intégré d’URL avec une gestion robuste des erreurs
- Extraction de métadonnées (titre, auteur, date)
- Détection de langue
- Optimisé pour les articles de presse et les blogs
- Parsing rapide basé sur C
Inconvénients :
- Peut supprimer trop de contenu pour le HTML général
- Axé sur l’extraction d’articles (non généraliste)
- Complexité de configuration pour les cas limites
Meilleur pour : Scraping web, extraction d’articles, préparation de données de formation LLM
5. domscribe - Le préservateur sémantique
domscribe se concentre sur la préservation du sens du HTML lors de la conversion en Markdown.
Installation :
pip install domscribe
Utilisation de base :
from domscribe import html_to_markdown
html = """
<article>
<header>
<h1>Comprendre le HTML sémantique</h1>
<time datetime="2024-10-24">24 octobre 2024</time>
</header>
<section>
<h2>Introduction</h2>
<p>Le HTML sémantique donne <mark>un sens</mark> au contenu.</p>
</section>
<aside>
<h3>Sujets connexes</h3>
<ul>
<li>Accessibilité</li>
<li>SEO</li>
</ul>
</aside>
</article>
"""
markdown = html_to_markdown(html)
print(markdown)
Options personnalisées :
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)
Avantages :
- Préservation de la structure HTML5 sémantique
- Gère bien les composants web modernes
- Conception d’API propre
Inconvénients :
- Toujours en développement initial (API peut changer)
- Documentation limitée par rapport aux alternatives matures
- Communauté plus petite et moins d’exemples disponibles
Meilleur pour : Documents HTML5 sémantiques, projets axés sur l’accessibilité, lorsque la préservation de la structure sémantique HTML5 est critique
Note : Bien que domscribe soit plus récent et moins testé que les alternatives, il remplit un besoin spécifique de préservation du HTML sémantique que d’autres outils ne privilégient pas.
6. html2md - La puissance asynchrone
html2md est conçu pour des conversions de grande performance en lots avec un traitement asynchrone.
Installation :
pip install html2md
Utilisation en ligne de commande :
# Convertir un répertoire entier
m1f-html2md convert ./website -o ./docs
# Avec des paramètres personnalisés
m1f-html2md convert ./website -o ./docs \
--remove-tags nav,footer \
--heading-offset 1 \
--detect-language
# Convertir un seul fichier
m1f-html2md convert index.html -o readme.md
Utilisation programmable :
import asyncio
from html2md import convert_html
async def convert_files():
"""Conversion asynchrone en lots"""
html_files = [
'page1.html',
'page2.html',
'page3.html'
]
tasks = [convert_html(file) for file in html_files]
results = await asyncio.gather(*tasks)
return results
# Exécuter la conversion
results = asyncio.run(convert_files())
Avantages :
- Traitement asynchrone pour une haute performance
- Détection intelligente des sélecteurs de contenu
- Génération de frontmatter YAML (très utile pour Hugo !)
- Détection de la langue de code
- Support du traitement parallèle
Inconvénients :
- Requiert Python 3.10+
- CLI centré (moins flexible API)
- Documentation pouvant être plus complète
Meilleur pour : Migrations à grande échelle, conversions en lots, migrations Hugo/Jekyll
Benchmarks de performance
La performance compte, surtout lorsqu’on traite des milliers de documents pour la formation LLM ou des migrations à grande échelle. Comprendre les différences de vitesse relatives entre les bibliothèques vous aide à prendre des décisions éclairées pour votre workflow.
Analyse comparative de performance :
Sur la base de schémas d’utilisation typiques, voici comment ces bibliothèques se comparent dans trois scénarios réalistes :
- HTML simple : Article de blog basique avec texte, titres et liens (5 Ko)
- HTML complexe : Documentation technique avec tableaux imbriqués et blocs de code (50 Ko)
- Site web réel : Page web complète incluant la navigation, le pied de page, la barre latérale et les publicités (200 Ko)
Voici un exemple de code de benchmark que vous pouvez utiliser pour tester ces bibliothèques vous-même :
import time
import html2text
from markdownify import markdownify
from html_to_markdown import convert
import trafilatura
def benchmark(html_content, iterations=100):
"""Benchmark de la vitesse de conversion"""
# 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
}
Caractéristiques de performance typiques (vitesses relatives représentatives) :
| Package | Simple (5 Ko) | Complexe (50 Ko) | Site réel (200 Ko) |
|---|---|---|---|
| html2text | Modérée | Plus lente | Plus lente |
| markdownify | Plus lente | Plus lente | La plus lente |
| html-to-markdown | Rapide | Rapide | Rapide |
| trafilatura | Rapide | Très rapide | Très rapide |
| html2md (asynchrone) | Très rapide | Très rapide | La plus rapide |
Observations clés :
html2mdettrafilaturasont les plus rapides pour les documents complexes, idéaux pour les conversions en lotshtml-to-markdownoffre le meilleur équilibre entre vitesse et fonctionnalités pour l’utilisation en productionmarkdownifyest plus lent mais le plus flexible — le compromis est justifié lorsqu’on a besoin de gestionnaires personnaliséshtml2textmontre son âge avec une performance plus lente, mais reste stable pour les cas d’utilisation simples
Note : Les différences de performance deviennent significatives uniquement lorsqu’on traite des centaines ou des milliers de fichiers. Pour des conversions occasionnelles, n’importe quelle bibliothèque fonctionnera bien. Concentrez-vous sur les fonctionnalités et les options de personnalisation.
Cas d’utilisation réels
La théorie est utile, mais des exemples pratiques démontrent comment ces outils fonctionnent en production. Voici quatre scénarios courants avec du code complet, prêt à la production, que vous pouvez adapter à vos propres projets.
Cas d’utilisation 1 : Préparation de données de formation LLM
Exigence : Extraire un texte propre à partir de milliers de pages de documentation
Recommandé : trafilatura + traitement parallèle
import trafilatura
from pathlib import Path
from concurrent.futures import ProcessPoolExecutor
def process_html_file(html_path):
"""Convertir un fichier HTML en markdown"""
html = Path(html_path).read_text(encoding='utf-8')
markdown = trafilatura.extract(
html,
output_format='markdown',
include_links=False, # Supprimer pour des données de formation plus propres
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
# Traiter 10 000 fichiers en parallèle
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"Traité {len(html_files)} fichiers")
print(f"Caractères totaux : {sum(token_counts):,}")
Cas d’utilisation 2 : Migration de blog WordPress vers Hugo
Exigence : Migrer un blog WordPress vers Hugo avec le frontmatter
Recommandé : html2md CLI
Hugo est un générateur de site statique populaire qui utilise le Markdown pour le contenu. Pour plus de conseils spécifiques à Hugo, consultez notre Feuille de triche Hugo et apprenez à Ajouter des balises de données structurées à un site Hugo. Notre hub d’outils de documentation a d’autres guides sur les workflows Markdown et la conversion de documents.
# Convertir tous les posts avec le frontmatter
m1f-html2md convert ./wordpress-export \
-o ./hugo/content/posts \
--generate-frontmatter \
--heading-offset 0 \
--remove-tags script,style,nav,footer
Ou programmablement :
from html_to_markdown import convert, Options
from pathlib import Path
import yaml
def migrate_post(html_file):
"""Convertir un HTML WordPress en markdown Hugo"""
html = Path(html_file).read_text()
# Extraire le titre et la date à partir du HTML
from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'html.parser')
title = soup.find('h1').get_text() if soup.find('h1') else 'Titre non spécifié'
# Convertir en markdown
options = Options(strip_tags=['script', 'style', 'nav', 'footer'])
markdown = convert(html, options=options)
# Ajouter le frontmatter Hugo
frontmatter = {
'title': title,
'date': '2024-10-24',
'draft': False,
'tags': []
}
output = f"---\n{yaml.dump(frontmatter)}---\n\n{markdown}"
# Sauvegarder
output_file = html_file.replace('.html', '.md')
Path(output_file).write_text(output, encoding='utf-8')
# Traiter tous les posts
for html_file in Path('./wordpress-export').glob('*.html'):
migrate_post(html_file)
Cas d’utilisation 3 : Scraper de documentation avec mise en forme personnalisée
Exigence : Scraper des documents techniques avec une gestion personnalisée des blocs de code
Recommandé : markdownify avec convertisseur personnalisé
Cette approche est particulièrement utile pour migrer la documentation à partir de systèmes wiki. Si vous gérez la documentation, vous pourriez également être intéressé par DokuWiki - wiki autohébergé et alternatives pour des solutions de documentation autohébergées.
from markdownify import MarkdownConverter
import requests
class DocsConverter(MarkdownConverter):
"""Convertisseur personnalisé pour la documentation technique"""
def convert_pre(self, el, text, convert_as_inline):
"""Bloc de code amélioré avec mise en surbrillance de la syntaxe"""
code = el.find('code')
if code:
# Extraire la langue à partir de la classe
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):
"""Gérer les blocs de documentation spéciaux"""
classes = el.get('class', [])
# Blocs d'avertissement
if 'warning' in classes:
return f'\n> ⚠️ **Avertissement** : {text}\n'
# Blocs d'information
if 'info' in classes or 'note' in classes:
return f'\n> 💡 **Note** : {text}\n'
return text
def scrape_docs(url):
"""Scraper et convertir une page de documentation"""
response = requests.get(url)
markdown = DocsConverter().convert(response.text)
return markdown
# Utilisation
docs_url = "https://docs.example.com/api-reference"
markdown = scrape_docs(docs_url)
Path('api-reference.md').write_text(markdown)
Cas d’utilisation 4 : Conversion de newsletters HTML en archive Markdown
Exigence : Convertir des newsletters HTML en markdown lisible
Recommandé : html2text avec configuration spécifique
import html2text
import email
from pathlib import Path
def convert_newsletter(email_file):
"""Convertir une newsletter HTML en markdown"""
# Parser l'email
with open(email_file, 'r') as f:
msg = email.message_from_file(f)
# Obtenir le contenu 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
# Configurer le convertisseur
h = html2text.HTML2Text()
h.ignore_images = False
h.images_to_alt = True
h.body_width = 0
h.protect_links = True
h.unicode_snob = True
# Convertir
markdown = h.handle(html_content)
# Ajouter les métadonnées
subject = msg.get('Subject', 'Aucun sujet')
date = msg.get('Date', '')
output = f"# {subject}\n\n*Date : {date}*\n\n---\n\n{markdown}"
return output
# Traiter l'archive de newsletters
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')
Recommandations par scénario
Encore incertain duquel choisir ? Voici un guide basé sur des cas d’utilisation spécifiques.
Pour le scraping web et le prétraitement LLM
Gagnant : trafilatura
Trafilatura excelle à extraire un contenu propre tout en supprimant les éléments superflus. Idéal pour :
- Construire des jeux de données de formation LLM
- Agrégation de contenu
- Collecte de recherches académiques
- Extraction d’articles de presse
Pour les migrations Hugo/Jekyll
Gagnant : html2md
Le traitement asynchrone et la génération de frontmatter rendent les migrations en lots rapides et faciles :
- Conversions en lots
- Extraction automatique des métadonnées
- Génération de frontmatter YAML
- Ajustement des niveaux de titres
Pour la logique de conversion personnalisée
Gagnant : markdownify
Hériter du convertisseur pour un contrôle complet :
- Gestionnaires de balises personnalisés
- Conversions spécifiques au domaine
- Exigences de formatage spéciales
- Intégration avec le code existant BeautifulSoup
Pour les systèmes de production typés
Gagnant : html-to-markdown
Moderne, typé et complet :
- Support complet de HTML5
- Indications de type complètes
- Gestion avancée des tableaux
- Maintenance active
Pour les conversions simples et stables
Gagnant : html2text
Lorsque vous avez besoin de quelque chose qui “fonctionne” :
- Aucune dépendance
- Testé en bataille
- Options de configuration étendues
- Support large des plateformes
Bonnes pratiques pour le prétraitement des LLM
Quelle que soit la bibliothèque que vous choisissez, suivre ces bonnes pratiques garantira une sortie Markdown de haute qualité optimisée pour la consommation par les LLM. Ces modèles se sont avérés essentiels dans les workflows de production traitant des millions de documents.
1. Nettoyer avant la conversion
Supprimez toujours les éléments indésirables avant la conversion pour obtenir une sortie plus propre et une meilleure performance :
from bs4 import BeautifulSoup
import trafilatura
def clean_and_convert(html):
"""Supprimer les éléments indésirables avant la conversion"""
soup = BeautifulSoup(html, 'html.parser')
# Supprimer les éléments indésirables
for element in soup(['script', 'style', 'nav', 'footer', 'header', 'aside']):
element.decompose()
# Supprimer les publicités et le suivi
for element in soup.find_all(class_=['ad', 'advertisement', 'tracking']):
element.decompose()
# Convertir le HTML nettoyé
markdown = trafilatura.extract(
str(soup),
output_format='markdown'
)
return markdown
2. Normaliser les espaces blancs
Les convertisseurs gèrent les espaces blancs différemment. Normalisez la sortie pour assurer la cohérence à travers votre corpus :
import re
def normalize_markdown(markdown):
"""Nettoyer l'espacement Markdown"""
# Supprimer les lignes vides multiples
markdown = re.sub(r'\n{3,}', '\n\n', markdown)
# Supprimer les espaces en fin de ligne
markdown = '\n'.join(line.rstrip() for line in markdown.split('\n'))
# Assurer une seule ligne de fin
markdown = markdown.rstrip() + '\n'
return markdown
3. Valider la sortie
Le contrôle de qualité est essentiel. Implémentez une validation pour détecter les erreurs de conversion précocement :
def validate_markdown(markdown):
"""Valider la qualité du Markdown"""
issues = []
# Vérifier les restes d'HTML
if '<' in markdown and '>' in markdown:
issues.append("Des balises HTML ont été détectées")
# Vérifier les liens brisés
if '[' in markdown and ']()' in markdown:
issues.append("Lien vide détecté")
# Vérifier les blocs de code excessifs
code_block_count = markdown.count('```')
if code_block_count % 2 != 0:
issues.append("Bloc de code non fermé")
return len(issues) == 0, issues
4. Modèle de traitement par lots
Lorsque vous traitez de grandes collections de documents, utilisez ce modèle prêt pour la production avec un bon traitement des erreurs, un journalisation appropriée et un traitement parallèle :
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):
"""Traiter un seul fichier 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:
# Normaliser
markdown = normalize_markdown(markdown)
# Valider
is_valid, issues = validate_markdown(markdown)
if not is_valid:
logger.warning(f"{html_path}: {', '.join(issues)}")
# Enregistrer
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"Erreur lors du traitement de {html_path}: {e}")
return False
def batch_convert(input_dir, max_workers=4):
"""Convertir tous les fichiers HTML dans un répertoire"""
html_files = list(Path(input_dir).rglob('*.html'))
logger.info(f"Trouvé {len(html_files)} fichiers HTML")
with ProcessPoolExecutor(max_workers=max_workers) as executor:
results = list(executor.map(process_file, html_files))
success_count = sum(results)
logger.info(f"Converti avec succès {success_count}/{len(html_files)} fichiers")
# Utilisation
batch_convert('./html_docs', max_workers=8)
Conclusion
L’écosystème Python propose des outils matures et prêts pour la production pour la conversion HTML en Markdown, chacun optimisé pour des scénarios différents. Votre choix doit correspondre à vos besoins spécifiques :
- Conversions rapides : Utilisez
html2textpour sa simplicité et l’absence de dépendances - Logique personnalisée : Utilisez
markdownifypour une flexibilité maximale grâce à la sous-classification - Raspagem web : Utilisez
trafilaturapour une extraction intelligente du contenu avec suppression de la mise en page - Migrations en masse : Utilisez
html2mdpour des performances asynchrones sur de grands projets - Systèmes de production : Utilisez
html-to-markdownpour la sécurité de type et le support complet de HTML5 - Préservation sémantique : Utilisez
domscribepour préserver la structure sémantique HTML5
Recommandations pour les workflows LLM
Pour les workflows de prétraitement LLM, il est recommandé d’adopter une approche à deux niveaux :
- Commencer par
trafilaturapour l’extraction initiale du contenu — il supprime intelligemment les éléments de navigation, les publicités et la mise en page tout en préservant le contenu principal - Passer à
html-to-markdownpour les documents complexes nécessitant une préservation précise de la structure, tels que la documentation technique avec des tableaux et des blocs de code
Cette combinaison gère efficacement 95 % des scénarios du monde réel.
Étapes suivantes
Pour plus de guides sur le Markdown, le LaTeX, le traitement des PDF et les workflows d’impression de documents, consultez Outils de Documentation en 2026 : Markdown, LaTeX, PDF & Workflows d’Impression.
Tous ces outils (sauf html2text) sont activement maintenus et prêts pour la production. Il est préférable de :
- Installer 2 à 3 bibliothèques correspondant à votre cas d’utilisation
- Les tester avec vos échantillons HTML réels
- Évaluer leurs performances avec les tailles de documents typiques
- Choisir en fonction de la qualité de la sortie, pas seulement de la vitesse
L’écosystème Python pour la conversion HTML en Markdown a mûri considérablement, et vous ne pouvez pas vous tromper avec l’une de ces options pour leurs cas d’utilisation prévus.
Ressources supplémentaires
- Documentation html2text
- markdownify sur PyPI
- html-to-markdown sur GitHub
- Documentation trafilatura
- Documentation html2md
- domscribe sur PyPI
Note : Cette comparaison est basée sur l’analyse de la documentation officielle, des retours de la communauté et de l’architecture des bibliothèques. Les caractéristiques de performance sont représentatives des schémas d’utilisation typiques. Pour des cas d’utilisation spécifiques, effectuez vos propres benchmarks avec vos échantillons HTML réels.
Autres articles utiles
- Outils de Documentation en 2026 : Markdown, LaTeX, PDF & Workflows d’Impression
- Feuille de rappel Markdown
- Utilisation des blocs de code Markdown
- Convertir des documents Word en Markdown : Un guide complet
- Convertir du contenu HTML en Markdown à l’aide d’un LLM et d’Ollama
- Feuille de rappel cURL
- Feuille de rappel de générateur de site statique Hugo
- Dokuwiki - wiki autohébergé et les alternatives
- Utilisation d’Obsidian pour la gestion de la connaissance personnelle