Convertir HTML en Markdown avec Python : Un guide complet

Python pour convertir HTML en Markdown propre et prêt à l'usage avec un LLM

Sommaire

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.

infographie : conversion de page de HTML en Markdown

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 :

  1. Efficacité des tokens : Le Markdown utilise nettement moins de tokens que le HTML pour le même contenu
  2. Clarté sémantique : Le Markdown préserve la structure du document sans balises verbeuses
  3. Lisibilité : Les humains et les LLM peuvent facilement analyser la syntaxe Markdown
  4. Consistance : Le format standardisé réduit l’ambiguïté dans les entrées du modèle
  5. 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'![{alt}]({src} "{title}")'
        return f'![{alt}]({src})'

    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 :

  1. HTML simple : Article de blog basique avec texte, titres et liens (5 Ko)
  2. HTML complexe : Documentation technique avec tableaux imbriqués et blocs de code (50 Ko)
  3. 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 :

  • html2md et trafilatura sont les plus rapides pour les documents complexes, idéaux pour les conversions en lots
  • html-to-markdown offre le meilleur équilibre entre vitesse et fonctionnalités pour l’utilisation en production
  • markdownify est plus lent mais le plus flexible — le compromis est justifié lorsqu’on a besoin de gestionnaires personnalisés
  • html2text montre 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 html2text pour sa simplicité et l’absence de dépendances
  • Logique personnalisée : Utilisez markdownify pour une flexibilité maximale grâce à la sous-classification
  • Raspagem web : Utilisez trafilatura pour une extraction intelligente du contenu avec suppression de la mise en page
  • Migrations en masse : Utilisez html2md pour des performances asynchrones sur de grands projets
  • Systèmes de production : Utilisez html-to-markdown pour la sécurité de type et le support complet de HTML5
  • Préservation sémantique : Utilisez domscribe pour 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 :

  1. Commencer par trafilatura pour 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
  2. Passer à html-to-markdown pour 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 :

  1. Installer 2 à 3 bibliothèques correspondant à votre cas d’utilisation
  2. Les tester avec vos échantillons HTML réels
  3. Évaluer leurs performances avec les tailles de documents typiques
  4. 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

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