Retour au blog
Guides
Gabriel CiociLast updated on May 1, 202619 min read

Comment faire du Web Scrape avec Puppeteer et NodeJS 2026 Guide

Comment faire du Web Scrape avec Puppeteer et NodeJS 2026 Guide
En bref : Puppeteer vous offre un contrôle total sur une instance de Chrome sans interface graphique depuis Node.js, ce qui en fait l'outil incontournable pour le scraping de pages rendues en JavaScript. Ce guide vous explique pas à pas l'installation, l'extraction à l'aide de sélecteurs, le défilement infini, la connexion via des formulaires, l'interception de requêtes, les plugins de dissimulation, l'exportation de données structurées et le déploiement avec Docker, afin que vous puissiez passer d'un simple script d'essai à un scraper prêt pour la production.

Le web scraping consiste à extraire des données de sites web par programmation. Lorsque ces sites s'appuient sur du JavaScript côté client pour afficher leur contenu, une simple requête HTTP ne suffit pas. Vous avez besoin d'un véritable navigateur, ou au moins d'un outil qui s'y ressemble. C'est exactement le problème que Puppeteer a été conçu pour résoudre.

Puppeteer est une bibliothèque Node.js qui vous permet de faire du web scraping avec Puppeteer et NodeJS en pilotant une instance Chrome sans interface graphique (ou avec interface graphique) via le protocole Chrome DevTools. Elle peut cliquer sur des boutons, remplir des formulaires, faire défiler des pages et évaluer du code JavaScript arbitraire dans le contexte de la page, puis renvoyer les résultats à votre script. Pour les développeurs déjà à l'aise avec JavaScript, c'est l'une des voies les plus naturelles pour aborder les workflows de scraping avec un navigateur sans interface graphique.

Dans ce tutoriel, vous apprendrez à configurer un projet Puppeteer à partir de zéro, à extraire des données de pages statiques et dynamiques, à gérer la pagination et le défilement infini, à intercepter les appels API cachés, à éviter la détection des bots, à exporter vos résultats au format JSON et CSV, et à déployer l'ensemble dans un conteneur Docker. Tous les exemples de code ciblent Node.js 18 ou une version ultérieure, et nous faisons référence à l'interface API de Puppeteer v24 tout au long du guide. Que vous développiez un outil de suivi des prix, un pipeline de génération de prospects ou un outil de recherche universitaire, les modèles présentés dans ce guide vous permettront de passer plus rapidement en production.

Comment fonctionne Puppeteer en coulisses

Lorsque vous appelez puppeteer.launch(), la bibliothèque lance un processus Chromium (ou Chrome) et s’y connecte via le protocole Chrome DevTools (CDP). Le CDP est une interface basée sur WebSocket qui expose presque toutes les capacités du navigateur : inspection du DOM, surveillance du réseau, simulation d’entrée, et plus encore. Votre script Node.js envoie des commandes via ce socket, et Chromium répond avec les résultats.

Cette architecture signifie que Puppeteer n'est pas un simple simulateur de navigateur. Il exécute du vrai JavaScript V8, un véritable moteur de rendu et une véritable pile réseau. Les pages qui dépendent de fetch, aux Web Workers ou au Shadow DOM se comportent exactement comme elles le feraient dans le navigateur d'un utilisateur. C'est ce qui en fait un choix si fiable lorsque vous souhaitez effectuer du web scraping avec Puppeteer et NodeJS sur des sites qui affichent du contenu de manière dynamique.

Puppeteer prend en charge à la fois le mode headless (pas de fenêtre visible, plus rapide, idéal pour les serveurs) et le mode headful (une fenêtre de navigateur visible, utile pour le débogage). Par défaut, les versions récentes de Puppeteer sont livrées avec un binaire Chromium intégré, vous n’avez donc pas besoin d’installer un navigateur séparément. Si vous souhaitez comprendre plus en détail ce qu’est un navigateur headless, il existe d’excellentes ressources qui expliquent l’architecture et les cas d’utilisation courants.

Configuration de votre projet Node.js et installation de Puppeteer

Avant d'écrire le moindre code de scraping, vérifiez que Node.js 18 ou une version supérieure est bien installé. À l'heure où nous écrivons ces lignes, Puppeteer v24 nécessite au minimum Node.js 18.0.

node --version   # should print v18.x or higher
mkdir puppeteer-scraper && cd puppeteer-scraper
npm init -y
npm install puppeteer

L'exécution de npm install puppeteer télécharge la bibliothèque ainsi qu'un binaire Chromium compatible (environ 170 Mo). Si vous gérez déjà votre propre installation de Chrome ou si vous souhaitez une installation plus légère, vous pouvez utiliser puppeteer-core à la place, ce qui évite le téléchargement du navigateur intégré. C'est courant dans les environnements Docker et CI où vous installez Chromium via le gestionnaire de paquets du système.

Votre dossier de projet devrait désormais contenir un node_modules répertoire et un fichier package.json fichier dans lequel Puppeteer est répertorié comme dépendance. Créez un fichier nommé scraper.js (ou scraper.mjs si vous préférez les modules ES) et vous êtes prêt à créer votre premier projet Puppeteer de scraping web en Node.js.

Une petite remarque : l'équipe Puppeteer met à jour le Chromium intégré à chaque nouvelle version, donc le fait de fixer une version spécifique (par exemple npm install puppeteer@24.26.1) permet de garantir la reproductibilité de vos builds CI dans tous les environnements.

Votre premier scraper : lancement, navigation et extraction HTML

La cible de départ classique pour le web scraping avec Puppeteer est Quotes to Scrape, un site sandbox spécialement conçu pour s'entraîner aux techniques d'extraction.

const puppeteer = require('puppeteer');

(async () => {
  const browser = await puppeteer.launch({ headless: true });
  const page = await browser.newPage();
  await page.goto('https://quotes.toscrape.com', {
    waitUntil: 'domcontentloaded',
  });

  const html = await page.content();
  console.log(html.substring(0, 500));

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

Voici comment cela se passe étape par étape :

  1. puppeteer.launch() lance un processus Chromium sans interface graphique.
  2. browser.newPage() ouvre un onglet vide.
  3. page.goto() navigue vers l'URL cible. L' waitUntil option indique à Puppeteer quand considérer la navigation comme terminée. L'utilisation de domcontentloaded est plus rapide que networkidle0 mais peut passer à côté du contenu chargé de manière différée.
  4. page.content() renvoie le code HTML entièrement rendu de la page.
  5. browser.close() ferme le processus du navigateur et libère les ressources.

Ce squelette constitue la base de tous les scrapers Puppeteer que vous allez créer. Le schéma reste le même : lancement, navigation, extraction, fermeture. Ce qui change, c'est la logique d'extraction au milieu, que nous allons développer dans les sections suivantes.

Exécutez le script avec node scraper.js et vous devriez voir le code HTML brut s'afficher dans votre terminal. Si vous obtenez des erreurs concernant des bibliothèques partagées manquantes sous Linux, passez directement à la section sur le déploiement pour trouver la solution.

Pour une référence complète des méthodes de navigateur et de page, la documentation officielle de l'API Puppeteer est la source la plus fiable.

Attente du contenu dynamique et analyse des éléments

Les pages statiques sont le cas le plus simple. Les sites web dynamiques chargent le contenu après la réponse HTML initiale, parfois via des appels XHR, parfois via des frameworks de rendu côté client. Puppeteer propose plusieurs stratégies d'attente pour gérer cela lorsque vous effectuez du web scraping avec Puppeteer et NodeJS sur des applications monopages modernes.

L'approche la plus fiable est page.waitForSelector(), qui met l'exécution en pause jusqu'à ce qu'un sélecteur CSS spécifique apparaisse dans le DOM :

await page.goto('https://quotes.toscrape.com');
await page.waitForSelector('.quote');

Une fois les éléments présents, utilisez page.evaluate() pour exécuter du JavaScript dans le contexte du navigateur et récupérer les données vers Node.js :

const quotes = await page.evaluate(() => {
  const items = document.querySelectorAll('.quote');
  return Array.from(items).map(item => ({
    text: item.querySelector('.text').innerText,
    author: item.querySelector('.author').innerText,
    tags: Array.from(item.querySelectorAll('.tag')).map(t => t.innerText),
  }));
});

console.log(quotes);

Quelques points à noter concernant page.evaluate():

  • Le callback s'exécute dans le navigateur, et non dans Node.js. Vous ne pouvez pas y faire référence à des variables ou modules Node.js.
  • La valeur de retour doit être sérialisable (objets simples, tableaux, chaînes de caractères, nombres). Vous ne pouvez pas renvoyer directement des éléments DOM.
  • Si un sélecteur ne correspond à rien, querySelector renvoie null, ce qui provoquera une exception lorsque vous tenterez de lire .innerText. En encapsulant l'accès dans un chaînage optionnel (?.) ou un contrôle de null permet d'éviter les plantages silencieux en production.

Pour les pages qui chargent du contenu selon un délai plutôt qu’à la suite d’un événement DOM, page.waitForTimeout() fonctionne comme solution de secours, mais privilégiez les attentes basées sur des sélecteurs dans la mesure du possible, car elles sont plus rapides et plus déterministes. Si vous hésitez entre une bibliothèque d'automatisation complète du navigateur et un parseur plus léger, les guides comparant Cheerio et Puppeteer peuvent vous aider à choisir l'outil le mieux adapté à votre tâche.

Scraping des modèles dynamiques courants

La plupart des cibles de scraping réelles ne fournissent pas toutes leurs données lors d’un seul chargement de page. Vous rencontrerez de la pagination, du défilement infini, des pages de connexion et d’autres modèles interactifs. Vous trouverez ci-dessous les trois modèles les plus courants que vous devrez gérer lorsque vous effectuez du scraping Web avec Puppeteer et NodeJS sur des sites Web en production.

Contenu paginé et exploration multipages

La pagination est le modèle que vous rencontrerez le plus souvent. La stratégie est simple : extraire les données de la page actuelle, trouver le lien « Suivant », y accéder, et répéter l'opération jusqu'à ce qu'il n'y ait plus de pages.

let currentPage = 1;
const allQuotes = [];

while (true) {
  await page.waitForSelector('.quote');
  const pageQuotes = await page.evaluate(() =>
    Array.from(document.querySelectorAll('.quote')).map(q => ({
      text: q.querySelector('.text').innerText,
      author: q.querySelector('.author').innerText,
    }))
  );
  allQuotes.push(...pageQuotes);

  const nextButton = await page.$('li.next > a');
  if (!nextButton) break;

  await Promise.all([
    page.waitForNavigation({ waitUntil: 'domcontentloaded' }),
    nextButton.click(),
  ]);
  currentPage++;
}

console.log(`Scraped ${allQuotes.length} quotes across ${currentPage} pages.`);

Le détail essentiel consiste à encapsuler click() et waitForNavigation() à l'intérieur Promise.all. Si vous cliquez d'abord puis attendez, Puppeteer risque de manquer l'événement de navigation car celui-ci s'est déjà déclenché. Cette protection contre les conditions de concurrence est essentielle pour un crawling multipages fiable.

L'ajout d'une logique de réessai rend ce modèle prêt pour la production. Encadrez la navigation dans un try/catch, définissez un délai d'expiration sur waitForNavigation, et réessayez la page jusqu'à trois fois avant de consigner l'échec et de passer à la suivante. C'est ce type de gestion des erreurs qui distingue les exemples de scraping avec Puppeteer présentés dans les articles de blog des scrapers qui tournent sans surveillance toute la nuit.

Pages à défilement infini

Le défilement infini remplace la pagination par un déclencheur « charger plus » activé en faisant défiler la page jusqu'en bas. Les flux des réseaux sociaux et les pages de listes de produits utilisent couramment ce modèle. Pour scraper un site web dynamique avec Puppeteer, vous faites défiler la page par programmation et attendez que du nouveau contenu apparaisse.

async function autoScroll(page, maxScrolls = 10) {
  let previousHeight = 0;
  let scrollCount = 0;

  while (scrollCount < maxScrolls) {
    previousHeight = await page.evaluate(() => document.body.scrollHeight);
    await page.evaluate(() => window.scrollTo(0, document.body.scrollHeight));
    await new Promise(r => setTimeout(r, 1500));

    const newHeight = await page.evaluate(() => document.body.scrollHeight);
    if (newHeight === previousHeight) break;
    scrollCount++;
  }
}

La fonction compare scrollHeight avant et après chaque défilement. Lorsque la hauteur cesse de changer, soit tout le contenu a été chargé, soit il faut cliquer sur un bouton « Afficher plus ». Ajoutez une maxScrolls limite pour éviter les boucles infinies sur les pages dont les flux sont véritablement sans fin. Vous pouvez également suivre le nombre d'éléments sur la page (via querySelectorAll) comme signal de fin secondaire, ce qui permet de détecter les cas où du nouveau contenu se charge sans modifier la hauteur globale de la page.

Cliquer sur des boutons, remplir des formulaires et se connecter

Le scraping derrière un mur de connexion nécessite une interaction avec les formulaires. La fonction page.type() simule la saisie caractère par caractère, et page.click() déclenche de véritables événements de souris, ce qui est important car certains sites surveillent les événements d'entrée plutôt que de simplement vérifier les valeurs des champs.

await page.goto('https://quotes.toscrape.com/login');
await page.type('#username', 'testuser');
await page.type('#password', 'testpass');
await Promise.all([
  page.waitForNavigation(),
  page.click('input[type="submit"]'),
]);

Une fois connecté, la session du navigateur conserve automatiquement les cookies pour la navigation suivante. Vous pouvez continuer à accéder aux pages authentifiées sans avoir à saisir à nouveau vos identifiants pendant cette session. Si le site affiche d'abord une bannière de consentement aux cookies, cliquez sur le bouton « Accepter » avant d'interagir avec le formulaire de connexion.

Pour les workflows de formulaire plus complexes (assistants en plusieurs étapes, téléchargements de fichiers, sélections dans des menus déroulants), Puppeteer propose des méthodes telles que page.select() pour <select> les éléments et elementHandle.uploadFile() pour les entrées de fichiers. Vous pouvez découvrir la soumission de formulaires avec Puppeteer dans des guides dédiés qui traitent de ces interactions avancées.

Interception des requêtes réseau et capture des API cachées

Voici une technique que la plupart des tutoriels sur le web scraping avec Puppeteer ignorent complètement : au lieu d'analyser le DOM, interceptez les requêtes réseau effectuées par la page et récupérez les charges utiles JSON structurées directement à partir des appels API du site lui-même.

De nombreux sites web modernes récupèrent leurs données via des requêtes XHR ou Fetch et les affichent côté client. Si vous parvenez à capturer ces données, vous évitez complètement la complexité des sélecteurs CSS.

await page.setRequestInterception(true);

page.on('response', async (response) => {
  const url = response.url();
  if (url.includes('/api/products') && response.status() === 200) {
    try {
      const data = await response.json();
      console.log('Captured API response:', data);
    } catch (e) {
      // Not a JSON response, skip
    }
  }
});

page.on('request', (request) => {
  const blocked = ['image', 'font', 'stylesheet'];
  if (blocked.includes(request.resourceType())) {
    request.abort();
  } else {
    request.continue();
  }
});

await page.goto('https://example-spa.com');

Cette approche est puissante pour deux raisons. Premièrement, la réponse est déjà au format JSON structuré, vous n'avez donc pas besoin d'écrire de sélecteurs. Deuxièmement, elle tend à être plus stable au fil du temps, car les contrats API changent moins fréquemment que le balisage de l'interface utilisateur.

Pour découvrir quels points de terminaison une page appelle, ouvrez l'onglet Réseau des DevTools de votre navigateur sur le site cible, filtrez par « Fetch/XHR » et recherchez les réponses contenant les données dont vous avez besoin. Filtrez ensuite ces modèles d'URL dans votre gestionnaire d'interception. Cette technique de collecte d'API cachées est l'un des atouts les plus marquants que vous pouvez ajouter à votre boîte à outils de scraping Puppeteer Node.js. Elle vous permet de scraper le Web avec Puppeteer et Node.js plus efficacement en évitant complètement l'analyse du DOM pour les pages basées sur des API.

Optimisation des performances et scraping parallèle

Une seule page Puppeteer traite les requêtes de manière séquentielle. Lorsque vous devez extraire des données de milliers d'URL, cette approche séquentielle devient un goulot d'étranglement. Voici les deux optimisations les plus efficaces pour faire évoluer votre workflow de scraping web Node.js avec Puppeteer.

Bloquez les ressources inutiles. Les images, les polices, les feuilles de style et les fichiers multimédias consomment de la bande passante et ralentissent le chargement des pages sans apporter de données exploitables. La désactivation du chargement des images et des vidéos est l’un des moyens les plus efficaces d’accélérer les scrapers Puppeteer, et cela n’entraîne aucune perte de données puisque ces ressources restent accessibles dans le balisage DOM. Utilisez l’interception de requêtes pour interrompre ces types de ressources (comme indiqué dans la section précédente). Ce simple changement peut réduire de moitié les temps de chargement des pages sur les sites riches en contenu multimédia.

Exécutez plusieurs pages simultanément. Puppeteer est asynchrone par nature, et Node.js gère bien la concurrence grâce à Promise.all. Au lieu de traiter les URL une par une, ouvrez plusieurs pages et extrayez-les en parallèle :

const urls = ['https://example.com/1', 'https://example.com/2', 'https://example.com/3'];
const browser = await puppeteer.launch({ headless: true });

const scrape = async (url) => {
  const page = await browser.newPage();
  try {
    await page.goto(url, { waitUntil: 'domcontentloaded', timeout: 15000 });
    const title = await page.evaluate(() => document.title);
    return { url, title };
  } catch (err) {
    return { url, error: err.message };
  } finally {
    await page.close();
  }
};

const results = await Promise.all(urls.map(scrape));
console.log(results);

Remarquez le try/catch/finally . En production, il arrive parfois que des pages individuelles expirent ou échouent. En encapsulant chaque tâche, vous vous assurez qu'une URL défectueuse ne plante pas l'ensemble du lot. Le finally bloc garantit la fermeture de la page même en cas d'erreur, ce qui évite les fuites de mémoire.

Une limite pratique de concurrence est de 5 à 10 pages par instance de navigateur, en fonction de la mémoire vive de votre machine. Au-delà, envisagez de lancer plusieurs instances de navigateur ou de regrouper les URL en lots séquentiels. Chaque page Chromium consomme environ 30 à 80 Mo de mémoire, et cela s'accumule rapidement lorsque vous exécutez des dizaines d'onglets simultanés. Pour les tâches à très grande échelle, vous pouvez envisager de passer à un cloud de navigateurs géré plutôt que d'héberger Chrome localement.

Éviter la détection des bots : proxys et plugins de camouflage

Même si Puppeteer utilise un véritable navigateur, les sites web peuvent toujours détecter le trafic automatisé grâce à l'empreinte digitale JavaScript, à l'analyse des en-têtes et à l'heuristique comportementale. Si vous avez déjà vu un scraper fonctionner correctement pendant 20 requêtes avant de commencer à renvoyer des CAPTCHA, c'est à cause de la détection des bots.

Les plugins de furtivité constituent la première ligne de défense. Le package puppeteer-extra-plugin-stealth corrige plusieurs vecteurs de détection connus : le drapeau navigator.webdriver flag, les tableaux de plugins Chrome, les chaînes du moteur de rendu WebGL, et plus encore. Au moment de la rédaction de cet article, vérifiez que la version du plugin Stealth que vous installez est compatible avec votre version de Puppeteer, car les deux bibliothèques peuvent se désynchroniser après des mises à jour majeures.

const puppeteer = require('puppeteer-extra');
const StealthPlugin = require('puppeteer-extra-plugin-stealth');
puppeteer.use(StealthPlugin());

const browser = await puppeteer.launch({ headless: true });

La rotation des proxys constitue la deuxième couche de protection. En faisant tourner votre adresse IP sortante d'une requête à l'autre, vous compliquez considérablement la tâche des sites qui tentent de corréler et de bloquer votre trafic. Vous pouvez passer un proxy au moment du lancement dans votre configuration de scraping furtif avec Puppeteer :

const browser = await puppeteer.launch({
  args: ['--proxy-server=http://proxy-address:port'],
});

Une limitation à prendre en compte : l'API native de Puppeteer ne prend pas en charge le changement de proxy par requête. Le proxy est défini au niveau du navigateur, donc le modifier nécessite de redémarrer l'instance du navigateur. Pour une rotation de proxy Puppeteer à haut débit, cela devient impraticable sans une couche de gestion de proxy externe ou un pool de proxys résidentiels dédié.

Au-delà des mesures techniques, vous devriez également ajouter des délais raisonnables entre les requêtes et respecter les robots.txt directives. En adoptant un comportement responsable, vous réduisez le risque de voir votre adresse IP bannie et prolongez la durée de fonctionnement de votre scraper. Pour découvrir un ensemble complet de stratégies pratiques, vous pouvez consulter les conseils pour éviter d'être bloqué lors du web scraping.

Exportation des données extraites au format JSON et CSV

L'enregistrement des résultats dans la console convient pour le débogage, mais les scrapers de production ont besoin d'une sortie de fichiers structurée. Node.js simplifie cette tâche grâce au module intégré fs .

Exportation JSON :

const fs = require('fs');
const data = [{ text: 'Example quote', author: 'Author' }];
fs.writeFileSync('quotes.json', JSON.stringify(data, null, 2), 'utf-8');

Exportation CSV :

const header = 'text,author\n';
const rows = data.map(d => `"${d.text}","${d.author}"`).join('\n');
fs.writeFileSync('quotes.csv', header + rows, 'utf-8');

Pour une génération de fichiers CSV plus robuste (gestion des virgules à l'intérieur des valeurs, des caractères spéciaux et des ensembles de données volumineux), envisagez d'utiliser une bibliothèque telle que csv-stringify ou fast-csv. Celles-ci gèrent les cas particuliers, tels que les guillemets intégrés et les champs multilignes, que l'approche simple par littéral de modèle ne prend pas en compte.

Optez pour le format JSON lorsque les consommateurs en aval sont d'autres programmes ou des API. Optez pour le format CSV lorsque les données sont destinées à des feuilles de calcul, à des bases de données avec importation CSV ou à des parties prenantes non techniques qui souhaitent ouvrir le fichier dans Excel. Quel que soit le format choisi, il est essentiel d'écrire les données sur le disque de manière incrémentielle au fur et à mesure que vous effectuez le web scraping avec Puppeteer et NodeJS (plutôt que de tout accumuler en mémoire) pour les tâches de longue durée susceptibles de se bloquer en cours d'exécution.

Déploiement de Puppeteer sur des serveurs et Docker

Les scrapers Puppeteer qui fonctionnent parfaitement sur macOS tombent souvent en panne dès que vous les déployez sur un serveur Linux. Le navigateur Chrome sans interface graphique hérite des paquets du système d'exploitation, et les serveurs Linux ne disposent généralement pas des bibliothèques partagées liées à l'interface graphique dont Chromium a besoin.

Pour les serveurs Debian ou Ubuntu, installez les dépendances manquantes :

apt-get update && apt-get install -y \
  ca-certificates fonts-liberation libasound2 libatk1.0-0 \
  libcups2 libdbus-1-3 libgdk-pixbuf2.0-0 libnspr4 libnss3 \
  libx11-xcb1 libxcomposite1 libxrandr2 xdg-utils

Pour les déploiements Docker, un fichier Dockerfile minimal ressemble à ceci :

FROM node:18-slim
RUN apt-get update && apt-get install -y chromium
ENV PUPPETEER_EXECUTABLE_PATH=/usr/bin/chromium
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
CMD ["node", "scraper.js"]

Deux indicateurs de lancement essentiels pour les environnements conteneurisés :

puppeteer.launch({
  headless: true,
  args: ['--no-sandbox', '--disable-setuid-sandbox'],
});

Sans --no-sandbox, Chromium refusera de démarrer dans la plupart des conteneurs Docker. Ces indicateurs sont sans danger dans un scraper conteneurisé où vous contrôlez les URL d'entrée, mais évitez-les dans les environnements qui traitent du contenu non fiable. L'ajout de votre scraper déployé via Docker à un pipeline CI (GitHub Actions, GitLab CI) est simple une fois que le conteneur est correctement construit et s'exécute. C'est à cette étape de déploiement que de nombreux développeurs se heurtent à des obstacles ; prévoyez donc dès le départ d'effectuer le web scraping avec Puppeteer et NodeJS dans un environnement conteneurisé si vous savez que vous aurez besoin d'un déploiement sur serveur.

Comment effectuer du web scraping avec Puppeteer et NodeJS par rapport à l'utilisation de Playwright

Si vous évaluez des outils de scraping avec un navigateur headless, vous avez probablement également entendu parler de Playwright. Ces deux bibliothèques partagent le même ADN (Playwright a été créé par d'anciens mainteneurs de Puppeteer), mais elles répondent à des besoins différents.

Fonctionnalité

Puppeteer

Playwright

Prise en charge des navigateurs

Chromium, Firefox (expérimental)

Chromium, Firefox, WebKit

SDK de langage

JavaScript/TypeScript

JS/TS, Python, Java, C#

Mécanisme d'attente automatique

Manuel (waitForSelector, waitForNavigation)

Attente automatique intégrée pour la plupart des actions

Plugins communautaires

Vaste écosystème (puppeteer-extra, stealth)

Écosystème de plugins plus restreint

Idéal pour

Le scraping axé sur Chrome, les bases de code JS existantes

Tests multi-navigateurs, équipes polyglottes

Si vos cibles de scraping ne nécessitent que Chromium et que votre équipe écrit déjà en JavaScript, Puppeteer est le choix le plus simple et le plus abouti, avec un écosystème de plugins plus vaste. Playwright excelle lorsque vous avez besoin d'une prise en charge multi-navigateurs ou lorsque vous travaillez dans un langage autre que JavaScript. Pour un aperçu plus complet des options disponibles, vous pouvez consulter d'autres alternatives à Puppeteer afin de trouver l'outil qui correspond le mieux aux exigences de votre projet.

Quelle que soit la bibliothèque que vous choisissez, les concepts fondamentaux abordés dans ce guide (stratégies d'attente, interception des requêtes, mesures de dissimulation, gestion des erreurs) s'appliquent directement à Playwright, avec seulement quelques différences mineures au niveau de l'API.

Points clés

  • Puppeteer pilote un véritable navigateur Chromium via le protocole DevTools, ce qui le rend idéal pour extraire des pages rendues en JavaScript que les clients HTTP simples ne peuvent pas gérer.
  • Utilisez toujours waitForSelector plutôt que des délais d'attente fixes, encapsulez les clics de navigation dans Promise.all, et ajoutez des try/catch des balises autour des opérations sur la page pour créer des scrapers résilients.
  • Interceptez les requêtes réseau pour capturer directement les charges utiles JSON des API cachées, en contournant entièrement les sélecteurs DOM fragiles.
  • Superposez des plugins furtifs et la rotation de proxys pour réduire le risque de détection des bots, et associez-les à des pratiques de scraping respectueuses telles que la limitation de débit et la conformité au fichier robots.txt.
  • Exportez les données structurées au format JSON ou CSV, déployez-les dans Docker avec les indicateurs de sandbox appropriés, et traitez les pages simultanément par lots pour aller au-delà des scripts à URL unique.

FAQ

Pourquoi mon scraper Puppeteer se comporte-t-il différemment lorsqu'il est déployé sur un serveur Linux par rapport à ma machine locale ?

Les serveurs Linux ne disposent généralement pas des bibliothèques partagées liées à l'interface graphique dont Chromium dépend, telles que libx11-xcb, libnss3et les paquets de polices. Installez-les avec apt-get ou utilisez une image de base Docker qui les inclut. De plus, l'exécution sans le --no-sandbox provoquera le plantage de Chrome sur la plupart des hôtes Linux, car le sandboxing du noyau nécessite des autorisations élevées que les conteneurs restreignent généralement.

Comment puis-je conserver les cookies et les données de session entre plusieurs exécutions de scraping Puppeteer ?

Utilisez page.cookies() pour exporter les cookies de la session en cours sous forme de tableau JSON, puis enregistrez-les dans un fichier avec fs.writeFileSync. Lors des exécutions suivantes, chargez le fichier et appelez page.setCookie(...cookies) avant de naviguer vers le site cible. Cela permet de conserver les sessions de connexion, les paramètres de préférences et les jetons CSRF sans avoir à se réauthentifier à chaque exécution.

Est-il légal de scraper des sites web avec Puppeteer, et comment dois-je respecter le fichier robots.txt ?

La légalité varie selon la juridiction et les conditions d'utilisation du site cible. En général, l'exploration de données accessibles au public est autorisée dans de nombreuses régions, mais enfreindre les conditions d'utilisation d'un site peut entraîner des risques juridiques. Vérifiez toujours le fichier robots.txt (généralement à l'adresse https://domain.com/robots.txt) et respectez ses Disallow directives. Ajoutez des délais entre les requêtes et évitez de surcharger les serveurs avec un trafic trop intense.

Comment gérer les CAPTCHA lors du scraping avec Puppeteer ?

Les CAPTCHA sont spécialement conçus pour bloquer l'automatisation. Les plugins de furtivité peuvent retarder leur apparition en masquant les empreintes du navigateur, mais une fois qu'un CAPTCHA est affiché, Puppeteer ne peut pas le résoudre à lui seul. Vous pouvez intégrer des services tiers de résolution de CAPTCHA via leurs API, ou restructurer votre scraper pour réduire les signaux de détection (taux de requêtes plus lents, adresses IP résidentielles, tailles de fenêtre d'affichage aléatoires) afin que les CAPTCHA se déclenchent moins fréquemment.

Conclusion

Puppeteer reste l’un des outils les plus performants pour scraper des sites web dynamiques et riches en JavaScript depuis un environnement Node.js. Tout au long de ce guide, vous avez appris à configurer un projet, à extraire du contenu à l’aide de sélecteurs et page.evaluate(), gérer la pagination et le défilement infini, intercepter les réponses d'API cachées, appliquer des mesures de furtivité, exporter des données structurées et déployer votre scraper dans Docker.

Le principal enseignement à retenir est que passer d’un prototype fonctionnel à un scraper de production nécessite de prêter attention à la gestion des erreurs, à la concurrence et à l’anti-détection, et pas seulement au parcours du DOM. Envelopper les pages dans try/catch, le traitement par lots des requêtes simultanées et la rotation des proxys sont les techniques qui distinguent les scripts qui tombent en panne après 50 requêtes de ceux qui fonctionnent de manière fiable à grande échelle.

Si vous passez plus de temps à lutter contre les blocages, les CAPTCHA et l'infrastructure de proxy qu'à écrire la logique d'extraction, c'est généralement le signe qu'il faut décharger la couche de requêtes. L'API Scraper de WebScrapingAPI gère la rotation des proxys, la gestion des empreintes de navigateur et la résolution des CAPTCHA derrière un seul point de terminaison, ce qui vous permet de conserver votre code d'analyse Puppeteer et de simplement remplacer la couche réseau sans avoir à repenser le reste de votre scraper.

À propos de l'auteur
Gabriel Cioci, Développeur full-stack @ WebScrapingAPI
Gabriel CiociDéveloppeur full-stack

Gabriel Cioci est développeur Full Stack chez WebScrapingAPI, où il se charge de la création et de la maintenance des sites web, du panneau utilisateur et des principaux éléments de la plateforme destinés aux utilisateurs.

Commencez à créer

Prêt à faire évoluer votre système de collecte de données ?

Rejoignez plus de 2 000 entreprises qui utilisent WebScrapingAPI pour extraire des données Web à l'échelle de l'entreprise, sans aucun coût d'infrastructure.