keepcalculator

06 Numbers and Powers

Webpage to Clean Markdown for LLMs: Fast Reliable Pipeline

Card No. 06·9756 · Updated · Standard formula, shown below

Yes, you can reliably convert any webpage to clean markdown for LLMs using a pipeline that combines a readability extractor (like Mozilla’s Readability) with a HTML-to-markdown converter (like Turndown), orchestrated by a headless browser or a simple HTTP request. This approach strips away navigation, ads, and scripts, leaving the main content in a structured format that large language models can ingest without token waste.

Why Clean Markdown Matters for LLMs

Large language models process text in tokens, and every piece of boilerplate—menus, cookie banners, related-article links—consumes tokens and adds noise. A 5,000-word article might have 2,000 words of cruft; feeding that to an LLM increases cost and can confuse the model with irrelevant context. Clean markdown preserves headings, lists, links, and code blocks, which help the model understand structure and semantics. For example, a table in HTML becomes a markdown table, and the model can reason about the data more easily than if it were in raw HTML with attributes and inline styles.

Core Components of a Pipeline

Any robust pipeline has three stages: fetching, extracting, and converting.

  • Fetching: Retrieve the HTML. Use a simple HTTP client (e.g., Python’s requests) for static pages, or a headless browser (Puppeteer, Playwright) for JavaScript-rendered content. The browser waits for network idle and executes scripts, so you get the fully rendered DOM.
  • Extracting main content: Use a readability algorithm to identify the main article body. Mozilla’s Readability (available in JavaScript and via Python’s readability-lxml) scores elements based on text density, link density, and class names. It returns the cleaned HTML fragment.
  • Converting to markdown: Feed the cleaned HTML into a converter like Turndown (JavaScript) or markdownify (Python). These map HTML tags to markdown syntax: <h2> to ##, <strong> to **, and so on.

Optionally, you can post-process the markdown to remove empty lines, normalize whitespace, or strip tracking parameters from links.

Choosing the Right Tools

The best tool depends on your language and environment.

  • Python: Use requests + readability-lxml + markdownify. This stack is lightweight and works for most static pages. For dynamic pages, add playwright to render before extraction.
  • Node.js: Use axios + @mozilla/readability + turndown. The Readability library is the same one used in Firefox’s Reader Mode, so it’s battle-tested.
  • CLI tools: Tools like pandoc can convert HTML to markdown, but they don’t extract the main content—you’d need to pre-process with something like readability first.

For a quick one-off, you can even use an online service like r.jina.ai, but for a reliable pipeline you want local control.

Handling JavaScript-Rendered Pages

Many modern sites (e.g., React, Vue) render content client-side. A simple HTTP request returns an empty shell. A headless browser solves this: launch a browser, navigate to the URL, wait for the network to be idle or for a selector to appear, then grab the page’s HTML. In Playwright, you can use page.goto(url, { waitUntil: 'networkidle' }). Be careful: waiting too long wastes time, waiting too short might miss content. A common approach is to wait for a specific element that indicates the article has loaded, like an <article> tag or a known class.

Common Pitfalls and How to Avoid Them

  • Paywalls and login walls: Some sites block bots or require authentication. You cannot bypass these ethically; the pipeline will only get the teaser. Check the site’s terms of service.
  • Images and media: Markdown can embed images, but you may want to skip them to save tokens. Turndown has an ignore option for tags. Alternatively, keep images but note that the LLM won’t “seeâ€� them unless it’s multimodal.
  • Tables and code blocks: Some converters mangle complex tables. Test with a sample. For code blocks, ensure the converter preserves indentation and language hints.
  • Relative URLs: Links to other pages are often relative. Convert them to absolute using the page’s base URL, otherwise the markdown has broken links.
  • Encoding issues: Always set the correct character encoding (usually UTF-8) when fetching and reading the HTML.

Performance and Caching

For batch processing, speed matters. Fetching and rendering each page takes time. Use caching: store the fetched HTML and the resulting markdown so you don’t re-fetch unchanged pages. If you’re processing many URLs from the same domain, reuse a single browser session. Also, consider rate limiting to be polite to the server.

Frequently Asked Questions

How do I handle pages that require JavaScript?

Use a headless browser like Playwright or Puppeteer. After loading, wait for a selector that indicates the content is present (e.g., article or a specific class). Then extract the innerHTML and pass it to Readability.

Can I use this pipeline offline?

Yes, all the tools run locally. You only need internet to fetch the pages. Once fetched, you can process them without a connection.

What if the page is a PDF or a video?

This pipeline is for HTML pages. For PDFs, you’d need a separate extractor like pdfplumber or PyPDF2. For videos, you can extract the transcript if available, but that’s out of scope.

How do I ensure the markdown is truly clean?

After conversion, run a cleanup script that removes empty lines, merges multiple blank lines, and strips any residual HTML tags. Also, check for unwanted elements like embedded tweets or iframes—you may want to remove them.

Is it legal to scrape webpages for LLM training?

It depends on the site’s terms of service and your jurisdiction. Always check the robots.txt and the site’s terms. For personal or research use, it’s often acceptable, but commercial use may require permission.

What’s the fastest way to do this for a single URL?

Use a one-liner with pandoc and readability if you have them installed. For example, in Python: requests.get(url) then readability.Document(html).summary() then markdownify. That’s about 10 lines of code.

Related

Method: the standard formula for this calculation, rounded as each result states. See how the calculators work or report an error.

More cards in this drawer

The whole Numbers and Powers drawer →