cdpfleet Docs GitHub Dashboard

Cases / #32 · 2026-10-10 · Easy

A page for an LLM: HTML, innerText or the accessibility snapshot?

Three ways to hand a rendered page to a model — raw HTML, innerText and Playwright's ARIA snapshot — measured on three real pages: how big each is and what it keeps.

Chromium

Run on production on 2026-10-10: ✓ Node.js ✓ Python ✓ Java ✓ C# ✓ Go

The problem

Agents and extraction prompts need the page as text. Raw HTML is the obvious choice and the most expensive one; innerText is small but throws away links and structure. Playwright can also give you the page as the accessibility tree sees it — roles, names and links in YAML. How big is each on real pages, and what does the model get?

What we used, and why

WhatWhy
page.content()The serialized DOM — everything, markup included.
locator("body").innerText()What a person reads: text only, no links or structure.
locator("body").ariaSnapshot()The accessibility tree as YAML: headings, lists, buttons, links with their URLs — the structure a screen reader uses.
Three page shapesHacker News (a table layout), a Wikipedia article (long prose) and a shop catalogue.

How it works

  1. Launch Chromium and open each page (waiting for the HTML).
  2. Take the HTML, the inner text and the ARIA snapshot of the body.
  3. Compare their sizes, count the links the snapshot keeps, and print the first lines of each snapshot.

The code

The same program in five languages (also on GitHub, with the raw output). Set these environment variables first:

// npm install [email protected]
// env: CDPFLEET_API_KEY, PROXY_URL
import { chromium } from 'playwright';

const KEY = process.env.CDPFLEET_API_KEY;
const URLS = ['https://news.ycombinator.com/', 'https://en.wikipedia.org/wiki/Web_scraping', 'https://books.toscrape.com/'];

const res = await fetch('https://starter.cdpfleet.com/chromium/session', {
  method: 'POST',
  headers: { 'x-api-key': KEY, 'content-type': 'application/json' },
  body: JSON.stringify({ proxy: process.env.PROXY_URL, headless: 'new' }),
});
if (!res.ok) throw new Error(`launch ${res.status} ${await res.text()}`);
const { wsUrl } = await res.json();
const browser = await chromium.connect(wsUrl, { headers: { 'x-api-key': KEY } });

try {
  const page = await browser.newPage();
  const pages = [];
  for (const url of URLS) {
    await page.goto(url, { waitUntil: 'domcontentloaded', timeout: 60000 });
    const html = await page.content();
    const text = await page.locator('body').innerText();
    const aria = await page.locator('body').ariaSnapshot();
    pages.push({
      url,
      html_chars: html.length,
      text_chars: text.length,
      aria_chars: aria.length,
      aria_links: (aria.match(/- link /g) || []).length,
      aria_vs_html: Math.round((aria.length / html.length) * 1000) / 10,
      aria_sample: aria.split('\n').slice(0, 6).join('\n'),
    });
  }
  console.log(JSON.stringify({ pages }, null, 2));
} finally {
  await browser.close();
}

What we got

PageHTML charsinnerText charsARIA snapshot charsSnapshot / HTML %Links in snapshot
https://news.ycombinator.com/34742409640476116.5224
https://en.wikipedia.org/wiki/Web_scraping256505285897132027.8383
https://books.toscrape.com/5100420291666232.784

From the Node.js run on 2026-10-10. IP addresses are replaced with placeholders (203.0.113.x); equal addresses stay equal. The other languages produced the same findings.

Raw output (Node.js)
{
  "pages": [
    {
      "url": "https://news.ycombinator.com/",
      "html_chars": 34742,
      "text_chars": 4096,
      "aria_chars": 40476,
      "aria_links": 224,
      "aria_vs_html": 116.5,
      "aria_sample": "- table:\n  - rowgroup:\n    - row \"Hacker Newsnew | past | comments | ask | show | jobs | submit login\":\n      - cell \"Hacker Newsnew | past | comments | ask | show | jobs | submit login\":\n        - table:\n          - rowgroup:"
    },
    {
      "url": "https://en.wikipedia.org/wiki/Web_scraping",
      "html_chars": 256505,
      "text_chars": 28589,
      "aria_chars": 71320,
      "aria_links": 383,
      "aria_vs_html": 27.8,
      "aria_sample": "- link \"Jump to content\":\n  - /url: \"#bodyContent\"\n- banner:\n  - navigation \"Site\":\n    - button \"Main menu\"\n  - link \"Wikipedia The Free Encyclopedia\":"
    },
    {
      "url": "https://books.toscrape.com/",
      "html_chars": 51004,
      "text_chars": 2029,
      "aria_chars": 16662,
      "aria_links": 84,
      "aria_vs_html": 32.7,
      "aria_sample": "- banner:\n  - link \"Books to Scrape\":\n    - /url: index.html\n  - text: We love being scraped!\n- list:\n  - listitem:"
    }
  ]
}

Takeaways