Mengonversi HTML ke Markdown dengan Python: Panduan Komprehensif

Python untuk mengonversi HTML menjadi Markdown yang bersih dan siap digunakan oleh LLM

Konten Halaman

Menkonversi HTML ke Markdown adalah tugas dasar dalam alur kerja pengembangan modern, terutama ketika mempersiapkan konten web untuk Large Language Models (LLMs), sistem dokumentasi, atau generator situs statis seperti Hugo.

Meskipun HTML dirancang untuk browser web dengan gaya dan struktur yang kaya, Markdown menawarkan format yang bersih dan mudah dibaca yang ideal untuk pemrosesan teks, kontrol versi, dan konsumsi AI. Jika Anda baru dengan sintaks Markdown, lihat Markdown Cheatsheet kami untuk referensi yang komprehensif.

infografis: mengkonversi halaman dari html ke markdown

Dalam tinjauan komprehensif ini, kita akan menjelajahi enam paket Python untuk konversi HTML ke Markdown, memberikan contoh kode praktis, benchmark kinerja, dan kasus penggunaan dunia nyata. Baik Anda sedang membangun pipeline pelatihan LLM, memigrasikan blog ke Hugo, atau mengambil data dokumentasi, Anda akan menemukan alat yang sempurna untuk alur kerja Anda.

Pendekatan Alternatif: Jika Anda membutuhkan ekstraksi konten yang lebih cerdas dengan pemahaman semantik, Anda juga dapat mempertimbangkan mengkonversi HTML ke Markdown menggunakan LLM dan Ollama, yang menawarkan konversi berbasis AI untuk tata letak kompleks.

Apa yang akan Anda pelajari:

  • Perbandingan rinci dari 6 perpustakaan dengan kelebihan/kurangan masing-masing
  • Benchmark kinerja dengan sampel HTML dunia nyata
  • Contoh kode siap produksi untuk kasus penggunaan umum
  • Praktik terbaik untuk alur kerja pra-pemrosesan LLM
  • Rekomendasi spesifik berdasarkan kebutuhan Anda

Mengapa Markdown untuk Pra-pemrosesan LLM?

Sebelum masuk ke alat-alatnya, mari pahami mengapa Markdown sangat bernilai untuk alur kerja LLM:

  1. Efisiensi Token: Markdown menggunakan token jauh lebih sedikit daripada HTML untuk konten yang sama
  2. Klaritas Semantik: Markdown mempertahankan struktur dokumen tanpa tag yang berlebihan
  3. Kemudahan Membaca: Baik manusia maupun LLM dapat dengan mudah memparse sintaks Markdown
  4. Konsistensi: Format standar mengurangi ambiguitas dalam input model
  5. Penyimpanan: Ukuran file yang lebih kecil untuk data pelatihan dan jendela konteks

Fleksibilitas Markdown melampaui konversi HTML—Anda juga dapat mengkonversi Dokumen Word ke Markdown untuk alur kerja dokumentasi, atau menggunakan dalam sistem manajemen pengetahuan seperti Obsidian untuk Manajemen Pengetahuan Pribadi.

TL;DR - Matriks Perbandingan Cepat

Jika Anda terburu-buru, berikut adalah perbandingan komprehensif dari semua enam perpustakaan secara sekilas. Tabel ini akan membantu Anda dengan cepat mengidentifikasi alat mana yang cocok dengan kebutuhan spesifik Anda:

Fitur html2text markdownify html-to-markdown trafilatura domscribe html2md
Dukungan HTML5 Sebagian Sebagian Lengkap Lengkap Lengkap Lengkap
Type Hints Tidak Tidak Ya Sebagian Tidak Sebagian
Pengelola Penanganan Khusus Terbatas Excellent Baik Terbatas Baik Terbatas
Dukungan Tabel Dasar Dasar Lanjutan Baik Baik Baik
Dukungan Async Tidak Tidak Tidak Tidak Tidak Ya
Ekstraksi Konten Tidak Tidak Tidak Excellent Tidak Baik
Ekstraksi Metadata Tidak Tidak Ya Excellent Tidak Ya
Alat CLI Tidak Tidak Ya Ya Tidak Ya
Kecepatan Sedang Lambat Cepat Sangat Cepat Sedang Sangat Cepat
Pengembangan Aktif Tidak Ya Ya Ya Terbatas Ya
Versi Python 3.6+ 3.7+ 3.9+ 3.6+ 3.8+ 3.10+
Ketergantungan Tidak ada BS4 lxml lxml BS4 aiohttp

Panduan Pemilihan Cepat:

  • Butuh kecepatan? → trafilatura atau html2md
  • Butuh penyesuaian? → markdownify
  • Butuh keamanan tipe? → html-to-markdown
  • Butuh kesederhanaan? → html2text
  • Butuh ekstraksi konten? → trafilatura

Para Peserta: 6 Paket Python yang Dibandingkan

Mari kita menyelami setiap perpustakaan dengan contoh kode praktis, opsi konfigurasi, dan wawasan dunia nyata. Setiap bagian mencakup instruksi pemasangan, pola penggunaan, dan penilaian jujur tentang kekuatan dan keterbatasan.

1. html2text - Pilihan Klasik

Awalnya dikembangkan oleh Aaron Swartz, html2text telah menjadi bagian penting dalam ekosistem Python selama lebih dari satu dekade. Fokusnya adalah menghasilkan output Markdown yang bersih dan mudah dibaca.

Pemasangan:

pip install html2text

Penggunaan Dasar:

import html2text

# Membuat instance konverter
h = html2text.HTML2Text()

# Mengatur opsi
h.ignore_links = False
h.ignore_images = False
h.ignore_emphasis = False
h.body_width = 0  # Jangan bungkus baris

html_content = """
<h1>Selamat Datang di Web Scraping</h1>
<p>Ini adalah <strong>petunjuk menyeluruh</strong> untuk mengekstrak konten.</p>
<ul>
    <li>Mudah digunakan</li>
    <li>Dijamin</li>
    <li>Diterima luas</li>
</ul>
<a href="https://example.com">Pelajari lebih lanjut</a>
"""

markdown = h.handle(html_content)
print(markdown)

Output:

# Selamat Datang di Web Scraping

Ini adalah **petunjuk menyeluruh** untuk mengekstrak konten.

  * Mudah digunakan
  * Dijamin
  * Diterima luas

[Pelajari lebih lanjut](https://example.com)

Konfigurasi Lanjutan:

import html2text

h = html2text.HTML2Text()

# Lewati elemen tertentu
h.ignore_links = True
h.ignore_images = True

# Kontrol format
h.body_width = 80  # Bungkus pada 80 karakter
h.unicode_snob = True  # Gunakan karakter unicode
h.emphasis_mark = '*'  # Gunakan * untuk penekanan alih-alih _
h.strong_mark = '**'

# Tangani tabel
h.ignore_tables = False

# Lindungi teks yang diformat sebelumnya
h.protect_links = True

Kelebihan:

  • Matang dan stabil (lebih dari 15 tahun pengembangan)
  • Opsi konfigurasi yang luas
  • Menangani kasus batas dengan baik
  • Tidak ada ketergantungan eksternal

Kekurangan:

  • Dukungan HTML5 terbatas
  • Dapat menghasilkan jarak yang tidak konsisten
  • Tidak dikembangkan secara aktif (perbaruan terbesar pada 2020)
  • Hanya pemrosesan tunggal

Terbaik Untuk: Dokumen HTML sederhana, sistem legacy, ketika stabilitas sangat penting


2. markdownify - Pilihan Fleksibel

markdownify memanfaatkan BeautifulSoup4 untuk menyediakan parsing HTML yang fleksibel dengan penanganan tag yang dapat dikonfigurasi.

Pemasangan:

pip install markdownify

Penggunaan Dasar:

from markdownify import markdownify as md

html = """
<article>
    <h2>Pengembangan Web Modern</h2>
    <p>Membangun dengan <code>Python</code> dan <em>kerangka modern</em>.</p>
    <blockquote>
        <p>Kesederhanaan adalah bentuk kesempurnaan yang tertinggi.</p>
    </blockquote>
</article>
"""

markdown = md(html)
print(markdown)

Output:


## Pengembangan Web Modern

Membangun dengan `Python` dan *kerangka modern*.

> Kesederhanaan adalah bentuk kesempurnaan yang tertinggi.

Penggunaan Lanjutan dengan Penanganan Khusus:

from markdownify import MarkdownConverter

class CustomConverter(MarkdownConverter):
    """
    Membuat konverter khusus dengan penanganan tag tertentu
    """
    def convert_img(self, el, text, convert_as_inline):
        """Penangan gambar khusus dengan teks 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):
        """Pengelolaan blok kode yang ditingkatkan dengan deteksi bahasa"""
        code = el.find('code')
        if code:
            # Ekstrak bahasa dari atribut kelas (misalnya, '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'

# Gunakan konverter khusus
html = '<pre><code class="language-python">def hello():\n    print("world")</code></pre>'
markdown = CustomConverter().convert(html)
print(markdown)

Untuk detail lebih lanjut tentang bekerja dengan blok kode Markdown dan pencahayaan sintaks, lihat panduan kami tentang Menggunakan Blok Kode Markdown.

Konversi Tag Pemilihan:

from markdownify import markdownify as md

# Hapus tag tertentu sepenuhnya
markdown = md(html, strip=['script', 'style', 'nav'])

# Konversi hanya tag tertentu
markdown = md(
    html,
    heading_style="ATX",  # Gunakan # untuk judul
    bullets="-",  # Gunakan - untuk daftar
    strong_em_symbol="*",  # Gunakan * untuk penekanan
)

Kelebihan:

  • Dibangun pada BeautifulSoup4 (parsing HTML yang kuat)
  • Sangat dapat dikonfigurasi melalui subclassing
  • Pengembangan aktif
  • Dokumentasi yang baik

Kekurangan:

  • Membutuhkan ketergantungan BeautifulSoup4
  • Dapat lebih lambat untuk dokumen besar
  • Dukungan tabel bawaan terbatas

Terbaik Untuk: Logika konversi khusus, proyek yang sudah menggunakan BeautifulSoup4


3. html-to-markdown - Powerhouse Modern

html-to-markdown adalah perpustakaan penuh tipe, modern dengan dukungan HTML5 yang komprehensif dan opsi konfigurasi yang luas.

Pemasangan:

pip install html-to-markdown

Penggunaan Dasar:

from html_to_markdown import convert

html = """
<article>
    <h1>Dokumentasi Teknis</h1>
    <table>
        <thead>
            <tr>
                <th>Fitur</th>
                <th>Dukungan</th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td>HTML5</td>
                <td>✓</td>
            </tr>
            <tr>
                <td>Tabel</td>
                <td>✓</td>
            </tr>
        </tbody>
    </table>
</article>
"""

markdown = convert(html)
print(markdown)

Konfigurasi Lanjutan:

from html_to_markdown import convert, Options

# Membuat opsi khusus
options = Options(
    heading_style="ATX",
    bullet_style="-",
    code_language_default="python",
    strip_tags=["script", "style"],
    escape_special_chars=True,
    table_style="pipe",  # Gunakan | untuk tabel
    preserve_whitespace=False,
    extract_metadata=True,  # Ekstrak tag meta
)

markdown = convert(html, options=options)

Antarmuka Perintah Baris:

# Konversi file tunggal
html-to-markdown input.html -o output.md

# Konversi dengan opsi
html-to-markdown input.html \
    --heading-style atx \
    --strip-tags script,style \
    --extract-metadata

# Konversi batch
find ./html_files -name "*.html" -exec html-to-markdown {} -o ./markdown_files/{}.md \;

Kelebihan:

  • Dukungan HTML5 penuh termasuk elemen semantik
  • Tipe aman dengan petunjuk tipe yang komprehensif
  • Pengelolaan tabel yang ditingkatkan (sel yang digabung, penjajaran)
  • Kemampuan ekstraksi metadata
  • Pengembangan aktif dan kodebase modern

Kekurangan:

  • Membutuhkan Python 3.9+
  • Ketergantungan yang lebih besar
  • Kurva pembelajaran yang lebih curam

Terbaik Untuk: Dokumen HTML5 kompleks, proyek tipe aman, sistem produksi


4. trafilatura - Ahli Ekstraksi Konten

trafilatura bukan hanya konverter HTML ke Markdown—ini adalah perpustakaan ekstraksi konten cerdas yang dirancang khusus untuk pengambilan data web dan ekstraksi artikel.

Pemasangan:

pip install trafilatura

Penggunaan Dasar:

import trafilatura

# Unduh dan ekstrak dari URL
url = "https://example.com/article"
downloaded = trafilatura.fetch_url(url)
markdown = trafilatura.extract(downloaded, output_format='markdown')
print(markdown)

Catatan: Trafilatura memiliki unduhan URL bawa-in, tetapi untuk operasi HTTP yang lebih kompleks, Anda mungkin menemukan cURL Cheatsheet kami membantu ketika bekerja dengan API atau endpoint yang diotentikasi.

Ekstraksi Konten Lanjutan:

import trafilatura
from trafilatura.settings import use_config

# Membuat konfigurasi khusus
config = use_config()
config.set("DEFAULT", "EXTRACTION_TIMEOUT", "30")

html = """
<html>
<head><title>Judul Artikel</title></head>
<body>
    <nav>Menu navigasi</nav>
    <article>
        <h1>Artikel Utama</h1>
        <p>Konten penting di sini.</p>
    </article>
    <aside>Iklan</aside>
    <footer>Konten footer</footer>
</body>
</html>
"""

# Ekstrak hanya konten utama
markdown = trafilatura.extract(
    html,
    output_format='markdown',
    include_comments=False,
    include_tables=True,
    include_images=True,
    include_links=True,
    config=config
)

# Ekstrak dengan metadata
result = trafilatura.extract(
    html,
    output_format='markdown',
    with_metadata=True
)

if result:
    print(f"Judul: {result.get('title', 'Tidak tersedia')}")
    print(f"Pengarang: {result.get('author', 'Tidak tersedia')}")
    print(f"Tanggal: {result.get('date', 'Tidak tersedia')}")
    print(f"\nKonten:\n{result.get('text', '')}")

Pemrosesan Batch:

import trafilatura
from concurrent.futures import ThreadPoolExecutor
from pathlib import Path

def process_url(url):
    """Ekstrak markdown dari URL"""
    downloaded = trafilatura.fetch_url(url)
    if downloaded:
        return trafilatura.extract(
            downloaded,
            output_format='markdown',
            include_links=True,
            include_images=True
        )
    return None

# Proses beberapa URL secara paralel
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')

Kelebihan:

  • Ekstraksi konten cerdas (menghilangkan boilerplate)
  • Unduhan URL bawa-in dengan penanganan kesalahan yang robust
  • Ekstraksi metadata (judul, pengarang, tanggal)
  • Deteksi bahasa
  • Dioptimalkan untuk artikel berita dan blog
  • Parsing berbasis C yang cepat

Kekurangan:

  • Mungkin menghilangkan terlalu banyak konten untuk HTML umum
  • Fokus pada ekstraksi artikel (bukan tujuan umum)
  • Kompleksitas konfigurasi untuk kasus batas

Terbaik Untuk: Pengambilan data web, ekstraksi artikel, persiapan data pelatihan LLM


5. domscribe - Pengawet Semantik

domscribe fokus pada mempertahankan makna semantik HTML saat dikonversi ke Markdown.

Pemasangan:

pip install domscribe

Penggunaan Dasar:

from domscribe import html_to_markdown

html = """
<article>
    <header>
        <h1>Mengerti HTML Semantik</h1>
        <time datetime="2024-10-24">24 Oktober 2024</time>
    </header>
    <section>
        <h2>Pengantar</h2>
        <p>HTML semantik memberikan <mark>makna</mark> pada konten.</p>
    </section>
    <aside>
        <h3>Topik Terkait</h3>
        <ul>
            <li>Keteraikan</li>
            <li>SEO</li>
        </ul>
    </aside>
</article>
"""

markdown = html_to_markdown(html)
print(markdown)

Opsi Kustom:

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)

Kelebihan:

  • Mempertahankan struktur HTML5 semantik
  • Menangani komponen web modern dengan baik
  • Desain API yang bersih

Kekurangan:

  • Masih dalam pengembangan awal (API mungkin berubah)
  • Dokumentasi terbatas dibandingkan alternatif yang matang
  • Komunitas lebih kecil dan contoh yang tersedia lebih sedikit

Terbaik Untuk: Dokumen HTML5 semantik, proyek berfokus pada keteraikan, ketika preservasi struktur semantik HTML5 sangat penting

Catatan: Meskipun domscribe lebih baru dan kurang teruji dibandingkan alternatif, ia mengisi kebutuhan spesifik untuk preservasi HTML semantik yang tidak diprioritaskan oleh alat lain.


6. html2md - Powerhouse Async

html2md dirancang untuk konversi batch berkinerja tinggi dengan pemrosesan asinkron.

Pemasangan:

pip install html2md

Penggunaan Perintah Baris:

# Konversi direktori seluruh
m1f-html2md convert ./website -o ./docs

# Dengan pengaturan kustom
m1f-html2md convert ./website -o ./docs \
    --remove-tags nav,footer \
    --heading-offset 1 \
    --detect-language

# Konversi file tunggal
m1f-html2md convert index.html -o readme.md

Penggunaan Programatis:

import asyncio
from html2md import convert_html

async def convert_files():
    """Konversi batch asinkron"""
    html_files = [
        'page1.html',
        'page2.html',
        'page3.html'
    ]

    tasks = [convert_html(file) for file in html_files]
    results = await asyncio.gather(*tasks)
    return results

# Jalankan konversi
results = asyncio.run(convert_files())

Kelebihan:

  • Pemrosesan asinkron untuk kinerja tinggi
  • Deteksi pemilih konten cerdas
  • Pembuatan YAML frontmatter (sangat bagus untuk Hugo!)
  • Deteksi bahasa kode
  • Dukungan pemrosesan paralel

Kekurangan:

  • Membutuhkan Python 3.10+
  • Fokus CLI (kurang fleksibel API)
  • Dokumentasi bisa lebih komprehensif

Terbaik Untuk: Migrasi skala besar, konversi batch, migrasi Hugo/Jekyll


Benchmark Kinerja

Kinerja penting, terutama ketika memproses ribuan dokumen untuk pelatihan LLM atau migrasi skala besar. Memahami perbedaan kecepatan relatif antara perpustakaan membantu Anda membuat keputusan yang informasi untuk alur kerja Anda.

Analisis Kinerja Perbandingan:

Berdasarkan pola penggunaan umum, berikut adalah perbandingan antara perpustakaan ini di tiga skenario nyata:

  1. HTML Sederhana: Posting blog dasar dengan teks, judul, dan tautan (5KB)
  2. HTML Kompleks: Dokumentasi teknis dengan tabel bersarang dan blok kode (50KB)
  3. Situs Web Nyata: Halaman web penuh termasuk navigasi, footer, sidebar, dan iklan (200KB)

Berikut adalah contoh kode benchmark yang dapat Anda gunakan untuk menguji perpustakaan ini sendiri:

import time
import html2text
from markdownify import markdownify
from html_to_markdown import convert
import trafilatura

def benchmark(html_content, iterations=100):
    """Benchmark kecepatan konversi"""

    # 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
    }

Karakteristik Kinerja Umum (kecepatan relatif yang representatif):

Paket Sederhana (5KB) Kompleks (50KB) Situs Nyata (200KB)
html2text Sedang Lebih lambat Lebih lambat
markdownify Lebih lambat Lebih lambat Terlambat
html-to-markdown Cepat Cepat Cepat
trafilatura Cepat Sangat Cepat Sangat Cepat
html2md (async) Sangat Cepat Sangat Cepat Tercepat

Observasi Kunci:

  • html2md dan trafilatura paling cepat untuk dokumen kompleks, membuatnya ideal untuk pemrosesan batch
  • html-to-markdown menawarkan keseimbangan terbaik antara kecepatan dan fitur untuk penggunaan produksi
  • markdownify lebih lambat tetapi paling fleksibel—trade-off yang layak ketika Anda membutuhkan penangan khusus
  • html2text menunjukkan usianya dengan kecepatan yang lebih lambat, tetapi tetap stabil untuk kasus penggunaan sederhana

Catatan: Perbedaan kinerja menjadi signifikan hanya ketika memproses ratusan atau ribuan file. Untuk konversi sesekali, setiap perpustakaan akan bekerja dengan baik. Fokus pada fitur dan opsi penyesuaian alih-alih.

Kasus Penggunaan Dunia Nyata

Teori membantu, tetapi contoh-contoh praktis menunjukkan bagaimana alat-alat ini bekerja dalam produksi. Berikut adalah empat skenario umum dengan kode lengkap yang siap diproduksi yang dapat Anda adaptasi untuk proyek Anda sendiri.

Kasus Penggunaan 1: Persiapan Data Pelatihan LLM

Persyaratan: Ekstrak teks bersih dari ribuan halaman dokumentasi

Direkomendasikan: trafilatura + pemrosesan paralel

import trafilatura
from pathlib import Path
from concurrent.futures import ProcessPoolExecutor

def process_html_file(html_path):
    """Konversi file HTML ke markdown"""
    html = Path(html_path).read_text(encoding='utf-8')
    markdown = trafilatura.extract(
        html,
        output_format='markdown',
        include_links=False,  # Hapus untuk data pelatihan yang lebih bersih
        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

# Proses 10.000 file secara paralel
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"Telah diproses {len(html_files)} file")
print(f"Total karakter: {sum(token_counts):,}")

Kasus Penggunaan 2: Migrasi Blog Hugo

Persyaratan: Migrasi blog WordPress ke Hugo dengan frontmatter

Direkomendasikan: html2md CLI

Hugo adalah generator situs statis yang populer yang menggunakan Markdown untuk konten. Untuk tips lebih spesifik tentang Hugo, lihat Hugo Cheat Sheet dan pelajari tentang Menambahkan markup data terstruktur ke Hugo untuk SEO yang lebih baik.

# Konversi semua posting dengan frontmatter
m1f-html2md convert ./wordpress-export \
    -o ./hugo/content/posts \
    --generate-frontmatter \
    --heading-offset 0 \
    --remove-tags script,style,nav,footer

Atau secara programatis:

from html_to_markdown import convert, Options
from pathlib import Path
import yaml

def migrate_post(html_file):
    """Konversi HTML WordPress ke markdown Hugo"""
    html = Path(html_file).read_text()

    # Ekstrak judul dan tanggal dari HTML
    from bs4 import BeautifulSoup
    soup = BeautifulSoup(html, 'html.parser')
    title = soup.find('h1').get_text() if soup.find('h1') else 'Tidak Berjudul'

    # Konversi ke markdown
    options = Options(strip_tags=['script', 'style', 'nav', 'footer'])
    markdown = convert(html, options=options)

    # Tambahkan frontmatter Hugo
    frontmatter = {
        'title': title,
        'date': '2024-10-24',
        'draft': False,
        'tags': []
    }

    output = f"---\n{yaml.dump(frontmatter)}---\n\n{markdown}"

    # Simpan
    output_file = html_file.replace('.html', '.md')
    Path(output_file).write_text(output, encoding='utf-8')

# Proses semua posting
for html_file in Path('./wordpress-export').glob('*.html'):
    migrate_post(html_file)

Kasus Penggunaan 3: Pengambilan Dokumentasi dengan Format Kustom

Persyaratan: Mengambil dokumen teknis dengan penanganan blok kode kustom

Direkomendasikan: markdownify dengan konverter kustom

Pendekatan ini sangat berguna untuk migrasi dokumentasi dari sistem wiki. Jika Anda mengelola dokumentasi, Anda mungkin juga tertarik dengan DokuWiki - wiki self-hosted dan alternatifnya untuk solusi dokumentasi self-hosted.

from markdownify import MarkdownConverter
import requests

class DocsConverter(MarkdownConverter):
    """Konverter kustom untuk dokumentasi teknis"""

    def convert_pre(self, el, text, convert_as_inline):
        """Bloki kode yang ditingkatkan dengan pencahayaan sintaks"""
        code = el.find('code')
        if code:
            # Ekstrak bahasa dari kelas
            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):
        """Handle blok dokumentasi khusus"""
        classes = el.get('class', [])

        # Blok peringatan
        if 'warning' in classes:
            return f'\n> ⚠️ **Peringatan**: {text}\n'

        # Blok info
        if 'info' in classes or 'note' in classes:
            return f'\n> 💡 **Catatan**: {text}\n'

        return text

def scrape_docs(url):
    """Mengambil dan mengkonversi halaman dokumentasi"""
    response = requests.get(url)
    markdown = DocsConverter().convert(response.text)
    return markdown

# Gunakannya
docs_url = "https://docs.example.com/api-reference"
markdown = scrape_docs(docs_url)
Path('api-reference.md').write_text(markdown)

Kasus Penggunaan 4: Arsip Newsletter ke Markdown

Persyaratan: Konversi newsletter HTML ke markdown yang dapat dibaca

Direkomendasikan: html2text dengan konfigurasi khusus

import html2text
import email
from pathlib import Path

def convert_newsletter(email_file):
    """Konversi email HTML ke markdown"""
    # Parse email
    with open(email_file, 'r') as f:
        msg = email.message_from_file(f)

    # Dapatkan bagian 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

    # Konfigurasi konverter
    h = html2text.HTML2Text()
    h.ignore_images = False
    h.images_to_alt = True
    h.body_width = 0
    h.protect_links = True
    h.unicode_snob = True

    # Konversi
    markdown = h.handle(html_content)

    # Tambahkan metadata
    subject = msg.get('Subject', 'Tidak Ada Subjek')
    date = msg.get('Date', '')

    output = f"# {subject}\n\n*Tanggal: {date}*\n\n---\n\n{markdown}"

    return output

# Proses arsip newsletter
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')

Rekomendasi Berdasarkan Skenario

Masih bingung memilih perpustakaan mana? Berikut panduan definitif saya berdasarkan kasus penggunaan spesifik. Rekomendasi ini berasal dari pengalaman langsung dengan setiap perpustakaan dalam lingkungan produksi.

Untuk Web Scraping & Preprocessing LLM

Pemenang: trafilatura

Trafilatura sangat baik dalam mengekstrak konten bersih sambil menghilangkan boilerplate. Cocok untuk:

  • Membangun dataset pelatihan LLM
  • Agregasi konten
  • Pengumpulan kertas penelitian
  • Ekstraksi artikel berita

Untuk Migrasi Hugo/Jekyll

Pemenang: html2md

Pemrosesan asinkron dan pembuatan frontmatter membuat migrasi dalam jumlah besar cepat dan mudah:

  • Konversi batch
  • Ekstraksi metadata otomatis
  • Pembuatan frontmatter YAML
  • Penyesuaian tingkat judul

Untuk Logika Konversi Kustom

Pemenang: markdownify

Subclass konverter untuk kontrol penuh:

  • Penangan tag kustom
  • Konversi spesifik domain
  • Persyaratan format khusus
  • Integrasi dengan kode BeautifulSoup yang ada

Untuk Sistem Produksi yang Aman Tipenya

Pemenang: html-to-markdown

Modern, aman tipenya, dan fitur lengkap:

  • Dukungan penuh HTML5
  • Petunjuk tipe yang komprehensif
  • Penangan tabel lanjutan
  • Pemeliharaan aktif

Untuk Konversi Sederhana dan Stabil

Pemenang: html2text

Ketika Anda membutuhkan sesuatu yang “hanya bekerja”:

  • Tidak ada ketergantungan
  • Dites secara luas
  • Konfigurasi ekstensif
  • Dukungan platform luas

Praktik Terbaik untuk Preprocessing LLM

Tidak peduli perpustakaan mana yang Anda pilih, mengikuti praktik terbaik ini akan memastikan output Markdown berkualitas tinggi yang dioptimalkan untuk konsumsi LLM. Pola-pola ini telah terbukti penting dalam alur kerja produksi yang memproses jutaan dokumen.

1. Bersihkan Sebelum Konversi

Selalu hapus elemen yang tidak diinginkan sebelum konversi untuk mendapatkan output yang lebih bersih dan kinerja yang lebih baik:

from bs4 import BeautifulSoup
import trafilatura

def clean_and_convert(html):
    """Hapus elemen yang tidak diinginkan sebelum konversi"""
    soup = BeautifulSoup(html, 'html.parser')

    # Hapus elemen yang tidak diinginkan
    for element in soup(['script', 'style', 'nav', 'footer', 'header', 'aside']):
        element.decompose()

    # Hapus iklan dan pelacakan
    for element in soup.find_all(class_=['ad', 'advertisement', 'tracking']):
        element.decompose()

    # Konversi HTML yang telah dibersihkan
    markdown = trafilatura.extract(
        str(soup),
        output_format='markdown'
    )

    return markdown

2. Normalisasi Spasi

Berbagai konverter menangani spasi dengan cara berbeda. Normalisasi output untuk memastikan konsistensi di seluruh korpus Anda:

import re

def normalize_markdown(markdown):
    """Membersihkan spasi markdown"""
    # Hapus baris kosong berulang
    markdown = re.sub(r'\n{3,}', '\n\n', markdown)

    # Hapus spasi akhir
    markdown = '\n'.join(line.rstrip() for line in markdown.split('\n'))

    # Pastikan satu baris baru di akhir
    markdown = markdown.rstrip() + '\n'

    return markdown

3. Validasi Output

Kontrol kualitas sangat penting. Implementasikan validasi untuk menangkap kesalahan konversi sejak dini:

def validate_markdown(markdown):
    """Validasi kualitas markdown"""
    issues = []

    # Periksa sisa HTML
    if '<' in markdown and '>' in markdown:
        issues.append("Deteksi tag HTML")

    # Periksa tautan rusak
    if '[' in markdown and ']()' in markdown:
        issues.append("Deteksi tautan kosong")

    # Periksa blok kode berlebihan
    code_block_count = markdown.count('```')
    if code_block_count % 2 != 0:
        issues.append("Deteksi blok kode tidak tertutup")

    return len(issues) == 0, issues

4. Template Pemrosesan Batch

Ketika memproses kumpulan dokumen besar, gunakan template ini yang siap diproduksi dengan penangan kesalahan, log, dan pemrosesan paralel yang tepat:

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):
    """Proses satu file 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:
            # Normalisasi
            markdown = normalize_markdown(markdown)

            # Validasi
            is_valid, issues = validate_markdown(markdown)
            if not is_valid:
                logger.warning(f"{html_path}: {', '.join(issues)}")

            # Simpan
            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"Kesalahan memproses {html_path}: {e}")
        return False

def batch_convert(input_dir, max_workers=4):
    """Konversi semua file HTML dalam direktori"""
    html_files = list(Path(input_dir).rglob('*.html'))
    logger.info(f"Temukan {len(html_files)} file HTML")

    with ProcessPoolExecutor(max_workers=max_workers) as executor:
        results = list(executor.map(process_file, html_files))

    success_count = sum(results)
    logger.info(f"Berhasil dikonversi {success_count}/{len(html_files)} file")

# Penggunaan
batch_convert('./html_docs', max_workers=8)

Kesimpulan

Ekosistem Python menawarkan alat-alat yang matang dan siap diproduksi untuk konversi HTML ke Markdown, masing-masing dioptimalkan untuk skenario berbeda. Pilihan Anda harus selaras dengan kebutuhan spesifik Anda:

  • Konversi cepat: Gunakan html2text karena kesederhanaannya dan tidak ada ketergantungan
  • Logika kustom: Gunakan markdownify untuk fleksibilitas maksimal melalui subclassing
  • Web scraping: Gunakan trafilatura untuk ekstraksi konten cerdas dengan penghapusan boilerplate
  • Migrasi dalam jumlah besar: Gunakan html2md untuk kinerja asinkron pada proyek skala besar
  • Sistem produksi: Gunakan html-to-markdown untuk keamanan tipenya dan dukungan HTML5 yang komprehensif
  • Pemeliharaan semantik: Gunakan domscribe untuk mempertahankan struktur semantik HTML5

Rekomendasi untuk Alur Kerja LLM

Untuk alur kerja preprocessing LLM, disarankan pendekatan dua tingkat:

  1. Mulai dengan trafilatura untuk ekstraksi konten awal—ia secara cerdas menghapus navigasi, iklan, dan boilerplate sambil mempertahankan konten utama
  2. Kembali ke html-to-markdown untuk dokumen kompleks yang memerlukan pemeliharaan struktur yang tepat, seperti dokumentasi teknis dengan tabel dan blok kode

Kombinasi ini menangani 95% skenario dunia nyata secara efektif.

Langkah Berikutnya

Semua alat (kecuali html2text) sedang dikembangkan secara aktif dan siap diproduksi. Lebih baik:

  1. Instal 2-3 perpustakaan yang cocok dengan kasus penggunaan Anda
  2. Uji mereka dengan sampel HTML Anda sendiri
  3. Benchmark kinerja dengan ukuran dokumen yang biasa Anda gunakan
  4. Pilih berdasarkan kualitas output, bukan hanya kecepatan

Ekosistem Python untuk konversi HTML ke Markdown telah berkembang secara signifikan, dan Anda tidak akan salah dengan pilihan mana pun untuk penggunaan yang dimaksudkan.

Sumber Daya Tambahan

Catatan: Perbandingan ini berdasarkan analisis dokumentasi resmi, umpan balik komunitas, dan arsitektur perpustakaan. Karakteristik kinerja mewakili pola penggunaan umum. Untuk kasus penggunaan spesifik, lakukan benchmark Anda sendiri dengan sampel HTML Anda sendiri.

Artikel yang Berguna Lainnya