Research
Web-to-Markdown, measured
Four ways to turn a web page into Markdown for a model, run on the same fetched pages and scored against what a browser actually shows.
By Roger Campos · Last updated: September 2026
TL;DR
On the same 33 real pages, a deterministic DOM walk kept 87.2% of the text a visitor sees, and 11.0% of its output was text the visitor never saw. Readability kept slightly more (88.2%) but leaked nearly twice as much (21.3%); Firecrawl's selector blocklist scored 85.8% and 17.0%; a language model scored 79.0% and 22.0%, at $0.0025 and 39 seconds a page.
Free plan, no credit card. 1,000 credits a month.
Summary
The results
Measured on 2026-09-14 over 33 pages. Higher coverage is better; lower leak is better.
| Strategy | Coverage of visible text | Text the reader never sees | Cost / page | Time / page |
|---|---|---|---|---|
| DOM walk (URLpipe's /markdown) | 87.2% | 11.0% | $0 | ~20 ms |
| Readability (the extractor Jina Reader runs) | 88.2% | 21.3% | — | — |
| Firecrawl's selector blocklist | 85.8% | 17.0% | — | — |
| Language-model conversion | 79.0% | 22.0% | $0.0025 | 39 s |
Coverage is how much of what the visitor sees survived into the Markdown. Leak is how much of the Markdown is text the visitor never saw. The DOM walk has the lowest leak of the four by a wide margin, at comparable coverage.
What these numbers are not
These are the strategies, reimplemented and run on the same fetched HTML — not the vendors' hosted APIs. Readability is the real @mozilla/readability 0.6.0 run in a real browser, with the fall-back-to-the-whole-document guard Jina Reader applies; Firecrawl's blocklist is its list of tag, class and id selectors taken from its source. A hosted API does more around its extractor, and may score differently.
Cost and time are only meaningful for the two strategies that ran as our own services. The model's 39 seconds is the benchmark's own average; the production 30-day average for that operation had been 171 seconds. The DOM walk needs only the page visit every endpoint makes, and no model.
Honestly
Where the DOM walk loses
Readability keeps a point more of the visible text: 88.2% against 87.2%. Its approach — score the page's containers by text density and keep the best one, and, as Jina Reader runs it, fall back to the whole document when the winner holds too little of it — errs towards keeping, and on this corpus that bought coverage at the price of nearly double the leak.
And the DOM walk reads no CSS. Text that a stylesheet hides — collapsed menus, off-screen drawers, the second language of a bilingual toggle — is in the HTML, and it reaches the Markdown, where it counts as leak. None of the other three strategies reads CSS either; only the browser knows what is hidden, so fixing it means pruning inside the page before it is serialized, which is a separate change.
How it was measured
Method
The corpus
33 pages. About half are well-known sites, each chosen because it breaks a different assumption: reference docs with definition lists, a guide with 38 code blocks, a front page built from nested layout tables, a news index rather than an article, a heavy client-rendered index, a page carrying 2 MB of inline SVG diagrams, a paywalled news homepage, docs with collapsed accordions, a product page built from sectioning <header>s. The other half are real URLs our customers asked for: e-commerce in Portuguese, an Arabic right-to-left listing, a Japanese ad-heavy homepage, a generated single-page app, a comment thread, a very long article with 98 code blocks, a single-page app that renders nothing.
The ground truth
Each page was loaded once in a real browser, and from that one visit we kept two things: the HTML, and document.body.innerText. innerText is the browser's own answer to "what does a visitor read", computed with the stylesheets applied, so it is the one yardstick that is not just another opinion about HTML. Every strategy was given the same HTML.
The two numbers
- Coverage — the share of innerText's words that appear in the Markdown, counted as a multiset: a word the page shows three times counts three times, so keeping one of them is not credited with all three.
- Leak — the share of the Markdown's words that innerText does not contain.
- Markdown syntax, link destinations and image URLs are stripped before counting; link text stays, because it is page text. Image alt text is excluded from both, since innerText never contains it and a converter is expected to carry it.
Neither number is a score on its own. Coverage below 100 is often correct: dropping a cookie banner and a footer full of navigation costs coverage and is the point. Leak is the sharper number, but it cannot tell two very different faults apart — text that was in the page but hidden by a stylesheet, which no HTML-only converter can avoid, and text that was never in the page at all, which is what a model invents. Read them together, per page, and look at the output when one moves.
One renderer for all four
Readability and the blocklist decide which part of the page to keep; their output was then written as Markdown by the same renderer the DOM walk uses. That is deliberate: a difference in Markdown style — how a table or a code fence is written — would otherwise swamp the difference that matters, which is what each strategy keeps. The model was the exception, since it did both steps itself.
Alongside the numbers, a blind judge compared the DOM walk's output with the model's for every page: it preferred the DOM walk on 24 of the 33 pages and the model on 3.
Negative results
Two heuristics we measured and deleted
Density scoring, Readability's core idea, was implemented and measured on top of the DOM walk. It cost the nytimes.com front page 48 points of coverage and a forum comment thread 36, because on an index page the highest-scoring container is one story out of forty. It was removed.
A class-and-id blocklist like Firecrawl's cost 3.3 points of coverage across the corpus and destroyed one page outright: a site whose content containers carried class names the list treats as chrome. It was removed too. Both are recorded in the code where someone would otherwise add them again.
Side findings
Two findings worth knowing on their own
A page built from <header> elements loses 99.9% of its text
A common shortcut removes every <header> and <footer> as page chrome. In HTML5 those tags also mean "the heading block of this section", and some pages are built almost entirely from <section><header>…</header></section>. On an apple.com product page, removing every <header> took 69,306 characters of page text down to 88. The converter then turned the 88 faithfully into Markdown, and the result looked like an answer rather than a failure. The rule that works: only a page-level header or footer — one with no sectioning element above it — is chrome, and if removing chrome takes away more than four fifths of a page's text, the removal is undone.
A model can "succeed" by returning its input
On a long technical article with 98 code blocks, the model spent 143 seconds and returned the input HTML unchanged: no headings, no code fences, no Markdown at all. The response was well-formed and on time, so the request was recorded as a success. Checking a model's output for the shape you asked for — here, any Markdown structure — is not optional.
Read before citing
Limits of this study
- 33 pages is a small corpus, and half of it is URLs our own customers requested, which is not a random sample of the web.
- The strategies were reimplemented on one fetched DOM; the vendors' hosted APIs were not called.
- The model figures are one model, one prompt, at one point in time; a different model would score differently.
- Live pages change. A re-run today fetches different HTML, so expect numbers near these rather than equal to them.
- Trafilatura, Microlink and the vendors' live APIs are not in this round.
Research
More research
What stops a headless browser in 2026
46 well-known, frequently protected sites, visited from a datacentre and a residential address: which refuse outright, which answer 200 with a block page, and what a residential exit changes.
Lighthouse variance: how much does one audit move?
Ten mobile Lighthouse audits of each of five public pages, back to back: the performance score moved by up to 61 points on the same page.
FAQ
Frequently asked questions
Which HTML-to-Markdown approach leaks the least hidden text?
Is Readability better than a DOM walk for Markdown?
Should I use an LLM to convert HTML to Markdown?
Did you test the vendors' APIs?
What is leak, exactly?
Try the converter on your own pages.
Free plan, no card. Confirm your email and your API key is live — you'll be making real requests in minutes.