Aller au contenu

Comment automatiser les captures d'écran de sites web avec Puppeteer

Utilisez Puppeteer pour automatiser les captures d'écran de sites web en JavaScript. Capturez une page, des pages entières, des lots d'URL et des vues mobiles avec un script réutilisable.

14 min de lectureCapture de sites webPar Temposhot Team

Puppeteer est une bibliothèque Node.js maintenue par l'équipe Chrome. Elle pilote Chrome ou Firefox via une API JavaScript et constitue un choix courant pour les captures d'écran de sites web scriptées. Les exemples ci-dessous partent d'une capture de cinq lignes pour aboutir à un programme réutilisable qui lit les URL depuis un fichier, traite les pages en parallèle et écrit un rapport.

La dernière section présente le même lot de travail sous la forme d'une exécution de Temposhot Website Capture sur Mac, sans script à maintenir. Les deux approches produisent des fichiers comparables. Le choix dépend de l'endroit où le travail s'exécute.

Quand Puppeteer est le bon outil

Puppeteer convient lorsque les captures font partie du code que vous exécutez déjà :

  • un service Node.js qui génère des aperçus ou des images de partage
  • un job cron ou une étape CI qui capture des pages après un déploiement
  • un job de scraping qui doit aussi conserver un enregistrement visuel
  • une équipe qui utilise déjà des fonctionnalités du Chrome DevTools Protocol

Il convient moins aux tâches ponctuelles réalisées par des personnes qui ne maintiennent pas de projets Node.js.

Liste de six signes indiquant que Puppeteer convient : un projet Node.js existe déjà, les captures s'exécutent selon un planning ou en CI, les fichiers alimentent un autre programme, l'équipe relit les modifications de script comme du code, un serveur exécute le job et la tâche nécessite des étapes de navigateur personnalisées.

Installer Puppeteer pour un script de capture

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

Le package puppeteer télécharge une version compatible de Chrome pendant l'installation. Le package plus léger puppeteer-core ignore ce téléchargement et demande en revanche le chemin d'un navigateur déjà installé. Les scripts ci-dessous utilisent des fichiers .mjs, ce qui permet d'utiliser await au niveau supérieur.

Choisir entre puppeteer et puppeteer-core

Utilisez puppeteer sur un poste de développeur où le téléchargement est autorisé. Utilisez puppeteer-core dans une image CI où Chrome est déjà installé, ou sur un réseau qui bloque le téléchargement du navigateur. L'API est identique dans les deux packages, donc le script ne change pas. Seul l'appel de lancement nécessite un executablePath lorsque le navigateur se trouve dans un emplacement personnalisé.

Arborescence du projet site-shots : fichiers de package, scripts one et run, un fichier texte urls et un dossier shots contenant un sous-dossier daté par exécution.

Capturer une capture d'écran d'un site web

// 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 définit la largeur et la hauteur. Ajoutez deviceScaleFactor: 2 au même appel pour obtenir une image à deux fois la densité de pixels, comparable à un écran Retina.

Ce que produisent les réglages

Le script ci-dessus, avec deviceScaleFactor: 2 ajouté, produit une taille de sortie fixe. Les valeurs découlent du viewport et du facteur d'échelle.

Réglages du script à une page : viewport de 1440 par 900 pixels CSS, facteur d'échelle de l'appareil 2, attente jusqu'à networkidle0 avec zéro connexion, format PNG et taille de sortie de 2880 par 1800 pixels.

La sortie fait deux fois la taille du viewport dans chaque direction, car le facteur d'échelle multiplie les pixels tandis que la taille en CSS reste la même. Un viewport de 1440 x 900 à l'échelle 1 produit une image de 1440 x 900, ce qui convient à un aperçu web. Le facteur d'échelle sert à obtenir une image nette sur un écran à haute densité, et il double la taille du fichier en conséquence.

Capturer une capture d'écran pleine page

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

Avec fullPage: true, l'image couvre l'intégralité du document défilable. Pour un fichier plus léger, enregistrez en JPEG ou en WebP :

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

quality accepte des valeurs de 0 à 100 et s'applique uniquement à JPEG et WebP. Une capture pleine page d'une longue page peut atteindre plusieurs dizaines de milliers de pixels de hauteur, si bien que le JPEG permet souvent de maintenir une taille de fichier raisonnable.

Taille d'une longue page

La largeur reste celle du viewport, et la hauteur suit celle du document. Un long article rend l'image très haute. Les chiffres ci-dessous montrent l'ampleur de cette différence.

Quatre statistiques pour une capture pleine page d'un long article de 1440 pixels de large : 12000 pixels de haut, 17,3 millions de pixels, environ 2,1 fois la surface d'une image 4K et un réglage JPEG de qualité 80.

Une image de 3840 x 2160 compte environ 8,3 millions de pixels, donc l'image d'exemple fait à peu près le double d'une image 4K. Une image très haute se consulte difficilement d'un seul tenant. Découpez les pages très longues en sections avec clip lorsque l'image doit être affichée à l'écran ou dans un document.

Capturer une section

Utilisez l'option clip pour enregistrer une seule zone. Les coordonnées sont exprimées en pixels CSS depuis le haut de la page, et non depuis le viewport :

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

Utilisez soit fullPage, soit clip dans un même appel. Pour découper une longue page en plusieurs fichiers, lisez la hauteur avec document.body.scrollHeight, puis prenez une zone clip par tranche. Une page de 12000 pixels découpée en tranches de 900 pixels donne 14 fichiers, et le dernier ne contient que 300 pixels.

Créer un lanceur d'URL réutilisable

// 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();
  }
}

Une nouvelle page par URL signifie qu'un plantage sur un site n'affecte pas le suivant. Le dossier de sortie daté conserve intacts les résultats des exécutions précédentes.

Le lanceur comporte cinq étapes. La figure ci-dessous les liste dans l'ordre, avec le fichier ou le processus concerné par chacune.

Schéma de cinq cases : lire urls.txt, créer le dossier daté, lancer un seul navigateur, capturer chaque URL sur sa propre page, puis écrire report.json avec chaque résultat.

Nettoyer la liste d'URL

Les lignes vides, les commentaires et les URL en double consomment du temps de navigateur, et un doublon produit un second fichier pour la même page. La version ci-dessous ignore les lignes commençant par un dièse, supprime les doublons exacts et écarte tout ce qui n'est pas une adresse HTTP ou HTTPS. raw contient le contenu du fichier lu à l'étape précédente.

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 compare les chaînes de caractères à l'identique, donc https://example.com et https://example.com/ restent deux URL distinctes. Journalisez aussi les lignes rejetées. Une faute de frappe comme htps://example.com apparaît alors dans le journal au début de l'exécution, au lieu de provoquer un délai d'expiration 45 secondes plus tard.

Numérotation des grands lots

Le script complète l'index sur trois chiffres, ce qui assure un tri correct jusqu'à 999 fichiers. L'index 1000 devient 1000.jpg, et un tri textuel le place entre 100.jpg et 101.jpg. Complétez plutôt sur la largeur du lot :

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

Un lot de 1 250 URL a une largeur de 4, donc le premier fichier s'appelle 0001.jpg. Calculez cette largeur une seule fois, avant le démarrage des workers.

Ajouter de la concurrence pour les lots plus grands

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();

Chaque worker prend l'URL suivante dans une file partagée. Commencez avec 4 et n'augmentez la limite qu'après avoir vérifié la mémoire, car chaque page ouverte utilise son propre processus de rendu.

Le script ouvre toutes les pages depuis un seul navigateur. Les pages partagent le cache du navigateur et, par défaut, aussi les cookies. Pour un lot de sites publics sans lien entre eux, ce comportement est sans conséquence. Pour une exécution qui ne doit pas transmettre d'état d'un site à l'autre, créez un contexte par URL avec browser.createBrowserContext() et fermez-le après la capture. Chaque contexte consomme de la mémoire, donc ce choix doit être décidé en même temps que la limite de concurrence.

Choisir la limite

La limite fixe le nombre de pages rendues simultanément. Une limite basse maintient la mémoire stable et allonge l'exécution, et une limite haute fait l'inverse. Le tableau ci-dessous présente ce compromis pour un lot de 200 URL, sachant que chaque page prend en moyenne environ 6 secondes.

Comparaison des limites 1 et 10 pour 200 URL à environ 6 secondes par page : une page à la fois prend environ 20 minutes, et dix pages à la fois prennent environ 2 minutes, plus le coût mémoire de dix processus de rendu.

Les durées idéales supposent aucune attente réseau et aucun échec. Les sites réels varient, et les délais d'expiration et les nouvelles tentatives ajoutent du temps. Mesurez un lot de 20 URL à deux limites sur la machine cible, puis retenez la limite la plus haute qui maintient le Mac réactif.

Capturer des captures d'écran mobiles

Puppeteer fournit des descripteurs d'appareils via 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 définit en un seul appel le viewport, le ratio de pixels, la prise en charge tactile et le user agent. Pour une simple largeur mobile sans modification du user agent, appelez setViewport avec isMobile: true et hasTouch: true.

Comparaison de deux configurations mobiles : emulate avec un descripteur d'appareil modifie le viewport, le ratio de pixels, la prise en charge tactile et le user agent, tandis que setViewport avec isMobile ne modifie que le viewport et le comportement tactile.

Utilisez emulate lorsqu'un site renvoie un balisage différent selon le user agent, et setViewport lorsque seule la largeur de mise en page compte. Les deux appels s'appliquent à la page sur laquelle ils sont exécutés, donc une seconde page ouverte plus tard nécessite son propre appel.

Un lot qui mélange bureau et mobile nécessite un viewport par ensemble d'images, et non par script. Gardez les images mobiles dans un dossier daté distinct, par exemple shots/2026-04-10-mobile, afin que les numéros de fichiers des deux ensembles n'entrent pas en collision. Temposhot Website Capture utilise une taille Mobile de 390 x 844 dans le même but, définie par ligne dans la même exécution.

Vérifier le viewport émulé

Vérifiez la largeur de mise en page dans la page avant la capture. Un mauvais descripteur produit une mise en page bureau dans une image de taille mobile. La valeur ci-dessous indique la largeur et le ratio de pixels vus par la page :

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

Pour le descripteur iPhone 13 dans les versions récentes de Puppeteer, la largeur doit être de 390. Le ratio de pixels provient également du descripteur. Vérifiez les valeurs dans la version que vous installez, car les données des descripteurs changent d'une version à l'autre.

Gérer le contenu chargé à la demande

Les images chargées au défilement restent vides dans une capture faite juste après la navigation. Faites défiler la page au préalable :

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);
});

L'entrée sur le chargement différé explique ce schéma.

Durée du défilement

La boucle attend 200 millisecondes à chaque étape, et chaque étape avance d'une hauteur de viewport. L'exemple ci-dessous porte sur une page de 8000 pixels avec un viewport de 900 pixels.

Chronologie du passage de défilement sur une page de 8000 pixels : défilement à 0 à 0,0 seconde, 900 pixels à 0,2 seconde, 7200 pixels à 1,6 seconde, et retour en haut à 1,8 seconde.

La page compte neuf étapes, donc le passage ajoute 1,8 seconde avant la capture d'écran. Une page qui charge lentement ses images nécessite une pause plus longue par étape, et une page à défilement infini n'atteint jamais de fin fixe. Pour un défilement infini, arrêtez-vous après un nombre fixe d'étapes plutôt qu'à la hauteur du document.

Défiler dans un conteneur

Certaines mises en page font défiler un élément interne au lieu de la fenêtre. La boucle ci-dessus ne détecte alors aucun mouvement, et la partie basse de la page reste vide. Faites défiler l'élément via son scrollTop, en utilisant son propre scrollHeight et clientHeight comme limites. Après une exécution, comparez la première et la dernière image. Deux images identiques signifient que la page n'a pas défilé, ce qui indique un conteneur.

Choisir la bonne stratégie d'attente

OptionRetourne lorsque
loadL'événement load se déclenche. C'est la valeur par défaut.
domcontentloadedLe HTML est analysé.
networkidle0Aucune connexion réseau pendant au moins 500 ms.
networkidle2Au plus 2 connexions pendant au moins 500 ms.

networkidle0 peut expirer sur les pages qui interrogent le serveur ou diffusent un flux. networkidle2 tolère ce trafic de fond. Lorsqu'une page dispose d'un signal de disponibilité clair, page.waitForSelector sur cet élément est le choix le plus fiable. Le délai de navigation par défaut est de 30 secondes.

Liste de signaux de disponibilité pour une page de tableau de bord : le conteneur du graphique principal est présent, le spinner de chargement a disparu, la dernière ligne de données est visible, les polices web sont chargées et la bannière de consentement est fermée.

Choisissez un seul signal que la page ne définit qu'une fois son contenu prêt. Un sélecteur présent à chaque chargement, comme l'en-tête, ne prouve rien sur les données situées en dessous.

Mesurer avant de choisir une attente

Mesurez la navigation pour chaque URL avant de choisir une stratégie d'attente. La valeur ci-dessous correspond au temps écoulé jusqu'au déclenchement de l'événement load :

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

Écrivez loadMs dans le rapport à côté de chaque URL. Si la plupart des pages se chargent en quelques secondes, l'attente par défaut convient. Si un groupe de pages s'approche du délai d'expiration, passez ces URL à domcontentloaded et attendez un sélecteur, puis conservez le rapport pour vérifier le changement.

Ajouter des nouvelles tentatives et un rapport

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

Le rapport liste chaque URL avec son chemin de fichier ou son erreur. Réinjectez les entrées en échec dans urls.txt pour une seconde passe.

Construire la liste de nouvelles tentatives à partir du rapport

Le rapport transforme la seconde passe en simple filtre, sans copie manuelle. Cette commande jq écrit les URL en échec dans un nouveau fichier :

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

Pointez le script vers urls-retry.txt pour la seconde passe. Le script nomme le dossier de sortie d'après la date, donc une seconde exécution le même jour écrit dans le même dossier. Les fichiers portant les mêmes numéros écrasent alors les images de la première exécution. Ajoutez un suffixe comme -retry à outDir avant la seconde passe, afin que les deux exécutions restent dans le dossier.

Durée maximale d'exécution

Un site lent peut consommer toutes les nouvelles tentatives. Le délai d'expiration et le nombre de tentatives fixent le pire cas pour une URL, et la limite répartit ce coût entre les workers. La figure ci-dessous utilise les valeurs du script.

Quatre statistiques pour le pire cas : 3 tentatives par URL, 45 secondes par tentative, 135 secondes par URL lorsque chaque tentative expire, et environ 56 minutes pour 100 URL avec 4 workers.

Le pire cas est peu probable sur un lot sain, mais il fixe un plafond. Planifiez le job de sorte qu'une exécution avec de nombreux délais d'expiration se termine avant le démarrage de l'exécution suivante.

Relancer uniquement les erreurs susceptibles de changer

Un délai de navigation ou une connexion interrompue peut réussir à la deuxième tentative. Une page qui se charge entièrement mais ne contient pas le sélecteur attendu échoue généralement de la même façon, de même qu'une page qui renvoie un statut 404. Relancez le premier groupe et consignez le second une seule fois. La fonction shootWithRetry ci-dessus relance toutes les erreurs, donc un échec persistant coûte trois délais d'expiration complets avant d'apparaître dans le rapport.

Une structure de dossiers pratique

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

Un dossier par date d'exécution, un rapport par dossier. Cette structure suffit pour comparer les exécutions plus tard, sans base de données.

Erreurs courantes

  1. Utiliser networkidle0 sur chaque site. Les pages avec des outils d'analyse ou des widgets de chat ne se stabilisent jamais.
  2. Laisser des pages ouvertes. La mémoire augmente jusqu'à ce que le processus ralentisse ou plante.
  3. Traiter trop de pages en même temps. Une limite de 20 sur un portable provoque souvent plus de délais d'expiration, et non des exécutions plus rapides.
  4. Capturer les superpositions de consentement. Cliquez sur le bouton de refus par sélecteur ou masquez la bannière avec page.addStyleTag.
  5. Ignorer les conditions d'utilisation des sites. Une capture automatisée envoie de vraies requêtes. Vérifiez les conditions de chaque site et limitez le débit.

Dépannage par symptôme

SymptômeCause probableCorrection
Zone vide dans une image pleine pageLe contenu chargé à la demande n'a jamais été amené à l'écranLancez le passage de défilement avant la capture
Délai d'expiration sur gotoLa page n'atteint jamais l'événement d'attenteAttendez un sélecteur, ou passez à domcontentloaded
La même image pour toutes les URLLa capture a eu lieu avant la fin de la navigationAttendez goto sur chaque page et ouvrez une nouvelle page par URL
Image deux fois plus grande que prévudeviceScaleFactor vaut 2Supprimez le facteur ou fixez-le à 1
La mémoire augmente pendant une longue exécutionLes pages restent ouvertes après la captureFermez chaque page dans un bloc finally et limitez la concurrence
Bannière de consentement dans l'imageLa bannière n'a pas été géréeCliquez sur le bouton de refus par sélecteur ou masquez la bannière
Liste à faire et à éviter pour un script de capture : fermer chaque page, limiter la concurrence, attendre un signal de disponibilité et conserver un rapport ; ne pas utiliser networkidle0 partout et ne pas réutiliser un dossier entre les exécutions.

Alternatives à un script de capture Puppeteer

  • Playwright propose une API similaire et pilote également WebKit. Voir Comment automatiser les captures d'écran de sites web avec Playwright.
  • Les API de capture hébergées exécutent le navigateur à votre place et renvoient les images via HTTP.
  • Les extensions de navigateur, comme l'extension Temposhot, enregistrent une capture PNG pleine page de l'onglet actif.
  • Temposhot Website Capture exécute une liste d'URL collée sur un Mac sans code, avec les tailles Desktop 1920×1080, Tablet 768×1024 ou Mobile 390×844 et un délai de 0 à 60 s par ligne.

Quand le script ne vaut pas la peine

Un script coûte plus cher avec le temps que sa première version ne le laisse croire. Chaque modification du site, mise à jour de Node.js ou mise à jour de Chrome peut nécessiter une correction. Un job mensuel portant sur une liste qui change souvent coûte moins cher dans Website Capture, où la liste d'URL et les réglages de chaque ligne se trouvent dans une seule fenêtre. Conservez le script lorsque ses images alimentent une étape de build, lorsqu'un pipeline CI doit l'exécuter, ou lorsque les étapes vont au-delà d'une visite et d'une capture.

Le même lot dans Temposhot Website Capture

Temposhot Website Capture couvre le lot décrit dans cet article sans script. Les réglages ci-dessous correspondent au lanceur pour la capture pleine page 1440 x 900, avec les options d'attente et de blocage que Temposhot expose par ligne.

Réglages d'un lot Temposhot Website Capture : appareil Desktop, zone Full page, attente Network idle, délai de 2 secondes, Reject banners pour les cookies, Block ads and trackers activé, JPEG qualité 80 et 4 navigateurs simultanés.

La taille de l'appareil diffère volontairement du script : Desktop vaut 1920 x 1080 dans Temposhot, tandis que le script utilise 1440 x 900. Définissez le même viewport dans les deux si les sorties doivent correspondre. Une exécution Temposhot se termine ensuite par ZIP, Images ou PDF dans la barre des résultats, qui exporte les images sélectionnées.

Cinq étapes pour exécuter le lot d'URL dans Temposhot Website Capture : coller la liste avec Bulk insert, définir les réglages d'exécution, démarrer la capture, relancer les lignes en échec et exporter les résultats en ZIP.

Chaque ligne affiche son état pendant l'exécution, par exemple Capturing ou Capture failed. Une ligne en échec peut être relancée seule, sans redémarrer le reste du lot.

Comparaison des états de ligne : Capture pending attend un emplacement de navigateur libre, Capturing charge la page, Capture complete signifie que la capture a été enregistrée, et Capture failed signifie qu'aucune capture n'a été produite.

FAQ

Puppeteer fonctionne-t-il avec Firefox ?

Oui. Les versions récentes peuvent lancer Firefox ainsi que Chrome. Chrome reste l'option la plus utilisée.

Puppeteer peut-il enregistrer des captures WebP ?

Oui. Définissez type: 'webp' dans les options de capture. La valeur quality s'applique au WebP comme au JPEG.

Pourquoi page.goto expire-t-il sur certains sites ?

La page n'a pas atteint l'événement d'attente choisi dans les 30 secondes. Passez à networkidle2 ou load, augmentez timeout, ou attendez plutôt un sélecteur.

Pourquoi une partie de ma capture pleine page est-elle vide ?

Le contenu se charge lorsqu'il entre dans le champ de vision lors du défilement. Lancez le passage de défilement de la section sur le chargement différé avant la capture, et attendez l'apparition de la dernière ligne.

Combien d'URL une exécution peut-elle traiter ?

La limite dépend de la mémoire et du temps, et non du code. Mesurez un lot de 20 URL à la concurrence prévue, surveillez la mémoire, puis adaptez. Temposhot Website Capture permet de régler Concurrent browsers de 1 à 10, avec 4 par défaut.

Les captures d'écran doivent-elles aller dans Git ?

Non. Les images et le rapport sont des sorties de build qui grossissent à chaque exécution. Conservez urls.txt et le script dans le contrôle de version, et stockez le dossier de sortie là où sa taille convient.

Références

Besoin d'une automatisation de captures d'écran sans code ?

Temposhot Website Capture exécute le même type de lot d'URL localement sur un Mac, avec des réglages par ligne et sans script à maintenir. Voir automatisation des captures d'écran de sites web ou le guide des options de capture.

puppeteerwebsite-captureautomationnodejs

Termes utilisés ici : full page screenshot, headless browser, playwright, puppeteer, screenshot api, screenshot automation, viewport screenshot

Transformez vos captures d'écran répétitives en résultats prêts à l'emploi

Temposhot capture l'écran à intervalles réguliers ou à chaque clic et exporte le résultat au format PDF, image, ZIP ou MP4.

Articles connexes