Zum Inhalt springen

Website-Screenshots mit Puppeteer automatisieren

Website-Screenshots mit Puppeteer und JavaScript automatisieren. Eine Seite, vollständige Seiten, URL-Batches und mobile Ansichten mit einem wiederverwendbaren Skript aufnehmen.

12 Min. LesezeitWebsite-AufnahmeVon Temposhot Team

Puppeteer ist eine Node.js-Bibliothek, die das Chrome-Team pflegt. Sie steuert Chrome oder Firefox über eine JavaScript-API und ist eine gängige Wahl für skriptgesteuerte Website-Screenshots. Die Beispiele unten wachsen von einer Aufnahme mit fünf Zeilen zu einem wiederverwendbaren Runner. Dieser liest URLs aus einer Datei, verarbeitet Seiten parallel und schreibt einen Bericht.

Der letzte Abschnitt zeigt denselben Batch-Auftrag als Temposhot-Website-Capture-Lauf auf einem Mac, ohne Skript, das Sie pflegen müssen. Beide Ansätze erzeugen vergleichbare Dateien. Welcher passt, hängt davon ab, wo der Auftrag läuft.

Wann Puppeteer das richtige Werkzeug ist

Puppeteer eignet sich, wenn Screenshots Teil von Code sind, den Sie ohnehin ausführen:

  • ein Node.js-Dienst, der Vorschauen oder Social-Media-Bilder rendert
  • ein Cron-Job oder CI-Schritt, der Seiten nach jedem Deployment aufnimmt
  • ein Scraping-Auftrag, der zusätzlich eine visuelle Dokumentation braucht
  • ein Team, das bereits Funktionen des Chrome DevTools Protocol nutzt

Weniger geeignet ist Puppeteer für einmalige Aufgaben von Personen, die keine Node.js-Projekte pflegen.

Checkliste mit sechs Merkmalen, die für Puppeteer sprechen: Im Team existiert bereits ein Node.js-Projekt, Aufnahmen laufen nach Zeitplan oder in einem CI-Schritt, die Bilddateien fließen in ein anderes Programm oder einen Build, das Team prüft Skriptänderungen wie anderen Code, ein Server oder CI-Runner hat keine Anzeige für eine Desktop-App und der Auftrag braucht Browser-Schritte über einen einfachen URL-Aufruf hinaus.

Puppeteer für ein Screenshot-Skript installieren

mkdir site-shots && cd site-shots
npm init -y
npm install puppeteer

Das Paket puppeteer lädt bei der Installation einen kompatiblen Chrome-Build herunter. Das schlankere Paket puppeteer-core überspringt diesen Download und benötigt stattdessen den Pfad zu einem installierten Browser. Die Skripte unten verwenden .mjs-Dateien, damit top-level await funktioniert.

puppeteer oder puppeteer-core wählen

Verwenden Sie puppeteer auf einem Entwicklerrechner, auf dem der Download erlaubt ist. Verwenden Sie puppeteer-core in einem CI-Image, auf dem Chrome bereits installiert ist, oder in einem Netzwerk, das den Browser-Download blockiert. Die API ist in beiden Paketen gleich, daher ändert sich das Skript nicht. Nur der Aufruf von launch braucht ein executablePath, wenn der Browser an einem eigenen Ort liegt.

Dateibaum des Projekts site-shots: Paketdateien, die Skripte one und run, eine Textdatei urls.txt und ein Ordner shots mit einem datierten Unterordner pro Lauf.

Einen Website-Screenshot aufnehmen

// one.mjs
import puppeteer from 'puppeteer';

const browser = await puppeteer.launch();
const page = await browser.newPage();

await page.setViewport({ width: 1440, height: 900 });
await page.goto('https://example.com', { waitUntil: 'networkidle0' });
await page.screenshot({ path: 'example.png' });

await browser.close();

page.setViewport legt Breite und Höhe fest. Fügen Sie demselben Aufruf deviceScaleFactor: 2 hinzu, um ein Bild mit doppelter Pixeldichte zu erhalten, ähnlich wie auf einem Retina-Display.

Ergebnis der Einstellungen

Das obige Skript mit deviceScaleFactor: 2 hat eine feste Ausgabegröße. Die Werte ergeben sich aus dem Viewport und dem Skalierungsfaktor.

Einstellungen des Skripts für eine Seite: Viewport 1440 mal 900 CSS-Pixel, Device Scale Factor 2, Warten bis networkidle0 mit null Verbindungen, Ausgabe als PNG und Ausgabegröße 2880 mal 1800 Pixel.

Die Ausgabe ist in jeder Richtung doppelt so groß wie der Viewport, weil der Skalierungsfaktor die Pixel vervielfacht und die CSS-Größe gleich bleibt. Ein Viewport von 1440 mal 900 mit Faktor 1 ergibt ein Bild von 1440 mal 900. Das ist die richtige Größe für eine Web-Vorschau. Der Skalierungsfaktor dient einem scharfen Bild auf einem Display mit hoher Pixeldichte. Dadurch verdoppelt sich die Dateigröße.

Einen vollständigen Seiten-Screenshot aufnehmen

await page.screenshot({ path: 'example-full.png', fullPage: true });

Mit fullPage: true deckt das Bild das gesamte scrollbare Dokument ab. Für eine kleinere Datei speichern Sie JPEG oder WebP:

await page.screenshot({ path: 'example.jpg', type: 'jpeg', quality: 80, fullPage: true });

quality akzeptiert Werte von 0 bis 100 und gilt nur für JPEG und WebP. Ein Vollseiten-Screenshot einer langen Seite kann zehntausende Pixel hoch sein. JPEG hält die Dateigröße daher oft im Rahmen.

Größe einer langen Seite

Die Breite bleibt die Viewport-Breite, die Höhe folgt dem Dokument. Ein langer Artikel macht das Bild sehr hoch. Die Werte unten zeigen das Ausmaß der Änderung.

Vier Kennzahlen für die vollständige Aufnahme eines langen Artikels mit 1440 Pixeln Breite: 12000 Pixel hoch, 17,3 Millionen Pixel, das 2,1-Fache der Fläche eines 4K-Bildes und eine JPEG-Qualitätseinstellung von 80.

Ein Bild mit 3840 mal 2160 Pixeln hat etwa 8,3 Millionen Pixel. Das Beispielbild ist also rund doppelt so groß wie ein 4K-Bild. Ein sehr hohes Bild lässt sich schlecht als Ganzes betrachten. Teilen Sie sehr lange Seiten mit clip in Abschnitte auf, wenn das Bild auf einem Bildschirm oder in einem Dokument gezeigt wird.

Einen Abschnitt zuschneiden

Mit der Option clip speichern Sie einen Bereich. Die Koordinaten sind CSS-Pixel vom oberen Seitenrand, nicht vom Viewport:

await page.screenshot({
  path: 'example-pricing.png',
  clip: { x: 0, y: 2400, width: 1440, height: 900 },
});

Verwenden Sie in einem Aufruf entweder fullPage oder clip. Um eine lange Seite in mehrere Dateien zu zerlegen, lesen Sie die Höhe mit document.body.scrollHeight aus und nehmen für jeden Abschnitt einen eigenen Clip auf. Eine 12000 Pixel hohe Seite, zerlegt in Abschnitte von 900 Pixeln, ergibt 14 Dateien. Die letzte Datei enthält nur 300 Pixel.

Einen wiederverwendbaren URL-Runner bauen

// run.mjs
import { readFile, mkdir, writeFile } from 'node:fs/promises';
import puppeteer from 'puppeteer';

const urls = (await readFile('urls.txt', 'utf8'))
  .split('\n').map((l) => l.trim()).filter(Boolean);
const outDir = `shots/${new Date().toISOString().slice(0, 10)}`;
await mkdir(outDir, { recursive: true });

const browser = await puppeteer.launch();

async function shoot(url, index) {
  const page = await browser.newPage();
  try {
    await page.setViewport({ width: 1440, height: 900 });
    await page.goto(url, { waitUntil: 'networkidle2', timeout: 45000 });
    const path = `${outDir}/${String(index + 1).padStart(3, '0')}.jpg`;
    await page.screenshot({ path, type: 'jpeg', quality: 80, fullPage: true });
    return { url, path, ok: true };
  } finally {
    await page.close();
  }
}

Eine neue Seite pro URL bedeutet, dass ein Absturz auf einer Website die nächste nicht beeinflusst. Der datierte Ausgabeordner bewahrt frühere Läufe unverändert.

Der Runner hat fünf Schritte. Die Abbildung unten listet sie in der Reihenfolge auf, mit der Datei oder dem Prozess, den jeder Schritt verwendet.

Ablauf mit fünf Kästen: urls.txt lesen, den datierten Ausgabeordner anlegen, einen Browser für den gesamten Lauf starten, jede URL auf einer eigenen Seite aufnehmen und report.json mit allen Ergebnissen schreiben.

URL-Liste bereinigen

Leere Zeilen, Kommentare und doppelte URLs verschwenden Browserzeit. Ein Duplikat erzeugt außerdem eine zweite Datei für dieselbe Seite. Die folgende Version überspringt Zeilen, die mit einer Raute beginnen, entfernt exakte Duplikate und verwirft alles, was keine HTTP- oder HTTPS-Adresse ist. raw enthält den Dateiinhalt aus dem vorherigen Schritt.

const lines = raw.split('\n').map((l) => l.trim()).filter((l) => l && !l.startsWith('#'));
const urls = [...new Set(lines)].filter((l) => {
  try {
    const { protocol } = new URL(l);
    return protocol === 'http:' || protocol === 'https:';
  } catch {
    return false;
  }
});

Set vergleicht Zeichenketten exakt. Daher bleiben https://example.com und https://example.com/ zwei URLs. Protokollieren Sie auch die abgelehnten Zeilen. Ein Tippfehler wie htps://example.com erscheint dann zu Beginn des Laufs im Protokoll und nicht als Timeout 45 Sekunden später.

Nummerierung für große Batches

Das Skript füllt den Index auf drei Stellen auf. Das sortiert bis 999 Dateien korrekt. Index 1000 wird zu 1000.jpg. Eine Textsortierung setzt diese Datei dann zwischen 100.jpg und 101.jpg. Füllen Sie den Index stattdessen auf die Breite des Batches auf:

const width = String(urls.length).length;
const path = `${outDir}/${String(index + 1).padStart(width, '0')}.jpg`;

Ein Batch mit 1.250 URLs erhält die Breite 4, sodass die erste Datei 0001.jpg heißt. Berechnen Sie die Breite einmal, bevor die Worker starten.

Parallelität für größere Batches hinzufügen

const LIMIT = 4;
const queue = [...urls.entries()];
const results = [];

async function worker() {
  while (queue.length) {
    const [i, url] = queue.shift();
    results.push(await shootWithRetry(url, i));
  }
}

await Promise.all(Array.from({ length: LIMIT }, worker));
await browser.close();

Jeder Worker nimmt die nächste URL aus einer gemeinsamen Warteschlange. Beginnen Sie mit 4 und erhöhen Sie das Limit erst, nachdem Sie den Speicherbedarf geprüft haben. Jede geöffnete Seite belegt einen eigenen Renderer-Prozess.

Das Skript öffnet alle Seiten aus einem Browser. Seiten teilen sich den Cache des Browsers und standardmäßig auch Cookies. Bei einem Batch aus unabhängigen öffentlichen Websites ist das unbedenklich. Wenn ein Lauf keinen Zustand von einer Website zur nächsten übertragen darf, erstellen Sie pro URL einen Kontext mit browser.createBrowserContext() und schließen ihn nach der Aufnahme. Jeder Kontext kostet Speicher. Diese Entscheidung gehört deshalb neben das Parallelitätslimit.

Das Limit wählen

Das Limit legt fest, wie viele Seiten gleichzeitig gerendert werden. Ein niedriges Limit hält den Speicherbedarf konstant und verlängert den Lauf. Ein hohes Limit kehrt das um. Die Tabelle zeigt den Zielkonflikt für einen Batch mit 200 URLs, bei dem jede Seite im Durchschnitt etwa 6 Sekunden braucht.

Vergleich der Limits 1 und 10 für 200 URLs mit etwa 6 Sekunden pro Seite: Eine Seite nach der anderen dauert etwa 20 Minuten, zehn Seiten gleichzeitig etwa 2 Minuten zuzüglich des Speicherbedarfs von zehn Renderern.

Die idealen Zeiten setzen keine Netzwerkwartezeit und keine Fehler voraus. Reale Websites variieren, und Timeouts und Wiederholungen verlängern den Lauf. Messen Sie einen Batch mit 20 URLs bei zwei Limits auf dem Zielrechner. Wählen Sie dann das höchste Limit, bei dem der Mac weiterhin reagiert.

Mobile Screenshots aufnehmen

Puppeteer enthält Gerätebeschreibungen über KnownDevices.

import puppeteer, { KnownDevices } from 'puppeteer';

const page = await browser.newPage();
await page.emulate(KnownDevices['iPhone 13']);
await page.goto('https://example.com');

page.emulate legt Viewport, Pixelverhältnis, Touch-Unterstützung und User Agent in einem Aufruf fest. Für eine einfache mobile Breite ohne Änderung des User Agent rufen Sie setViewport mit isMobile: true und hasTouch: true auf.

Vergleich zweier mobiler Einstellungen: emulate mit einer Gerätebeschreibung ändert Viewport, Pixelverhältnis, Touch-Unterstützung und User Agent. setViewport mit isMobile ändert nur Viewport und Touch-Verhalten.

Verwenden Sie emulate, wenn eine Website je nach User Agent unterschiedliches Markup ausliefert. Verwenden Sie setViewport, wenn nur die Layoutbreite zählt. Beide Aufrufe wirken auf die Seite, auf der sie laufen. Eine später geöffnete zweite Seite braucht daher einen eigenen Aufruf.

Ein Batch, der Desktop und Mobil mischt, braucht einen Viewport pro Ausgabeset und nicht einen pro Skript. Legen Sie die mobilen Bilder in einen eigenen datierten Ordner, etwa shots/2026-04-10-mobile. So überschneiden sich die Dateinummern der beiden Sets nicht. Temposhot Website Capture verwendet für denselben Zweck die Mobile-Größe 390 mal 844. Sie wird pro Zeile im selben Lauf gesetzt.

Den emulierten Viewport prüfen

Prüfen Sie die Layoutbreite der Seite vor der Aufnahme. Ein falscher Deskriptor erzeugt ein Desktop-Layout in einem Bild mit Mobilgröße. Der folgende Code gibt Breite und Pixelverhältnis aus, die die Seite sieht:

const seen = await page.evaluate(() => ({
  width: window.innerWidth,
  pixelRatio: window.devicePixelRatio,
}));
console.log(seen);

Für den Deskriptor iPhone 13 in aktuellen Puppeteer-Versionen sollte die Breite 390 betragen. Das Pixelverhältnis stammt ebenfalls aus dem Deskriptor. Prüfen Sie die Werte in der Version, die Sie installieren, da sich die Gerätedaten zwischen Versionen ändern.

Lazy-Loading-Inhalte behandeln

Bilder, die beim Scrollen geladen werden, bleiben in einer Aufnahme direkt nach der Navigation leer. Scrollen Sie die Seite daher zuerst durch:

await page.evaluate(async () => {
  for (let y = 0; y < document.body.scrollHeight; y += window.innerHeight) {
    window.scrollTo(0, y);
    await new Promise((r) => setTimeout(r, 200));
  }
  window.scrollTo(0, 0);
});

Der Eintrag Lazy Loading erklärt das Muster.

Wie lange der Scroll-Durchlauf dauert

Die Schleife wartet 200 Millisekunden pro Schritt, und jeder Schritt bewegt sich um eine Viewport-Höhe. Das Beispiel zeigt eine Seite mit 8000 Pixeln bei einem Viewport von 900 Pixeln.

Zeitablauf des Scroll-Durchlaufs auf einer Seite mit 8000 Pixeln: Scroll auf 0 bei 0,0 Sekunden, 900 Pixel bei 0,2 Sekunden, 7200 Pixel bei 1,6 Sekunden und zurück zum Seitenanfang bei 1,8 Sekunden.

Die Seite hat neun Schritte. Der Durchlauf verlängert die Zeit vor dem Screenshot daher um 1,8 Sekunden. Eine Seite, die Bilder langsam lädt, braucht pro Schritt eine längere Pause. Eine Seite mit unendlichem Scrollen erreicht nie ein festes Ende. Bei unendlichem Scrollen stoppen Sie nach einer festen Anzahl von Schritten statt an der Dokumenthöhe.

In einem Container scrollen

Manche Layouts scrollen ein inneres Element statt des Fensters. Die Schleife oben erkennt dann keine Bewegung, und der untere Teil der Seite bleibt leer. Scrollen Sie das Element stattdessen über scrollTop und verwenden Sie dessen eigene scrollHeight und clientHeight als Grenzen. Vergleichen Sie nach einem Lauf das erste und das letzte Bild. Zwei identische Bilder bedeuten, dass die Seite nicht gescrollt hat. Das weist auf einen Container hin.

Die passende Wartestrategie wählen

OptionRückgabe, wenn
loadDas load-Ereignis ausgelöst wird. Dies ist der Standard.
domcontentloadedDas HTML geparst ist.
networkidle0Keine Netzwerkverbindungen für mindestens 500 ms bestehen.
networkidle2Nicht mehr als 2 Verbindungen für mindestens 500 ms bestehen.

networkidle0 kann bei Seiten, die regelmäßig abfragen oder streamen, in einen Timeout laufen. networkidle2 toleriert diesen Hintergrundverkehr. Wenn eine Seite ein eindeutiges Bereitschaftssignal hat, ist page.waitForSelector auf dieses Element die zuverlässigste Wahl. Das Standard-Timeout für die Navigation beträgt 30 Sekunden.

Checkliste mit Bereitschaftssignalen für eine Dashboard-Seite: Der Hauptcontainer des Diagramms ist im DOM vorhanden, der Ladeindikator ist entfernt, die letzte Datenzeile ist sichtbar, Webfonts sind geladen und der Consent-Banner ist geschlossen oder ausgeblendet.

Wählen Sie ein Signal, das die Seite erst setzt, wenn der Inhalt bereit ist. Ein Selektor, der bei jedem Seitenaufruf existiert, etwa der Header, belegt nichts über die Daten darunter.

Vor der Wahl messen

Messen Sie die Navigation für jede URL, bevor Sie eine Wartestrategie wählen. Der folgende Code misst die Zeit bis zum load-Ereignis:

const started = Date.now();
await page.goto(url, { waitUntil: 'load', timeout: 45000 });
const loadMs = Date.now() - started;

Schreiben Sie loadMs neben jede URL in den Bericht. Laden die meisten Seiten innerhalb weniger Sekunden, ist das Standardwarten in Ordnung. Liegt eine Gruppe von Seiten nahe am Timeout, stellen Sie diese URLs auf domcontentloaded um und warten auf einen Selektor. Behalten Sie dann den Bericht, um die Änderung zu bestätigen.

Wiederholungen und Bericht hinzufügen

async function shootWithRetry(url, i, tries = 3) {
  for (let attempt = 1; attempt <= tries; attempt++) {
    try {
      return await shoot(url, i);
    } catch (error) {
      if (attempt === tries) return { url, ok: false, error: error.message };
    }
  }
}

// after Promise.all in run.mjs
await writeFile(`${outDir}/report.json`, JSON.stringify(results, null, 2));

Der Bericht listet jede URL mit ihrem Dateipfad oder Fehler auf. Übergeben Sie die fehlgeschlagenen Einträge für einen zweiten Durchlauf zurück in urls.txt.

Die Wiederholungsliste aus dem Bericht erstellen

Der Bericht macht den zweiten Durchlauf zu einem Filter statt zu einer manuellen Kopie. Dieser jq-Befehl schreibt die fehlgeschlagenen URLs in eine neue Datei:

jq -r '.[] | select(.ok == false) | .url' shots/2026-04-10/report.json > urls-retry.txt

Lassen Sie das Skript für den zweiten Durchlauf urls-retry.txt lesen. Das Skript benennt den Ausgabeordner nach dem Datum. Ein zweiter Lauf am selben Tag schreibt daher in denselben Ordner. Dateien mit denselben Nummern überschreiben dann die Bilder des ersten Laufs. Fügen Sie outDir vor dem zweiten Durchlauf ein Suffix wie -retry hinzu, damit beide Läufe im Ordner bleiben.

Laufzeit im ungünstigsten Fall

Eine langsame Website kann alle Wiederholungen ausschöpfen. Timeout und Anzahl der Wiederholungen bestimmen den ungünstigsten Fall für eine URL. Das Limit verteilt diese Kosten auf die Worker. Die Abbildung unten verwendet die Werte aus dem Skript.

Vier Kennzahlen für den ungünstigsten Fall: 3 Versuche pro URL, 45 Sekunden pro Versuch, 135 Sekunden pro URL, wenn jeder Versuch in einen Timeout läuft, und etwa 56 Minuten für 100 URLs mit 4 Workern, die alle in einen Timeout laufen.

Der ungünstigste Fall tritt bei einem gesunden Batch unwahrscheinlich ein, legt aber eine Obergrenze fest. Planen Sie den Auftrag so, dass ein Lauf mit vielen Timeouts noch endet, bevor der nächste Lauf startet.

Nur Fehler wiederholen, die sich ändern können

Ein Navigations-Timeout oder eine abgebrochene Verbindung kann beim zweiten Versuch gelingen. Eine Seite, die vollständig lädt, aber den erwarteten Selektor nicht enthält, scheitert meist erneut auf dieselbe Weise. Dasselbe gilt für eine Seite, die den Status 404 zurückgibt. Wiederholen Sie die erste Gruppe und erfassen Sie die zweite einmal. Die Funktion shootWithRetry oben wiederholt jeden Fehler. Ein dauerhafter Fehler kostet daher drei volle Timeouts, bevor er im Bericht erscheint.

Eine praktische Ordnerstruktur

site-shots/
  run.mjs
  urls.txt
  shots/
    2026-04-10/
      001.jpg
      002.jpg
      report.json

Ein Ordner pro Lauftag, ein Bericht pro Ordner. Diese Struktur reicht aus, um Läufe später ohne Datenbank zu vergleichen.

Häufige Fehler

  1. networkidle0 auf jeder Website verwenden. Seiten mit Analytics oder Chat-Widgets kommen nie zur Ruhe.
  2. Seiten offen lassen. Der Speicherbedarf wächst, bis der Prozess langsamer wird oder abstürzt.
  3. Zu viele Seiten gleichzeitig ausführen. Ein Limit von 20 auf einem Laptop verursacht oft mehr Timeouts, nicht schnellere Läufe.
  4. Consent-Overlays aufnehmen. Klicken Sie den Ablehnen-Button per Selektor oder blenden Sie den Banner mit page.addStyleTag aus.
  5. Nutzungsbedingungen ignorieren. Automatisierte Aufnahmen senden echte Anfragen. Prüfen Sie die Nutzungsbedingungen jeder Website und halten Sie die Rate niedrig.

Fehlersuche nach Symptom

SymptomWahrscheinliche UrsacheBehebung
Leerer Bereich in einem Vollseiten-BildLazy-geladener Inhalt wurde nie in den sichtbaren Bereich gescrolltDen Scroll-Durchlauf vor der Aufnahme ausführen
Timeout bei gotoDie Seite erreicht das Warte-Ereignis nieAuf einen Selektor warten oder auf domcontentloaded umstellen
Dasselbe Bild für jede URLDie Aufnahme lief, bevor die Navigation fertig wargoto auf jeder Seite mit await aufrufen und pro URL eine neue Seite öffnen
Bild doppelt so groß wie erwartetdeviceScaleFactor ist 2Den Faktor entfernen oder auf 1 setzen
Speicher wächst bei einem langen LaufSeiten bleiben nach der Aufnahme offenJede Seite in einem finally-Block schließen und die Parallelität begrenzen
Consent-Banner im BildDer Banner wurde nicht behandeltDen Ablehnen-Button per Selektor klicken oder den Banner ausblenden
Do- und Dont-Liste für ein Screenshot-Skript: jede Seite schließen, die Parallelität begrenzen, auf ein Bereitschaftssignal warten und einen Bericht führen. networkidle0 nicht überall verwenden und denselben Ausgabeordner zwischen Läufen nicht wiederverwenden.

Alternativen zu einem Puppeteer-Screenshot-Skript

  • Playwright hat eine ähnliche API und steuert zusätzlich WebKit. Siehe Website-Screenshots mit Playwright automatisieren.
  • Gehostete Screenshot-APIs betreiben den Browser für Sie und liefern Bilder über HTTP.
  • Browser-Erweiterungen wie die Temposhot-Erweiterung speichern einen PNG-Screenshot der gesamten aktiven Seite.
  • Temposhot Website Capture führt eine URL-Liste ohne Code auf einem Mac aus. Verfügbare Größen sind Desktop 1920×1080, Tablet 768×1024 oder Mobile 390×844, und die Verzögerung pro Zeile liegt zwischen 0 und 60 s.

Wann sich das Skript nicht lohnt

Ein Skript kostet über die Zeit mehr, als seine erste Version vermuten lässt. Jede Änderung an einer Website, jedes Node.js-Upgrade und jedes Chrome-Update kann eine Korrektur erfordern. Ein monatlicher Auftrag über eine Liste, die sich oft ändert, kostet in Website Capture weniger, weil dort URL-Liste und Zeileneinstellungen in einem Fenster stehen. Behalten Sie das Skript, wenn seine Bilder in einen Build-Schritt fließen, wenn eine CI-Pipeline es ausführen muss oder wenn die Schritte über einen Besuch und eine Aufnahme hinausgehen.

Derselbe Batch in Temposhot Website Capture

Temposhot Website Capture deckt den Batch-Auftrag dieses Beitrags ohne Skript ab. Die folgenden Einstellungen entsprechen dem Runner bei der Vollseiten-Aufnahme mit 1440 mal 900, mit den Warte- und Blockierungsoptionen, die Temposhot pro Zeile anbietet.

Einstellungen für einen Temposhot-Website-Capture-Batch: Gerät Desktop, Bereich Full page, Warten auf Network idle, 2 Sekunden Verzögerung, Banner für Cookies ablehnen, Werbung und Tracker blockiert, JPEG mit Qualität 80 und 4 gleichzeitige Browser.

Die Gerätegröße weicht absichtlich vom Skript ab. Desktop ist in Temposhot 1920 mal 1080, das Skript verwendet 1440 mal 900. Setzen Sie in beiden denselben Viewport, wenn die Ausgaben übereinstimmen müssen. Ein Temposhot-Lauf endet dann mit ZIP, Images oder PDF in der Ergebnisleiste. Damit exportieren Sie die ausgewählten Bilder.

Fünf Schritte für den URL-Batch in Temposhot Website Capture: Liste mit Bulk insert einfügen, Run Settings festlegen, Capture starten, fehlgeschlagene Zeilen mit Retry wiederholen und die Ergebnisse als ZIP exportieren.

Jede Zeile zeigt während des Laufs ihren Zustand, etwa Capturing oder Capture failed. Eine fehlgeschlagene Zeile lässt sich einzeln wiederholen, ohne den restlichen Batch neu zu starten.

Vergleich der Zeilenzustände: Capture pending wartet auf einen freien Browser-Slot, Capturing lädt die Seite, Capture complete bedeutet, dass der Screenshot gespeichert wurde, und Capture failed bedeutet, dass kein Screenshot entstanden ist.

FAQ

Funktioniert Puppeteer mit Firefox?

Ja. Aktuelle Versionen können neben Chrome auch Firefox starten. Chrome bleibt die meistgenutzte Option.

Kann Puppeteer WebP-Screenshots speichern?

Ja. Setzen Sie type: 'webp' in den Screenshot-Optionen. Der Wert quality gilt für WebP wie für JPEG.

Warum läuft page.goto auf einigen Websites in einen Timeout?

Die Seite hat das gewählte Warte-Ereignis nicht innerhalb von 30 Sekunden erreicht. Wechseln Sie zu networkidle2 oder load, erhöhen Sie timeout oder warten Sie stattdessen auf einen Selektor.

Warum ist ein Teil meines Vollseiten-Bildes leer?

Der Inhalt lädt, wenn er in den sichtbaren Bereich scrollt. Führen Sie vor der Aufnahme den Scroll-Durchlauf aus dem Abschnitt zu Lazy Loading aus und warten Sie, bis die letzte Zeile erscheint.

Wie viele URLs schafft ein Lauf?

Die Grenze ergibt sich aus Speicher und Zeit, nicht aus dem Code. Messen Sie einen Batch mit 20 URLs bei der Parallelität, die Sie planen, und beobachten Sie den Speicher. Skalieren Sie von dort. Temposhot Website Capture erlaubt für Concurrent browsers Werte von 1 bis 10, der Standard ist 4.

Sollte die Screenshot-Ausgabe in Git?

Nein. Die Bilder und der Bericht sind Build-Ausgaben, die mit jedem Lauf wachsen. Behalten Sie urls.txt und das Skript in der Versionsverwaltung und speichern Sie den Ausgabeordner dort, wo seine Größe passt.

Quellen

Website-Screenshot-Automatisierung ohne Code?

Temposhot Website Capture führt dieselbe Art von URL-Batch lokal auf einem Mac aus, mit Einstellungen pro Zeile und ohne Skript, das Sie pflegen müssen. Siehe Automatisierung von Website-Screenshots oder den Leitfaden zu den Capture-Optionen.

puppeteerwebsite-captureautomationnodejs

Verwendete Begriffe: full page screenshot, headless browser, playwright, puppeteer, screenshot api, screenshot automation, viewport screenshot

Verwandeln Sie wiederholbare Screenshots in fertige Ergebnisse

Temposhot erstellt Screenshots per Timer oder bei jedem Klick und exportiert das Ergebnis als PDF, Bilder, ZIP oder MP4.

Ähnliche Beiträge