Tutorial
Shotomatic Team
12 Min. Lesezeit

Website-Screenshots mit Playwright automatisieren

Automatisiere Website-Screenshots mit Playwright und JavaScript. Nimm einzelne Seiten, Ganzseiten, mobile Ansichten und URL-Stapel mit Wiederholungen auf.

Laptop mit Code für ein automatisches Website-Screenshot-Skript

In dieser Anleitung bauen wir schrittweise ein Screenshot-Skript mit Playwright: zuerst eine einzelne Ansichtsgröße, danach eine Ganzseiten-Aufnahme, einen wiederverwendbaren URL-Runner und eine mobile Ansicht.

Playwright passt, wenn die Screenshots neben dem steuernden Code liegen sollen. Du erhältst echtes Browser-Rendering, isolierte Browserkontexte, genaue Kontrolle der Ansichtsgröße, Geräteemulation und Möglichkeiten zum Warten auf den benötigten Seitenzustand.

Die Beispiele verwenden die Shotomatic-Funktionsseite https://www.shotomatic.com/features. So lässt sich dieselbe Seite als Ansichtsgröße, Ganzseite, stapelfähige Aufnahme und mobile Ansicht vergleichen.

Kurz gesagt: Nutze Playwright, wenn Screenshot-Automatisierung in Code gehört. Erstelle einen Browserkontext, lege Ansichtsgröße oder Gerät fest, warte auf den wichtigen Seitenzustand, rufe page.screenshot() auf und ergänze danach Ganzseiten-Aufnahmen, Stapel, Wiederholungen und Berichte. Wenn du dieses Skript nicht schreiben und pflegen möchtest, ist Website Capture von Shotomatic möglicherweise einfacher.

Hinweis: Wir entwickeln Shotomatic. Deshalb verwenden die Beispiele unsere öffentliche Funktionsseite als Ziel. Playwright kann andere öffentliche Websites aufnehmen, sofern du sie aufnehmen darfst. Für URL-Listen ohne Code steht Website Capture in Shotomatic zur Verfügung.

Wann Playwright das richtige Werkzeug ist

Nutze Playwright, wenn die Aufnahme Browserlogik folgen muss.

Playwright passt, wenn du:

  • Screenshots in CI aufnehmen möchtest
  • dich vor der Aufnahme anmelden musst
  • auf einen bestimmten Selektor oder App-Zustand warten möchtest
  • denselben Screenshot-Job in Chromium, Firefox oder WebKit ausführen möchtest
  • responsive Screenshots mit genau festgelegten Ansichtsgrößen brauchst
  • Screenshots innerhalb eines internen Werkzeugs erzeugen möchtest

Weniger bequem wird es, wenn die Person mit Screenshot-Bedarf das Skript nicht pflegt. Soll der Job in Code leben, ist Playwright ein guter Ausgangspunkt.

Playwright für ein Screenshot-Skript installieren

Installiere für ein gewöhnliches Node.js-Skript die Playwright-Bibliothek und den gewünschten Browser:

$ mkdir website-screenshots-playwright
$ cd website-screenshots-playwright
$ npm init -y
$ npm i -D playwright
$ npx playwright install chromium

Die Bibliotheksdokumentation von Playwright verwendet denselben Grundaufbau: Paket und Browser installieren, Playwright importieren, Browser starten und mit Seiten arbeiten. Wenn du später Firefox oder WebKit brauchst, installiere auch diese Browser.

Erstelle Ordner für Skripte und Ausgaben:

$ mkdir scripts screenshots

Einen Website-Screenshot aufnehmen

Erstelle scripts/capture-one.js:

const { chromium } = require("playwright");
const fs = require("node:fs/promises");

const url = "https://www.shotomatic.com/features";
const outputPath = "screenshots/shotomatic-features.png";

(async () => {
  await fs.mkdir("screenshots", { recursive: true });

  const browser = await chromium.launch();
  const context = await browser.newContext({
    viewport: { width: 1440, height: 1000 },
    deviceScaleFactor: 1,
  });

  const page = await context.newPage();

  try {
    await page.goto(url, { waitUntil: "load", timeout: 45_000 });
    await page.screenshot({ path: outputPath });
    console.log(`Saved ${outputPath}`);
  } finally {
    await context.close();
    await browser.close();
  }
})();

Führe das Skript aus:

$ node scripts/capture-one.js

Damit wird die sichtbare Ansichtsgröße aufgenommen. Die Screenshot-API von Playwright unterstützt außerdem Ganzseiten- und Element-Screenshots, Buffer, Ausschnitte und Optionen für die Bildqualität.

Das Skript erzeugt screenshots/shotomatic-features.png:

Screenshot-Ausgabe des Playwright-Beispiels capture-one mit der Shotomatic-Funktionsseite
Ausgabe der Funktionsseite aus dem obigen Skript, aufgenommen mit einer Ansichtsgröße von 1440 × 1000.

Einen Ganzseiten-Screenshot aufnehmen

Übergib für einen Ganzseiten-Screenshot fullPage: true:

await page.screenshot({
  path: "screenshots/shotomatic-features-full-page.png",
  fullPage: true,
});

Nutze die Ganzseiten-Aufnahme für das gesamte Dokument von oben bis unten. Ein Ansichtsgrößen-Screenshot passt, wenn dich genau der sichtbare Bereich bei einer bestimmten Bildschirmgröße interessiert.

Playwright-Ganzseiten-Screenshot der Shotomatic-Funktionsseite
Ganzseiten-Ausgabe derselben `/features`-Seite, nachdem die Abschnitte unterhalb des ersten sichtbaren Bereichs gerendert wurden.

Auch eine Ganzseiten-Aufnahme hängt vom Seitenzustand ab. fullPage: true verändert den Aufnahmebereich, zwingt Lazy-Loading-Bilder, Animationen oder erst im sichtbaren Bereich erscheinende Abschnitte aber nicht zum Rendern. Der Abschnitt zu Lazy Loading erklärt, warum der Seitenzustand wichtig bleibt.

Die Ziel-URL in ein Stapelskript verschieben

Wenn das Skript für eine Seite funktioniert, verschiebe die Ziel-URL in einen Runner, der eine Liste annehmen und Dateien mit vorhersehbaren Namen speichern kann. Das Beispiel verwendet weiterhin nur /features, damit die Ausgabe leicht nachvollziehbar bleibt. Später kannst du weitere URLs in dasselbe Array aufnehmen.

Erstelle scripts/capture-batch.js:

const { chromium } = require("playwright");
const fs = require("node:fs/promises");

const urls = ["https://www.shotomatic.com/features"];

const outputDir = "screenshots";

function filenameForUrl(url, index) {
  const parsed = new URL(url);
  const rawName = `${parsed.hostname}${parsed.pathname}`;

  const slug = rawName
    .replace(/^www\./, "")
    .replace(/\/$/, "")
    .replace(/[^a-z0-9]+/gi, "-")
    .replace(/^-+|-+$/g, "")
    .toLowerCase();

  return `${String(index + 1).padStart(2, "0")}-${slug || "home"}.png`;
}

async function captureUrl(browser, url, index) {
  const context = await browser.newContext({
    viewport: { width: 1440, height: 1000 },
    deviceScaleFactor: 1,
  });

  const page = await context.newPage();
  const outputPath = `${outputDir}/${filenameForUrl(url, index)}`;

  try {
    await page.goto(url, { waitUntil: "load", timeout: 45_000 });
    await page.locator("body").waitFor({ state: "visible", timeout: 15_000 });
    await page.screenshot({ path: outputPath, fullPage: true });

    console.log(`Captured ${url} -> ${outputPath}`);
    return { url, ok: true, outputPath };
  } catch (error) {
    console.error(`Failed ${url}: ${error.message}`);
    return { url, ok: false, error: error.message };
  } finally {
    await context.close();
  }
}

(async () => {
  await fs.mkdir(outputDir, { recursive: true });

  const browser = await chromium.launch();

  try {
    const results = [];

    for (const [index, url] of urls.entries()) {
      results.push(await captureUrl(browser, url, index));
    }

    const failed = results.filter((result) => !result.ok);

    if (failed.length > 0) {
      process.exitCode = 1;
      console.error(`${failed.length} screenshot(s) failed.`);
    }
  } finally {
    await browser.close();
  }
})();

Diese Fassung läuft bewusst nacheinander. Sie ist langsamer, lässt sich aber deutlich einfacher untersuchen. Sobald sie für deine Seiten zuverlässig funktioniert, kannst du Parallelität ergänzen.

Bei größeren Stapeln Parallelität ergänzen

Für fünf URLs reicht eine einfache Schleife. Bei 50 oder 500 brauchst du wahrscheinlich eine kleine Begrenzung der Parallelität.

Öffne nicht Hunderte Seiten gleichzeitig. Browserautomatisierung braucht viel Arbeitsspeicher, und viele Websites drosseln oder schlagen fehl, wenn sie zu schnell angefragt werden. Beginne mit zwei bis vier parallelen Aufnahmen und erhöhe den Wert nur bei stabilen Ergebnissen.

Ergänze denselben Helfer wie in der Puppeteer-Fassung dieser Anleitung:

async function runWithConcurrency(items, limit, worker) {
  const results = new Array(items.length);
  let nextIndex = 0;

  async function runNext() {
    while (nextIndex < items.length) {
      const currentIndex = nextIndex;
      nextIndex += 1;
      results[currentIndex] = await worker(items[currentIndex], currentIndex);
    }
  }

  const workers = Array.from(
    { length: Math.min(limit, items.length) },
    () => runNext(),
  );

  await Promise.all(workers);
  return results;
}

Ersetze danach die serielle Schleife:

const results = await runWithConcurrency(urls, 3, (url, index) =>
  captureUrl(browser, url, index),
);

Damit bleibt ein Browser geöffnet, jede Aufnahme erhält einen isolierten Browserkontext und nur eine begrenzte Zahl von Seiten ist gleichzeitig aktiv. Die Playwright-Bibliotheksdokumentation verwendet im Ablauf für Node-Skripte ausdrücklich Browserkontexte, sodass jede Aufnahme ihren eigenen Lebenszyklus hat.

Screenshots für Smartphones oder Tablets aufnehmen

Playwright enthält Geräteemulation mit Beschreibungen gängiger Smartphones und Tablets. Zum Beispiel:

const { chromium, devices } = require("playwright");

(async () => {
  const browser = await chromium.launch();
  const iPhone = devices["iPhone 13"];

  const context = await browser.newContext({
    ...iPhone,
  });

  const page = await context.newPage();
  await page.goto("https://www.shotomatic.com/features", {
    waitUntil: "load",
  });
  await page.screenshot({
    path: "screenshots/shotomatic-features-iphone-13.png",
  });

  await context.close();
  await browser.close();
})();

Hier ist dieselbe Funktionsseite mit der Beschreibung des iPhone 13 aufgenommen:

Mobile Playwright-Screenshot-Ausgabe der Shotomatic-Funktionsseite
Mobile Ansichtsgröße aus Playwright mit der Gerätebeschreibung des iPhone 13.

Nutze Gerätebeschreibungen, wenn User Agent, Touch-Unterstützung, Ansichtsgröße und Geräteskalierungsfaktor wichtig sind. Verwende eine einfache Ansichtsgröße, wenn du nur bestimmte Maße brauchst:

const context = await browser.newContext({
  viewport: { width: 390, height: 844 },
  deviceScaleFactor: 2,
  isMobile: true,
});

Lazy Loading behandeln

Viele Seiten laden Bilder oder zeigen Abschnitte erst, wenn sie in die Ansichtsgröße gelangen. Nimmst du eine Ganzseite zu früh auf, kann der Screenshot leere Bereiche enthalten, weil Inhalte unterhalb des ersten sichtbaren Bereichs noch nicht erschienen sind.

Playwright-Ganzseiten-Screenshot mit großem leerem Bereich vor dem Rendern von Lazy-Loading-Abschnitten
Sofort aufgenommen: Die Seitenhöhe stimmt, aber ein Teil des Inhalts wurde noch nicht gerendert.
Playwright-Ganzseiten-Screenshot nach dem Scrollen durch Lazy-Loading-Abschnitte
Nach dem Scrollen aufgenommen: Die Abschnitte unterhalb des ersten sichtbaren Bereichs konnten erscheinen.

Scrolle vor einem Ganzseiten-Screenshot durch das Dokument, um Lazy-Loading-Bilder und sichtbarkeitsabhängige Abschnitte auszulösen:

async function triggerLazyLoading(page) {
  await page.evaluate(async () => {
    const delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
    const viewportHeight = window.innerHeight;
    const scrollHeight = document.body.scrollHeight;

    for (let y = 0; y < scrollHeight; y += viewportHeight) {
      window.scrollTo(0, y);
      await delay(600);
    }

    window.scrollTo(0, 0);
    await delay(300);
  });
}

Rufe die Funktion vor page.screenshot() auf:

await page.goto(url, { waitUntil: "load", timeout: 45_000 });
await triggerLazyLoading(page);
await page
  .waitForFunction(
    () =>
      Array.from(document.images).every(
        (image) => image.complete && image.naturalWidth > 0,
      ),
    null,
    { timeout: 15_000 },
  )
  .catch(() => {});
await page.screenshot({ path: outputPath, fullPage: true });

Manche Seiten brauchen mehr. Eigene Scrollcontainer, Animationen, verzögerte API-Aufrufe oder virtualisierte Inhalte können einen seitenspezifischen Selektor oder Zustand erfordern.

Die passende Wartestrategie wählen

Die meisten Zuverlässigkeitsprobleme bei Screenshots sind Timingprobleme.

Die Navigationsdokumentation von Playwright erklärt, dass page.goto() standardmäßig auf das load-Ereignis wartet. Moderne Seiten können danach aber weiter Daten abrufen oder rendern. Für Screenshots eignet sich meist eine dieser Strategien:

  • waitUntil: "load" als Ausgangspunkt für gewöhnliche öffentliche Seiten verwenden
  • auf einen bestimmten Locator warten, der das Rendern des wichtigen Inhalts belegt
  • page.waitForFunction() verwenden, wenn die Bereitschaft vom App-Zustand abhängt
  • vor der Aufnahme scrollen, wenn Bilder per Lazy Loading erscheinen
  • feste Pausen nicht zur wichtigsten Wartelogik machen

Zum Beispiel:

await page.goto(url, { waitUntil: "load", timeout: 45_000 });
await page
  .getByRole("heading", { name: "Shotomatic Features" })
  .waitFor({ state: "visible", timeout: 15_000 });
await page.screenshot({ path: outputPath, fullPage: true });

Geh nicht davon aus, dass eine Wartelogik für jede Seite funktioniert. Wenn du die Zielwebsite pflegst, ist ein Locator oder eine Prüfung des App-Zustands meist zuverlässiger als das Warten auf einen allgemeinen Netzwerkzustand.

Wiederholungsversuche ergänzen

Netzwerkanfragen schlagen fehl. Seiten laufen in ein Zeitlimit. Drittanbieter-Widgets hängen. Ein echtes Stapelskript sollte eine fehlgeschlagene URL erneut versuchen, bevor es den gesamten Durchlauf aufgibt.

async function withRetries(task, retries = 2) {
  let lastError;

  for (let attempt = 0; attempt <= retries; attempt += 1) {
    try {
      return await task();
    } catch (error) {
      lastError = error;
      console.warn(`Attempt ${attempt + 1} failed: ${error.message}`);
    }
  }

  throw lastError;
}

Umschließe die Seitenarbeit:

await withRetries(async () => {
  await page.goto(url, { waitUntil: "load", timeout: 45_000 });
  await page.screenshot({ path: outputPath, fullPage: true });
});

Schreibe im Produktiveinsatz außerdem einen JSON-Bericht mit URL, Ausgabepfad, Status, Fehlermeldung und Zeitstempel. Dieser Bericht spart später Zeit, wenn jemand fragt, welche Seiten warum fehlgeschlagen sind.

Eine praktische Ordnerstruktur

Halte bei wiederkehrenden Screenshot-Jobs Eingabe, Ausgabe und Skript getrennt:

website-screenshots-playwright/
  scripts/
    capture-batch.js
  urls/
    launch-pages.txt
    competitor-pages.txt
  screenshots/
    2026-06-23-launch/
    2026-06-23-competitors/
  reports/
    2026-06-23-launch.json

So lässt sich der Ablauf leichter wiederholen. Die Screenshot-Serie bleibt außerdem mit der URL-Liste verbunden, aus der sie entstanden ist.

Häufige Fehler

  • Zu früh aufnehmen: Der Browser kann load erreichen, bevor der wichtige Inhalt sichtbar ist. Warte auf einen Selektor oder ergänze eine seitenspezifische Prüfung.
  • Zu viele Seiten gleichzeitig öffnen: Hohe Parallelität kann den Browser zum Absturz bringen, den Arbeitsspeicher erschöpfen oder Ratenbegrenzungen auslösen. Beginne klein.
  • Ein Dateinamensmuster für jede Website verwenden: URLs können Abfragezeichenfolgen, abschließende Schrägstriche, Duplikate und ungewöhnliche Zeichen enthalten. Bereinige Dateinamen immer und ergänze einen Index.
  • Browserbereinigung vergessen: Schließe Seiten, Kontexte und den Browser. Nicht freigegebene Kontexte werden bei lang laufenden Jobs zu einem echten Problem.
  • Ganzseiten-Screenshots als visuelle Tests behandeln: Eine Screenshot-Datei ist ein Nachweis. Ein visueller Regressionstest braucht zusätzlich Baselines, Vergleichsschwellen und einen Prüfprozess.

Alternativen zu einem Screenshot-Skript mit Playwright

Playwright ist nicht der einzige Weg zur Automatisierung von Website-Screenshots. Die Wahl hängt davon ab, wer die Arbeit nach dem ersten Skript verantwortet.

Für ein fokussiertes Browserautomatisierungsskript kann Puppeteer ausreichen. Playwright passt besser, wenn Screenshots neben einer breiteren Testsuite liegen, Chromium, Firefox und WebKit abgedeckt werden müssen oder Runner, Traces und Berichte von Playwright Test bereits zum Ablauf gehören.

Wenn du Screenshot-Aufnahmen in ein Produkt einbaust, kann eine Screenshot-API weniger Aufwand verursachen als der eigene Betrieb von Browsern.

Wenn du dieses Skript nicht schreiben und pflegen möchtest, lies Website-Screenshots ohne Code automatisieren. Website Capture in Shotomatic nimmt URL-Listen mit seitenspezifischen Optionen auf, hält Ergebnisse prüfbar und exportiert sie, ohne Playwright-Code zu pflegen.

Häufige Fragen

Kann Playwright Website-Screenshots automatisieren?

Ja. Playwright kann einen Browser starten, eine URL öffnen, Ansichtsgrößen oder Geräteoptionen festlegen und mit page.screenshot() einen Screenshot speichern.

Kann Playwright Ganzseiten-Screenshots aufnehmen?

Ja. Übergib fullPage: true an page.screenshot(), um die gesamte scrollbare Seite statt nur der sichtbaren Ansichtsgröße aufzunehmen.

Kann ich mit Playwright Screenshots von mehreren URLs aufnehmen?

Ja. Lege die URLs in einem Array ab, durchlaufe sie und erstelle für jede Aufnahme einen neuen Browserkontext. Ergänze bei größeren Stapeln eine Begrenzung der Parallelität und eine Fehlerbehandlung.

Sollte ich Playwright oder Puppeteer für Website-Screenshots verwenden?

Nutze Playwright für mehrere Browser, Geräteemulation oder einen größeren Testablauf rund um die Screenshots. Puppeteer ist ebenfalls praktisch für Skripte, die sich auf Chrome konzentrieren.

Wann ist ein No-Code-Ablauf besser als Playwright?

Ein No-Code-Ablauf passt besser, wenn Nichtentwickler URL-Listen aufnehmen, prüfen oder exportieren sollen, ohne Skripte, Browserabhängigkeiten oder CI-Jobs zu pflegen.

Quellen

Die Beispiele wurden anhand der aktuellen offiziellen Dokumentation geprüft:

Frequently Asked Questions

Ähnliche Artikel

Weitere Artikel

Website-Screenshots mit Puppeteer automatisieren

Automatisiere Website-Screenshots mit Puppeteer und JavaScript. Erfasse einzelne Seiten, Ganzseiten, URL-Stapel und mobile Ansichten mit einem wiederverwendbaren Skript.

13 Min. Lesezeit
Laptop mit Code für ein Website-Screenshot-Skript mit Puppeteer

Website-Screenshots ohne Code automatisieren

Finde den passenden No-Code-Weg für automatische Website-Screenshots: URL-Listen, Automatisierungsplattformen mit Screenshot-API, Monitoring oder Browser-Helfer.

7 Min. Lesezeit
Mehrere Bildschirme auf einem Schreibtisch für die Prüfung von Website-Screenshots

Website-Screenshots ohne Code automatisieren

Mit Website Capture nimmst du URL-Listen mit eigenen Einstellungen pro Seite auf, prüfst die Ergebnisse und exportierst sie – ohne ein Skript zu pflegen.

Website-Screenshots mit Playwright automatisieren | Blog | Shotomatic