Come automatizzare gli screenshot dei siti web con Playwright
Usa Playwright e JavaScript per automatizzare gli screenshot di una pagina, pagine intere, viste mobile e batch di URL con nuovi tentativi.

In questo articolo costruiremo uno script Playwright per gli screenshot in più fasi: prima una singola viewport, poi una pagina intera, un esecutore riutilizzabile per gli URL e una viewport mobile.
Playwright è adatto quando gli screenshot devono stare accanto al codice che li produce. Offre il rendering di un browser reale, contesti isolati, controllo esplicito della viewport, emulazione dei dispositivi e strumenti per attendere lo stato della pagina che ti interessa.
Gli esempi usano la pagina delle funzioni di Shotomatic, https://www.shotomatic.com/features, così puoi confrontare la stessa pagina nelle acquisizioni per viewport, pagina intera, batch e mobile.
In breve: usa Playwright quando l'automazione degli screenshot deve vivere nel codice. Crea un contesto del browser, imposta viewport o dispositivo, attendi lo stato che ti interessa, chiama
page.screenshot(), quindi aggiungi pagine intere, batch, nuovi tentativi e rapporti. Se non vuoi occuparti dello script e della sua manutenzione, Website Capture di Shotomatic può essere più semplice.
Quando Playwright è lo strumento adatto
Usa Playwright quando lo screenshot deve seguire la logica del browser.
È indicato per:
- acquisire screenshot nella CI;
- eseguire l'accesso prima dell'acquisizione;
- attendere un selettore o uno stato preciso dell'app;
- eseguire lo stesso lavoro con Chromium, Firefox o WebKit;
- creare screenshot adattivi da impostazioni esplicite della viewport;
- generare screenshot dentro uno strumento interno.
Diventa meno comodo quando chi ha bisogno degli screenshot non mantiene lo script. Se il lavoro deve vivere nel codice, Playwright è un buon punto di partenza.
Installa Playwright per uno script di screenshot
Per un semplice script Node.js, installa la libreria Playwright e il browser che vuoi automatizzare:
$ mkdir website-screenshots-playwright
$ cd website-screenshots-playwright
$ npm init -y
$ npm i -D playwright
$ npx playwright install chromium
La documentazione della libreria di Playwright usa la stessa struttura di base: installazione del pacchetto e dei browser, importazione di Playwright, avvio di un browser e interazione con le pagine. Se in seguito ti servono Firefox o WebKit, installa anche quei browser.
Crea le cartelle per script e risultati:
$ mkdir scripts screenshots
Acquisisci lo screenshot di un sito
Crea 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();
}
})();
Eseguilo:
$ node scripts/capture-one.js
Il codice acquisisce la viewport visibile. L'API per gli screenshot di Playwright supporta anche pagine intere, singoli elementi, buffer, ritagli e opzioni di qualità.
L'esecuzione crea screenshots/shotomatic-features.png:
Acquisisci uno screenshot a pagina intera
Per uno screenshot a pagina intera, passa fullPage: true:
await page.screenshot({
path: "screenshots/shotomatic-features-full-page.png",
fullPage: true,
});
Usa la pagina intera quando ti serve tutto il documento dall'alto verso il basso. Usa uno screenshot della viewport quando conta ciò che un visitatore vede su uno schermo di dimensioni precise.
Anche l'acquisizione a pagina intera dipende dallo stato della pagina. fullPage: true cambia l'area, ma non forza il rendering di immagini caricate in differita, animazioni o sezioni attivate quando entrano nella viewport. La sezione sul caricamento differito spiega perché conta lo stato della pagina.
Inserisci l'URL di destinazione in uno script batch
Quando lo script per una pagina funziona, sposta l'URL in uno script che accetta un elenco e salva i file con nomi prevedibili. L'esempio continua a usare soltanto /features, così il risultato resta facile da seguire. In seguito potrai aggiungere altri URL allo stesso array.
Crea 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();
}
})();
Questa versione è volutamente sequenziale. È più lenta, ma molto più facile da correggere. Aggiungi la concorrenza soltanto quando funziona in modo affidabile sulle tue pagine.
Aggiungi un limite di concorrenza ai batch grandi
Per 5 URL basta un ciclo semplice. Per 50 o 500, probabilmente serve un piccolo limite di concorrenza.
Evita di aprire centinaia di pagine insieme. L'automazione dei browser usa molta memoria e molti siti applicano limiti o smettono di rispondere se ricevono richieste troppo aggressive. Parti da 2-4 acquisizioni simultanee e aumenta soltanto dopo avere ottenuto risultati stabili.
Aggiungi lo stesso helper usato nella versione Puppeteer di questa guida:
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;
}
Poi sostituisci il ciclo sequenziale:
const results = await runWithConcurrency(urls, 3, (url, index) =>
captureUrl(browser, url, index),
);
In questo modo resta aperto un solo browser, ogni acquisizione usa un contesto isolato e il numero di pagine attive contemporaneamente rimane limitato. La documentazione Library di Playwright usa contesti espliciti nel flusso degli script Node, assegnando a ogni acquisizione il proprio ciclo di vita.
Acquisisci screenshot mobile o tablet
Playwright include profili di emulazione dei dispositivi per telefoni e tablet comuni. Per esempio:
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();
})();
Ecco la stessa pagina delle funzioni acquisita con il profilo iPhone 13:
Usa i profili quando contano user agent, supporto del tocco, viewport e fattore di scala del dispositivo. Usa una viewport semplice quando ti servono soltanto dimensioni precise:
const context = await browser.newContext({
viewport: { width: 390, height: 844 },
deviceScaleFactor: 2,
isMobile: true,
});
Gestisci il contenuto caricato in differita
Molte pagine caricano immagini o mostrano sezioni soltanto quando entrano nella viewport. Se acquisisci troppo presto la pagina intera, lo screenshot può conservare spazi vuoti dove il contenuto sotto la piega non è ancora comparso.
Prima dello screenshot a pagina intera, scorri il documento per attivare immagini caricate in differita e sezioni mostrate all'ingresso nella viewport:
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);
});
}
Usalo prima di page.screenshot():
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 });
Per alcune pagine serve altro. Contenitori di scorrimento personalizzati, animazioni, chiamate API ritardate e contenuti virtualizzati possono richiedere un selettore o uno stato specifico.
Scegli la strategia di attesa adatta
Gran parte dei problemi di affidabilità degli screenshot dipende dai tempi.
La documentazione sulla navigazione di Playwright spiega che, per impostazione predefinita, page.goto() attende l'evento load; le pagine moderne, però, possono continuare a recuperare dati o eseguire il rendering. Per gli screenshot, in genere conviene:
- partire da
waitUntil: "load"per le normali pagine pubbliche; - attendere un locator preciso che dimostri il rendering del contenuto importante;
- usare
page.waitForFunction()quando la prontezza dipende dallo stato dell'app; - scorrere prima dell'acquisizione se le immagini vengono caricate in differita;
- evitare pause fisse come regola principale di attesa.
Per esempio:
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 });
Non dare per scontato che una sola regola funzioni ovunque. Se gestisci il sito di destinazione, un locator o un'attesa legata allo stato dell'app è di solito più affidabile di una condizione generica della rete.
Aggiungi nuovi tentativi
Le richieste di rete falliscono, le pagine superano il timeout e i widget di terze parti possono bloccarsi. Uno script batch reale deve riprovare l'URL non riuscito prima di abbandonare la sessione.
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;
}
Avvolgi il lavoro sulla pagina:
await withRetries(async () => {
await page.goto(url, { waitUntil: "load", timeout: 45_000 });
await page.screenshot({ path: outputPath, fullPage: true });
});
In produzione, scrivi anche un rapporto JSON con URL, percorso del risultato, stato, messaggio di errore e data e ora. In seguito farà risparmiare tempo quando qualcuno chiederà quali pagine non sono riuscite e perché.
Una struttura pratica per le cartelle
Per i lavori da ripetere, mantieni separati input, output e script:
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
La struttura rende il flusso più facile da rieseguire e mantiene il gruppo di screenshot associato all'elenco di URL che lo ha prodotto.
Errori comuni
- Acquisizione troppo anticipata: il browser può raggiungere
loadprima che il contenuto importante sia visibile. Attendi un selettore o aggiungi un controllo specifico per la pagina. - Troppe pagine aperte insieme: un'elevata concorrenza può bloccare il browser, esaurire la memoria o attivare limiti. Parti con un numero ridotto.
- Un unico schema di nomi per ogni sito: gli URL possono contenere query string, barre finali, duplicati e caratteri insoliti. Normalizza sempre i nomi e includi un indice.
- Pulizia del browser dimenticata: chiudi pagine, contesti e browser. I contesti non chiusi diventano un problema concreto nei processi lunghi.
- Screenshot a pagina intera trattati come test visivi: il file è una prova. Un test di regressione visiva richiede anche baseline, soglie di confronto e un processo di revisione.
Alternative a uno script Playwright
Playwright non è l'unico modo per automatizzare gli screenshot dei siti. La scelta dipende da chi sarà responsabile del lavoro dopo l'esistenza del primo script.
Se ti basta uno script mirato per automatizzare il browser, Puppeteer può essere sufficiente. Playwright è più adatto quando gli screenshot affiancano una suite di test più ampia, servono Chromium, Firefox e WebKit oppure il runner, le tracce e i rapporti di Playwright Test fanno già parte del lavoro.
Se stai integrando l'acquisizione in un prodotto, un'API per screenshot può ridurre il lavoro rispetto alla gestione autonoma dei browser.
Se non vuoi occuparti di scrivere e mantenere questo script, leggi come automatizzare gli screenshot dei siti web senza codice, oppure usa Website Capture in Shotomatic per acquisire schermate da un elenco di URL, impostare opzioni per ogni pagina, rivedere i risultati ed esportarli senza mantenere codice Playwright.
FAQ
Playwright può automatizzare gli screenshot dei siti web?
Sì. Playwright può avviare un browser, aprire un URL, impostare viewport o dispositivo e salvare uno screenshot della pagina con page.screenshot().
Playwright può acquisire screenshot a pagina intera?
Sì. Passa fullPage: true a page.screenshot() per acquisire l'intera pagina scorrevole anziché la sola viewport visibile.
Posso acquisire più URL con Playwright?
Sì. Inserisci gli URL in un array, scorrili con un ciclo e crea un nuovo contesto del browser per ogni acquisizione. Per i batch più grandi, aggiungi un limite di concorrenza e la gestione degli errori.
Devo usare Playwright o Puppeteer per gli screenshot dei siti web?
Usa Playwright se vuoi coprire più browser, emulare dispositivi o inserire gli screenshot in un flusso di test più ampio. Puppeteer è pratico anche per script incentrati su Chrome.
Quando è preferibile un flusso senza codice rispetto a Playwright?
È preferibile quando utenti non tecnici devono avviare, controllare o esportare screenshot da elenchi di URL senza mantenere script, dipendenze dei browser o processi CI.
Riferimenti
Gli esempi qui sopra sono stati controllati sulla documentazione ufficiale attuale:
- Documentazione Library di Playwright per browser, contesto, pagina e pulizia;
- Guida agli screenshot e API
Page.screenshot()per le opzioni di acquisizione; - Documentazione sull'emulazione per i profili dei dispositivi;
- Documentazione sulla navigazione e API
page.waitForFunction()per le attese.
Articoli correlati
Altri articoliCome automatizzare gli screenshot dei siti web con Puppeteer
Usa Puppeteer e JavaScript per automatizzare gli screenshot di una pagina, pagine intere, batch di URL e viewport mobile con uno script riutilizzabile.

Come automatizzare gli screenshot dei siti web senza scrivere codice
Scegli come automatizzare gli screenshot senza codice: acquisizione da un elenco di URL, piattaforme collegate a un'API, monitoraggio o estensioni.

Come acquisire screenshot di siti web in serie sul Mac
Acquisisci in serie gli screenshot di un sito sul Mac con Shotomatic. Incolla gli URL, scegli desktop, tablet o mobile, esegui acquisizioni parallele ed esporta per audit o report.

Cosa controllare prima di acquistare un libro di testo digitale per studiare offline
Prima dell'acquisto, verifica dispositivi offline, file portatili, limiti di stampa, durata dell'accesso, esportazione delle note e accessibilità.

Automatizza gli screenshot dei siti web senza scrivere codice
Con Website Capture puoi acquisire elenchi di URL, impostare ogni pagina, controllare i risultati ed esportarli senza mantenere uno script.