Senza KYC — niente documento, niente selfie, niente documenti. Paga in criptovalute: BTC, USDT, USDC, ETH, SOL, LTC
Lingua: Italiano
Ottieni una chiave API

Docs · Node.js

Da pagina web a Markdown in Node.js

Node.js 18 e successivi includono fetch, quindi non ti serve alcuna dipendenza. Tre ricette: leggi una pagina, leggi una lista con un piccolo pool di concorrenza e segui un crawl job fino alla fine.

Ultimo aggiornamento: · 4 min di lettura

Risposta rapida

Come converto una pagina web in Markdown in Node.js?

Usa fetch integrato di Node.js 18+: chiama https://webreaderapi.com/api/v1/read?url=… con la tua chiave nell'header Authorization e leggi markdown dalla risposta JSON. WebReaderAPI restituisce il contenuto principale della pagina con titolo, autore e data. Una pagina costa 1 credito, 2 con un browser, da 0,07 USD/1K pagine a ottobre 2026. Senza KYC; paghi in criptovalute.

Di cosa ho bisogno?

Node.js 18 o successivo, per il fetch globale, e una chiave API nella variabile d'ambiente WEBREADER_API_KEY. Gli esempi sono moduli ES: salvali con l'estensione .mjs, oppure imposta "type": "module" nel tuo package.json, così che await di primo livello funzioni.

I commenti JSDoc descrivono la forma della risposta, così editor come VS Code ti danno il completamento senza bisogno di una build TypeScript.

read.mjs: una pagina
/**
 * @typedef {Object} Page
 * @property {string} url
 * @property {string} final_url
 * @property {number} status_code
 * @property {boolean} rendered
 * @property {number} credits_used
 * @property {string} [title]
 * @property {string} [author]
 * @property {string} [published_at]
 * @property {string} [language]
 * @property {string} [markdown]
 * @property {number} word_count
 */

/** @returns {Promise<Page>} */
export async function readPage(url, options = {}) {
  const params = new URLSearchParams({ url, ...options });
  const res = await fetch(`https://webreaderapi.com/api/v1/read?${params}`, {
    headers: { Authorization: `Bearer ${process.env.WEBREADER_API_KEY}` },
    signal: AbortSignal.timeout(75_000),
  });
  const body = await res.json();
  if (!res.ok) throw Object.assign(new Error(body.error.message), { code: body.error.code });
  return body;
}

const page = await readPage('https://example.com/docs/getting-started', { max_chars: '20000' });
console.log(page.title, page.word_count, 'words,', page.credits_used, 'credit(s)');

Come leggo una lista di URL senza superare il limite?

Esegui un numero fisso di worker che prendono gli URL da una coda condivisa. È più semplice di Promise.all sull'intera lista, che avvierebbe tutte le richieste insieme e farebbe scattare 429 concurrency_limit. Ogni account ha un limite di pagine lette contemporaneamente; la tua dashboard lo mostra e il supporto può aumentarlo.

Il pool qui sotto tiene gli errori accanto ai risultati, così una pagina rifiutata non blocca l'esecuzione. Rifiuti come blocked_by_robots sono definitivi e gratuiti; contali e vai avanti.

pool.mjs: una lista di URL, 8 alla volta
import { readPage } from './read.mjs';

export async function readAll(urls, workers = 8) {
  const queue = [...urls];
  const results = [];
  async function worker() {
    while (queue.length) {
      const url = queue.shift();
      try {
        const page = await readPage(url, { max_chars: '50000' });
        results.push({ url, page });
      } catch (err) {
        results.push({ url, error: err.code ?? err.name });
      }
    }
  }
  await Promise.all(Array.from({ length: workers }, worker));
  return results;
}

const urls = Array.from({ length: 30 }, (_, i) => `https://example.com/blog/post-${i + 1}`);
for (const r of await readAll(urls)) console.log(r.url, '->', r.error ?? r.page.title);

Come seguo un crawl job in Node.js?

Avvia il job con POST https://webreaderapi.com/api/v1/crawl, poi leggi https://webreaderapi.com/api/v1/jobs/{job_id} in un ciclo. Passa cursor ogni volta che next_cursor torna; quando non c'è cursor e lo status è done, il job è finito. Aspetta tra un polling vuoto e l'altro e raddoppia l'attesa fino a 30 secondi, perché un crawl che rispetta il Crawl-delay di un sito può essere lento.

La pagina batch e crawl spiega come il crawl sceglie le pagine e come limit limita ciò che legge.

crawl.mjs: avvia un crawl e raccogli ogni pagina
const headers = {
  Authorization: `Bearer ${process.env.WEBREADER_API_KEY}`,
  'Content-Type': 'application/json',
};
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));

const start = await fetch('https://webreaderapi.com/api/v1/crawl', {
  method: 'POST',
  headers,
  body: JSON.stringify({ url: 'https://docs.example.com/', limit: 300, include_paths: ['/docs/*'] }),
});
const { job_id } = await start.json();

const pages = [];
let cursor = '';
let wait = 2000;
for (;;) {
  const url = `https://webreaderapi.com/api/v1/jobs/${job_id}${cursor ? `?cursor=${encodeURIComponent(cursor)}` : ''}`;
  const job = await (await fetch(url, { headers })).json();
  pages.push(...job.results.filter((r) => !r.error));
  if (job.next_cursor) {
    cursor = job.next_cursor;
    wait = 2000;
    continue;
  }
  if (job.status === 'done') break;
  await sleep(wait);
  wait = Math.min(wait * 2, 30000);
}
console.log(pages.length, 'pages read, job', job_id);

Come passo il risultato a un modello?

Invia il Markdown, non l'intero JSON. Il campo markdown è ciò che dovrebbe leggere un modello; i metadati è meglio tenerli per le citazioni. Anteponi titolo e final_url, così il modello può indicare la sua fonte, e mantieni max_chars a una dimensione che il contesto del tuo modello possa contenere, ad esempio 20.000 caratteri per pagina.

La pagina OpenAI function calling mostra l'intero tool loop in Python; la stessa funzione readPage qui sopra può servire da corpo del tool in un agente Node.js.

Node.js: domande frequenti

Funziona in Deno, Bun o nel browser?

Deno e Bun supportano lo stesso fetch e i moduli ES. Non chiamare l'API da una pagina del browser: la chiave sarebbe visibile a ogni visitatore. Chiamala invece dal tuo server.

Esiste un pacchetto npm?

No. Le funzioni di questa pagina sono l'intera integrazione. WebReaderAPI è semplice HTTPS e JSON, così mantieni il controllo su retry, timeout e logging.

Come gestisco il 429 concurrency_limit?

Riduci il numero di worker, oppure riprova dopo una breve attesa che raddoppia ogni volta. Un 429 non costa nulla, e la pagina degli errori ha una funzione di backoff pronta.

Quanto costa leggere 10.000 pagine?

Circa 10.000 crediti per pagine semplici, di più se alcune richiedono un browser. 10.000 pagine costano 3,75 USD; I crediti prepagati non scadono mai: le pagine non utilizzate restano sul tuo account finché non le usi.

Da 0,07 USD/1K pagine · senza KYC

Ottieni una chiave API