# Webseite in Markdown umwandeln in Node.js

> Wandeln Sie Webseiten in Node.js in Markdown um, mit nativem fetch, Concurrency-Pool und Crawl-Polling. Ab 0,07 $/1K Seiten, ohne KYC, mit Krypto zahlen.

- URL: https://webreaderapi.com/de/docs/node/
- Zuletzt aktualisiert: 2026-10-22
- Herausgeber: WebReaderAPI (https://webreaderapi.com)

Node.js 18 und später liefern `fetch` mit, Sie brauchen also gar keine Abhängigkeit. Drei Rezepte: eine Seite lesen, eine Liste mit einem kleinen Concurrency-Pool lesen und einen Crawl-Job verfolgen, bis er fertig ist.

**Kurze Antwort — Wie wandle ich eine Webseite in Markdown um in Node.js?**

Nutzen Sie das eingebaute `fetch` von Node.js 18+: Rufen Sie `https://webreaderapi.com/api/v1/read?url=…` mit Ihrem Schlüssel im `Authorization`-Header auf und lesen Sie `markdown` aus der JSON-Antwort. **WebReaderAPI** liefert den Hauptinhalt der Seite mit Titel, Autor und Datum. Eine Seite kostet 1 Credit, 2 mit Browser, ab 0,07 $/1K Seiten Stand Oktober 2026. Ohne KYC; mit Krypto bezahlen.

## Was brauche ich?

Node.js 18 oder später, für das globale `fetch`, und einen API-Schlüssel in der Umgebungsvariable `WEBREADER_API_KEY`. Die Beispiele sind ES-Module: Speichern Sie sie mit der Endung `.mjs` oder setzen Sie `"type": "module"` in Ihrer `package.json`, damit Top-Level-`await` funktioniert.

Die JSDoc-Kommentare beschreiben die Form der Antwort, sodass Editoren wie VS Code Ihnen Autovervollständigung ohne TypeScript-Build-Schritt geben.

*read.mjs: eine Seite*

```javascript
/**
 * @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)');

```

## Wie lese ich eine Liste von URLs, ohne das Limit zu erreichen?

Führen Sie eine feste Anzahl von Workern aus, die URLs aus einer gemeinsamen Warteschlange nehmen. Das ist einfacher als `Promise.all` über die ganze Liste, das alle Anfragen auf einmal starten und das `429 concurrency_limit` erreichen würde. Jedes Konto hat ein Limit dafür, wie viele Seiten es gleichzeitig liest; Ihr Dashboard zeigt es an, und der Support kann es erhöhen.

Der Pool unten legt Fehler neben die Ergebnisse, sodass eine abgelehnte Seite den Lauf nicht stoppt. Ablehnungen wie `blocked_by_robots` sind endgültig und kostenlos; zählen Sie sie und machen Sie weiter.

*pool.mjs: eine Liste von URLs, 8 auf einmal*

```javascript
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);

```

## Wie verfolge ich einen Crawl-Job in Node.js?

Starten Sie den Job mit `POST https://webreaderapi.com/api/v1/crawl` und lesen Sie dann `https://webreaderapi.com/api/v1/jobs/{job_id}` in einer Schleife. Übergeben Sie `cursor` jedes Mal, wenn `next_cursor` zurückkommt; wenn kein Cursor mehr vorhanden ist und der Status `done` lautet, ist der Job fertig. Warten Sie zwischen leeren Abfragen und verdoppeln Sie die Wartezeit bis zu 30 Sekunden, da ein Crawl, der die Crawl-delay einer Website respektiert, langsam sein kann.

Die [Batch- und Crawl-Seite](https://webreaderapi.com/de/docs/crawl/) beschreibt, wie der Crawl seine Seiten wählt und wie `limit` begrenzt, was er liest.

*crawl.mjs: einen Crawl starten und jede Seite sammeln*

```javascript
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);

```

## Wie übergebe ich das Ergebnis an ein Modell?

Senden Sie das Markdown, nicht das ganze JSON. Das Feld `markdown` ist das, was ein Modell lesen sollte; die Metadaten bewahren Sie besser für Quellenangaben auf. Stellen Sie Titel und `final_url` voran, damit das Modell seine Quelle nennen kann, und halten Sie `max_chars` in einer Größe, die der Kontext Ihres Modells aufnehmen kann, etwa 20.000 Zeichen pro Seite.

Die [OpenAI-Function-Calling-Seite](https://webreaderapi.com/de/docs/openai/) zeigt die vollständige Tool-Schleife in Python; dieselbe `readPage`-Funktion oben kann als Tool-Body in einem Node.js-Agenten dienen.

## Node.js: häufige Fragen

### Funktioniert das in Deno, Bun oder im Browser?

Deno und Bun unterstützen dasselbe `fetch` und ES-Module. Rufen Sie die API nicht aus einer Browser-Seite auf: Der Schlüssel wäre für jeden Besucher sichtbar. Rufen Sie sie stattdessen von Ihrem Server aus auf.

### Gibt es ein npm-Paket?

Nein. Die Funktionen auf dieser Seite sind die gesamte Integration. WebReaderAPI ist reines HTTPS und JSON, sodass Sie die Kontrolle über Wiederholungen, Timeouts und Logging behalten.

### Wie gehe ich mit 429 concurrency_limit um?

Verringern Sie die Anzahl der Worker oder wiederholen Sie nach einer kurzen Wartezeit, die sich jedes Mal verdoppelt. Ein 429 kostet nichts, und die [Fehlerseite](https://webreaderapi.com/de/docs/errors/) enthält eine fertige Backoff-Funktion.

### Was kostet das Lesen von 10.000 Seiten?

Etwa 10.000 Credits für einfache Seiten, mehr, wenn einige einen Browser benötigen. 10.000 Seiten kosten 3,75 $; Prepaid-Credits verfallen nie: Ungenutzte Seiten bleiben auf Ihrem Konto, bis Sie sie verwenden.

---

WebReaderAPI: WebReaderAPI ist eine Web-Reader-API für KI-Agenten, die jede öffentliche Webseite in sauberes Markdown umwandelt und die Sie mit Krypto bezahlen – ohne ID-Upload. Prepaid-Credits ab 0,07 $/1K Seiten verfallen nie, und robots.txt wird respektiert. Ohne KYC – keine ID, kein Selfie, keine Dokumente. Mit Krypto bezahlen.
