De populairste HTML-naar-Markdown-bibliotheek zet geen tabellen om

Laatst bijgewerkt op August 17, 2026
De populairste HTML-naar-Markdown-bibliotheek zet geen tabellen om
AI-samenvatting
turndown was op het moment van de metadata-snapshot de meest gestarde van de vier geteste bibliotheken, met 11.386 GitHub-stars. Op de vier gedeelde HTML-voorbeelden leverde het met de standaardinstellingen nul Markdown-tabellen op en gebruikte het 24,6% meer tokens dan markdownify voor dezelfde input. Alle vier haalden ze alle content-probes terug. De verschillen zitten volledig in wat er met de structuur gebeurt — en in wat die structuur downstream aan kosten met zich meebrengt. Voer je een model, of sla je gestructureerde content op van pagina’s zoals deze? Begin met markdownify. Het komt onder deze teller uit op hetzelfde aantal uitgestuurde tabelrijen als markitdown, zit in de laagste tokencluster, is MIT-licensed en installeert in 1,8 MiB.

turndown was op het moment van de metadata-snapshot de meest gestarde van de vier geteste bibliotheken, met 11.386 GitHub-stars. Op de vier gedeelde HTML-voorbeelden leverde het met de standaardinstellingen nul Markdown-tabellen op en gebruikte het 24,6% meer tokens dan markdownify voor dezelfde input.

Alle vier haalden ze alle content-probes terug. De verschillen zitten volledig in wat er met de structuur gebeurt — en in wat die structuur downstream aan kosten met zich meebrengt.

Wat is gemeten, en op wiens voorbeelden

Deze onderzoeksbasis had al een set voor markitdown met vijf HTML-voorbeelden en vooraf vastgelegde probe-strings — exacte strings waarvan werd gecontroleerd of ze behouden bleven, plus boilerplate-strings om paginabediening te detecteren. De gezamenlijke vergelijking gebruikt de vier voorbeelden die alle vier converters delen: een boekwinkelcatalogus, een quotes-site, een hockeystatistiektabel en het Wikipedia-artikel over webscraping. Een vijfde voorbeeld, Nothing but tables, wordt alleen gebruikt als tabelzware diagnose en valt buiten het totaal van 24,6%.

De vier: turndown 7.2.4 (Node), markdownify 1.2.3, html2text 2025.4.15, en markitdown, waarbij de gepubliceerde cijfers 그대로 worden gebruikt. Pagina’s: een boekwinkelcatalogus, een quotes-site, een hockeystatistiektabel en het Wikipedia-artikel over webscraping.

Elke metrieknaam hieronder komt één-op-één overeen met het eigen artifact-veld van markitdown, zodat de rijen netjes naast elkaar kunnen staan zonder dat iemand twee definities van hetzelfde woord hoeft te harmoniseren.

De tabel

Measured results chart: Token output vs Markdown table rows

ConverterBody probesOutput charsTokens (o200k)Bytes/tokenMarkdown table rowsLinks
turndown16/1695,18826,2363.630611
markdownify16/1676,86821,0623.6536599
html2text16/1676,45221,1763.6132545
markitdown16/1676,99521,3363.6136598

Vier voorbeelden — dezelfde die markitdown ook heeft verwerkt. Volledige cijfers per voorbeeld staan in fiveway-scores.json. Tokens geteld met o200k_base; de tabelrijen van markitdown opnieuw geteld uit de eigen opgeslagen Markdown met dezelfde teller als bij de andere.

Contentbehoud is gelijkspel. Alle zestien body-probes over de vier voorbeelden bleven intact in elke converter. Als je enige vraag is: "komt de tekst erdoorheen?", dan is het antwoord bij alle vier ja.

Structuur is geen gelijkspel. Op de vier gedeelde voorbeelden geven markdownify en markitdown allebei 36 Markdown-tabelrijen uit; html2text geeft er 32 uit; turndown geen enkele. In de aparte tabel-only diagnose gaf markdownify 62 rijen en html2text 59; die rijen zijn niet meegenomen in het totaal hierboven.

De tokenkosten zijn 24,6% hoger voor turndown, en dat komt niet door de tabellen. Ik ging er eerst vanuit dat dat wel zo was, maar de cijfers per voorbeeld laten iets anders zien — zie hieronder.

Wat turndown met een tabel doet

Hier is het hockeystatistiek-voorbeeld, dezelfde rijen, op drie manieren.

turndown:

System diagram: Core Table Paths Diverge

Team Name

Year

Wins

Losses

Boston Bruins

1990

44

24

markdownify:

| Team Name | Year | Wins | Losses | ... |
| --- | --- | --- | --- | --- |
| Boston Bruins | 1990 | 44 | 24 | ... |

html2text:

Team Name  |  Year  |  Wins  |  Losses  | ...
---|---|---|---|---
Boston Bruins  |  1990  |  44  |  24  | ...

Elke waarde overleeft de omzetting door turndown, en daarom scoort het 16/16 op de probes. Wat niet behouden blijft, is bij welke kolom elke waarde hoort. Lees je de turndown-uitvoer, dan is 44 gewoon een getal op een regel; je kunt niet terughalen dat dit het aantal overwinningen van Boston is zonder posities te tellen en te hopen dat er geen lege cel was. In dit voorbeeld zijn sommige cellen wel leeg, dus posities tellen werkt ook niet.

Voor een model dat de output leest, is dat het verschil tussen een tabel waar het vragen over kan beantwoorden en een lijst getallen waar het maar naar moet gokken.

Dat is niet zozeer een fout als wel een gedocumenteerde grens — de core van turndown ondersteunt geen tabellen, en turndown-plugin-gfm bestaat om die toe te voegen. Maar de standaardinstallatie bevat die niet, en 11.386 sterren suggereert dat veel mensen gewoon de standaard gebruiken.

Waar het tokenverschil echt vandaan komt

Ik schreef de alinea hierboven in de overtuiging dat de tokenkloof van 24,6% werd veroorzaakt door afgevlakte tabellen als extra tekens. Toen keek ik er per voorbeeld naar, en dat klopt niet.

Voorbeeldturndown tokens ÷ markdownify tokens
Quotes-site (geen tabellen)0,99×
Boekwinkelcatalogus1,06×
Hockeystatistieken (één grote tabel)1,37×
Wikipedia (meestal proza, 9 tabelrijen)1,29×
Alleen tabellen0,78×

Op het voorbeeld dat alleen uit tabellen bestaat, is turndown 22% goedkoper — omdat pipe-structuur ook tokens kost, en turndown die helemaal niet uitspuugt. Een tabel afvlakken is op zichzelf dus geen tokenboete.

Het Wikipedia-voorbeeld is 74% van het totaal, en bevat negen tabelrijen. Het verschil van 15.378 tekens kan dus niet door tabellen komen. Het komt hierdoor:

(function(){var className="client-js vector-feature-language-in-header-enabled…
.mw-parser-output cite.citation{font-style:inherit;word-wrap:break-word}…
(RLQ=window.RLQ||[]).push(function(){mw.config.set({"wgHostname":"mw-web…

turndown verwijdert <script>- en <style>-inhoud niet. markdownify en html2text doen dat wel. Geteld via markers die alleen binnen die elementen voorkomen: de output van turndown bevat over de voorbeelden heen 10 script-markers en 84 style-markers; de andere twee bevatten er nul van beide. Op de Wikipedia-pagina verklaren acht regels met MediaWiki’s inline JavaScript-configuratie en CSS 14.644 tekens — 95% van het hele verschil (script-style-stripping.json).

Dat is de bevinding waar ik in de praktijk iets mee zou doen. Een afgevlakte tabel is een structuurprobleem dat je kunt zien. Een JavaScript-configblob in je Markdown is pure kostenpost zonder inhoudelijke waarde, en op een echte webpagina overheerst het bijna alles in deze vergelijking.

html2text schrijft tabellen die je misschien niet herkent

html2text scoorde 32 rijen waar markdownify en markitdown 36 scoorden, en de eerste versie van mijn teller kwam uit op 1.

Dat lag aan mijn telregel, niet aan de bibliotheek. html2text geeft Team Name | Year | Wins zonder leidende en afsluitende pipes weer — een gangbare Markdown-tabelvorm, maar onzichtbaar voor een regex die ^\|.*\|$ vereist. Ik had die regex geschreven, erop losgelaten en was al klaar om te melden dat html2text geen tabellen doet.

Dat doet het wel. De gecorrigeerde teller gebruikt een heuristiek: een reeks opeenvolgende regels met pipes, met daarin een scheidingsregel. Met die regel gaat html2text van 1 naar 32. Dit is geen volledige Markdown-parser, dus de rijtotalen moeten gelezen worden als metingen onder een gedocumenteerde teller, niet als universele renderresultaten.

Handig om te weten als je de Markdown achteraf met je eigen regex verwerkt: twee van deze vier bibliotheken zetten buitenste pipes, één niet.

De licentie die niemand noemt

ConverterLicentieInstallatieKoude importSterrenLaatste release
turndownMIT3 npm-pakketten, 8,8 MiB0,056 s11.3862026-04-03
markdownifyMIT5 pakketten, 1,8 MiB0,046 s2.2352026-06-30
html2textGPL-3.0-or-later1 pakket, 0,2 MiB0,077 s2.1682025-04-15
markitdownZie pakketmetadataNiet gemeten in deze install-runNiet gemeten——

install-and-import.json. Elke bibliotheek is in een eigen lege omgeving geïnstalleerd. Licenties zijn bevestigd via drie bronnen: de registry-metadata, de GitHub-repository en het eigen METADATA-bestand van het geïnstalleerde pakket, waar License-Expression: GPL-3.0-or-later staat.

De lichtste bibliotheek in deze installvergelijking — één pakket, 0,2 MiB — is GPL-3.0-or-later. Of dat relevant is voor een project hangt af van hoe de software wordt gecombineerd en gedistribueerd. Zie dit als een selectie-checkpoint voor wie verantwoordelijk is voor licenties; dit artikel is geen juridisch advies. markitdown staat hier als niet-gemeten, omdat installatie en licentie in dit specifieke artifact niet zijn vastgelegd.

Dat compromis is makkelijk te missen, omdat de licentie het ene kenmerk is dat je niet in een benchmark ziet.

Alle drie zijn ze bovendien aanzienlijk lichter dan de libraries voor artikel-extractie in dezelfde categorie — die zitten op 21 tot 70 MiB. Een converter is een veel kleiner instrument dan een extractor, en het is verstandig die apart mee te nemen in je afhankelijkheidsbudget.

Twee verstorende factoren die ik eerst moest oplossen voordat deze tabel klopte

De cijfers hierboven zijn de derde versie. De eerste twee waren op manieren fout die het waard zijn om te benoemen, omdat beide makkelijk te reproduceren zijn.

Vijf voorbeelden tegen vier. markitdown draaide vier van deze vijf bestanden; de andere drie draaiden ze alle vijf. Door elk hulpmiddel op zijn eigen set te totaliseren, kreeg markdownify 98 tabelrijen tegenover 36 voor markitdown, waardoor het leek alsof er een capaciteitsverschil was. Over dezelfde vier is het 36 tegen 36 — exact gelijk. Het vijfde voorbeeld is juist het tabelzware, dus de verstorende factor werkte in de slechtst denkbare richting en blies de nieuwkomers bijna drie keer zo hoog op ten opzichte van de gevestigde speler.

System diagram: Make the Comparison Comparable

Twee tellers, één kolom. markitdown’s gepubliceerde md_table_rows kwam uit zijn eigen code, die ik niet had gelezen. Dat getal vergelijken met het mijne had kunnen betekenen dat ik twee tellers vergeleek in plaats van twee converters. De Markdown-output staat op schijf, dus de oplossing was om één teller over alle vier te laten lopen — en toen ik dat deed, kwam de hertelling voor markitdown exact overeen met de gepubliceerde waarde per voorbeeld (0, 0, 27, 9). De definities kwamen overeen; ik kon dat alleen niet weten zonder te controleren.

Geen van beide fouten zou zichtbaar zijn geweest in de output. Beide hadden een zelfverzekerde, verkeerde tabel opgeleverd.

Wie wat zou moeten gebruiken

Voer je een model, of sla je gestructureerde content op van pagina’s zoals deze? Begin met markdownify. Het komt onder deze teller uit op hetzelfde aantal uitgestuurde tabelrijen als markitdown, zit in de laagste tokencluster, is MIT-licensed en installeert in 1,8 MiB. Test het wel op je eigen paginatypes voordat je het standaardiseert.

Je afhankelijkheidsbudget wordt in kilobytes gemeten en je distribueert niet? html2text. Eén pakket, 0,2 MiB, tabellen intact. Check eerst de GPL-vraag, en noteer dat de laatste release uit april 2025 kwam.

Werk je al in een Node-stack? turndown, samen met turndown-plugin-gfm geïnstalleerd — en strip <script> en <style> uit de HTML voordat je het doorgeeft, want turndown doet dat niet. Die twee omissies kosten een kwart meer tokens én je tabelstructuur, en beide zie je pas als je de output bekijkt.

Converteer je al andere documentformaten? markitdown verwerkt PDF, Office en meer, en de HTML-uitvoer is prima vergelijkbaar met die van gespecialiseerde converters. Eén dependency in plaats van twee is ook wat waard.

Waar een beheerde API past

Al deze vier nemen HTML die je al hebt. Geen ervan haalt een pagina op, rendert JavaScript of handelt een anti-botlaag af — en voor veel echte doelpagina’s is juist dat het moeilijkere deel.

Onze eigen developer-stack bij Thunderbit dekt dat stuk. POST /distill neemt een URL en levert schone, LLM-klare Markdown terug, met rendering en ophalen al afgehandeld; POST /extract levert AI-gestuurde gestructureerde JSON die overeenkomt met een door jou aangeleverde JSON Schema, dus een ander uitvoerformaat opnieuw — rijen in plaats van een Markdown-tabel die je daarna nog moet parsen. Beide zijn bereikbaar via een MCP-server en een CLI (npx @thunderbit/thunderbit-cli). Prijzen staan op de Thunderbit-prijspagina.

De eerlijke vergelijking: als je de HTML al hebt en Markdown wilt, dan is markdownify gratis en doet het zijn werk goed, en deze tabel laat zien welke rivalen dat ook doen. Als je de pagina’s nog moet ophalen, of je wilt gestructureerde rijen in plaats van proza, dan koop je iets anders.

Voor het bredere veld behandelt onze web scraping API-roundup gehoste opties en de open-source scraper-pijler de zelfgehoste varianten. HTML naar Markdown converteren in Python is de praktische walkthrough, en wat llms.txt probeert te standaardiseren laat zien waar deze hele categorie naartoe beweegt.

Probeer Thunderbit voor webdata-extractie

Oordeel

Voor deze workload met vier voorbeelden is markdownify de sterkste standaardkeuze: hetzelfde aantal uitgestuurde tabelrijen als markitdown onder de gedeelde teller, een tokenaantal binnen 1,3% van de andere efficiënte converters, MIT, en een installatie van 1,8 MiB.

Dat verschil tussen populariteit en gemeten gedrag is de kernbevinding. turndown is een uitstekende bibliotheek die heel veel mensen hebben geïnstalleerd zonder de plugin die tabellen mogelijk maakt, en de prijs daarvan zie je terug als een kwart meer tokens en een tabelstructuur die niet meer bestaat. Geen van beide cijfers verschijnt ergens totdat je ze telt.

Als je één ding onthoudt: controleer wat je converter met een tabel doet voordat je de output aan een model toevertrouwt. Drie van deze vier doen iets zinnigs. De populairste niet, tenzij je daar expliciet om hebt gevraagd.

Probeer Thunderbit voor webdata-extractie Get Started Free

Veelgestelde vragen

Ondersteunt turndown echt geen tabellen? De core niet. Tabellen komen uit turndown-plugin-gfm, een apart pakket, en een gewone npm install turndown bevat dat niet. Zonder die plugin blijft elke cel als losse alinea over — de waarden zijn er wel, maar de rij- en kolomrelaties niet. Over vier voorbeelden leverde dat nul Markdown-tabelrijen op en 24,6% meer tokens dan markdownify voor dezelfde content.

Waarom leek html2text eerst geen tabellen te hebben? Omdat mijn teller leidende en afsluitende pipes eiste en html2text die niet uitspuugt. Team Name | Year | Wins is geldige Markdown en rendert correct; het is alleen een andere stijl dan | Team Name | Year |. De gecorrigeerde teller zoekt naar een reeks regels met pipes en een scheidingsregel, zoals een parser dat doet, en html2text gaat dan van 1 rij naar 32. Als je Markdown met je eigen regex nabewerkt, is dit precies het verschil waar je op stukloopt.

Is de GPL op html2text echt een probleem? Dat hangt af van hoe je de software combineert en distribueert. GPL-3.0-or-later kan verplichtingen meebrengen die MIT niet heeft, dus betrek degene die verantwoordelijk is voor licenties voordat je dit kiest voor een gedistribueerd product. Dit is een compliance-checkpoint, geen juridisch advies; de licentie is bevestigd via registry-metadata, de repository en het METADATA-bestand van het geïnstalleerde pakket.

Zijn deze tokenaantallen betekenisvol voor andere pagina’s? De kloof van 24,6% komt vooral doordat turndown <script>- en <style>-inhoud laat staan, dus de impact schaalt mee met hoeveel daarvan een pagina bevat — groot op een moderne CMS-pagina, bijna nul op een statische pagina. Tabellen werken juist de andere kant op: op het voorbeeld dat alleen uit tabellen bestaat, was turndown 22% goedkoper, omdat het geen pipe-structuur uitstuurt. Bytes per token lagen voor alle vier tussen 3,61 en 3,65, dus de dichtheid is overal vergelijkbaar en het verschil zit in de hoeveelheid. Meet je eigen corpus als dat getal belangrijk is voor je budget.

Wat is hier niet getest? Echte variatie — vier voorbeelden zijn vier voorbeelden. Geneste lijsten, definitielijsten, voetnoten en wiskunde. Slecht gevormde HTML, waar converters historisch gezien het sterkst uiteenlopen. Het terugzetten van de Markdown naar HTML. docling, dat wel dezelfde voorbeelden op schijf heeft maar in de gepubliceerde run deze velden niet rapporteert, en daarom ontbreekt in plaats van geschat te worden. En configuratie: html2text is uitgevoerd met body_width=0, omdat de standaardwaarde 78 elke regel hard zou wrappen, wat elk karakter- en tokenaantal in deze tabel had veranderd.

Ke
Ke
CTO bij Thunderbit | Senior Data Scientist & ML-expert Met bijna tien jaar ervaring in machine learning en data science is Ke Shen alumnus van Columbia University en voormalig Senior Data Scientist bij Walmart Labs. Met diepgaande, door vakgenoten erkende expertise in Python, R, Java en statistiek deelt hij praktijkgerichte inzichten over hoe je complexe AI-algoritmen van theorie naar productieklare architectuur brengt.
Inhoudsopgave
Thunderbit · AI-webdata-agent

Gegevens extraheren van elke pagina in 1 klik

Vertrouwd door meer dan 250.000 gebruikers
gratis abonnement beschikbaar
Van webpagina naar spreadsheet
Beschrijf wat je nodig hebt — Thunderbit's AI Agent scrapt het en exporteert het naar Excel, Google Sheets, Airtable of Notion. Gratis om te starten.
Chrome Store Rating
PRODUCT HUNT#1 Product of the Week