Introduction à Puppeteer : Concepts de Base et Premiers Scripts
Bienvenue dans cette leçon dédiée à Puppeteer, un outil essentiel dans notre parcours pour Maîtriser l'Automatisation de Navigateurs avec Playwright et Puppeteer. Alors que Playwright est notre cadre principal, il est crucial de comprendre et de savoir utiliser Puppeteer, l'un des pionniers et une référence dans le domaine de l'automatisation de navigateurs basés sur Chromium.
1. Qu'est-ce que Puppeteer ?
Puppeteer est une bibliothèque Node.js fournie par Google qui offre une API de haut niveau pour contrôler les navigateurs Chrome ou Chromium via le protocole DevTools. En d'autres termes, il permet de "piloter" un navigateur de manière programmatique.
Pourquoi Puppeteer est-il si puissant et populaire ?
- Automatisation de tests UI : Simuler les interactions utilisateur pour s'assurer que les applications web fonctionnent comme prévu.
- Web Scraping : Collecter des données à partir de pages web, même celles qui chargent du contenu dynamiquement avec JavaScript.
- Génération de PDF et captures d'écran : Transformer des pages web entières en fichiers PDF ou en images.
- Crawling de sites web : Parcourir des liens, naviguer entre les pages pour indexer du contenu.
- Automatisation de tâches répétitives : Remplir des formulaires, se connecter à des sites, télécharger des fichiers, etc.
- Performance monitoring : Analyser le temps de chargement et d'autres métriques de performance.
Puppeteer est particulièrement apprécié pour sa simplicité d'utilisation et sa grande flexibilité. Il est souvent comparé à Selenium, mais il offre une API plus moderne et est directement intégré à l'écosystème Chromium, ce qui le rend potentiellement plus rapide et plus fiable pour ces navigateurs.
Puppeteer vs. Playwright : Une brève distinction
Bien que Playwright soit un outil plus récent et supporte plus de navigateurs (Chromium, Firefox, WebKit) avec une API souvent plus ergonomique pour certains cas d'usage, Puppeteer a pavé la voie et reste une référence. Apprendre Puppeteer nous donne une compréhension fondamentale des concepts d'automatisation de navigateur qui sont transférables à Playwright. De plus, il existe de nombreux projets et ressources existants basés sur Puppeteer.
2. Prérequis et Installation
Avant de plonger dans le code, assurez-vous d'avoir les éléments suivants :
- Node.js (version 14 ou supérieure recommandée) installé sur votre machine.
- Un gestionnaire de paquets comme npm ou yarn.
Installation de Puppeteer
L'installation de Puppeteer est très simple via npm ou yarn. Par défaut, Puppeteer télécharge une version compatible de Chromium lors de son installation.
# Utilisation de npm
npm install puppeteer
# Ou avec yarn
yarn add puppeteer
Note sur puppeteer-core: Si vous souhaitez utiliser une installation de Chrome/Chromium existante sur votre système (par exemple, pour réduire la taille de votre package ou si vous travaillez dans un environnement contraint), vous pouvez installer puppeteer-core à la place. puppeteer-core ne télécharge pas Chromium par défaut.
npm install puppeteer-core
Pour cette leçon, nous utiliserons puppeteer standard qui inclut son propre binaire Chromium.
3. Concepts Fondamentaux de Puppeteer
Comprendre l'architecture de Puppeteer est crucial pour écrire des scripts efficaces. Voici les objets clés avec lesquels vous interagirez :
-
Browser(ouBrowserContext)Représente une instance du navigateur Chromium. C'est le point d'entrée pour toutes les opérations. Un navigateur peut avoir plusieurs contextes de navigateur isolés (similaire aux profils d'invités), et chaque contexte peut avoir plusieurs pages.
- Lancement : On lance un navigateur avec
puppeteer.launch(). - Fermeture : Il est important de fermer le navigateur à la fin de votre script avec
browser.close().
- Lancement : On lance un navigateur avec
-
PageReprésente un onglet ou une page dans le navigateur. C'est l'objet principal avec lequel vous interagirez pour naviguer, cliquer, taper, etc.
- Création : Vous obtenez une page à partir de l'instance du navigateur avec
browser.newPage(). - Navigation : Utilisez
page.goto(url)pour naviguer vers une URL spécifique.
- Création : Vous obtenez une page à partir de l'instance du navigateur avec
-
ElementHandleC'est une référence à un élément DOM sur la page. Vous obtenez un
ElementHandleen utilisant des méthodes commepage.$()oupage.$$(). Avec unElementHandle, vous pouvez interagir directement avec l'élément (cliquer, taper, etc.) ou obtenir ses propriétés. -
SelectorLes sélecteurs sont des chaînes de caractères utilisées pour cibler des éléments spécifiques sur une page web. Puppeteer prend en charge les sélecteurs CSS (comme
.class,#id,div > span) et, dans une certaine mesure, les sélecteurs XPath.page.$('selector'): Sélectionne le premier élément correspondant au sélecteur.page.$$('selector'): Sélectionne tous les éléments correspondant au sélecteur.page.waitForSelector('selector'): Attend qu'un élément correspondant au sélecteur apparaisse sur la page. Très utile pour gérer les chargements asynchrones.
-
Async/AwaitPresque toutes les opérations de Puppeteer sont asynchrones et retournent des Promises. Il est donc essentiel d'utiliser les mots-clés
asyncetawaitpour écrire des scripts Puppeteer de manière synchrone et lisible. Votre fonction principale doit êtreasync. -
Mode Headless vs. Headful
Par défaut, Puppeteer exécute Chromium en mode "headless", c'est-à-dire sans interface utilisateur visible. C'est excellent pour les serveurs ou les exécutions automatisées en arrière-plan. Cependant, pour le débogage ou la démonstration, vous pouvez lancer le navigateur en mode "headful" (avec une interface utilisateur visible) en passant l'option
headless: falseàpuppeteer.launch().
4. Premier Script : Visiter une Page et Prendre une Capture d'Écran
Commençons par un script simple qui lance un navigateur, navigue vers une page web et prend une capture d'écran.
Créez un fichier nommé screenshot.js :
// Importe la bibliothèque Puppeteer
const puppeteer = require('puppeteer');
// Définit une fonction asynchrone pour encapsuler notre logique
async function run() {
// 1. Lancer le navigateur Chromium
// 'headless: true' (par défaut) signifie qu'aucune fenêtre de navigateur ne sera affichée.
// 'headless: false' afficherait une fenêtre de navigateur.
const browser = await puppeteer.launch({ headless: true });
// 2. Ouvrir une nouvelle page (un nouvel onglet) dans le navigateur
const page = await browser.newPage();
// 3. Définir les dimensions de la fenêtre de la page
// Ceci est utile pour garantir des captures d'écran cohérentes.
await page.setViewport({ width: 1280, height: 800 });
// 4. Naviguer vers l'URL spécifiée
// 'waitUntil: 'networkidle2'' attend que le réseau soit inactif (pas plus de 2 requêtes pendant 500ms).
// D'autres options incluent 'load', 'domcontentloaded', 'networkidle0'.
await page.goto('https://www.example.com', { waitUntil: 'networkidle2' });
// 5. Prendre une capture d'écran de la page et l'enregistrer dans un fichier
await page.screenshot({ path: 'example_screenshot.png', fullPage: true });
console.log('Capture d\'écran de https://www.example.com enregistrée sous example_screenshot.png');
// 6. Fermer le navigateur
await browser.close();
}
// Appelle la fonction 'run' et gère les erreurs potentielles
run().catch(console.error);
Explication du code :
const puppeteer = require('puppeteer');: Importe le module Puppeteer.async function run() { ... }: Nous définissons notre logique principale à l'intérieur d'une fonction asynchrone pour pouvoir utiliserawait.const browser = await puppeteer.launch({ headless: true });: Lance une nouvelle instance de Chromium.headless: trueest le comportement par défaut et signifie que le navigateur ne sera pas visible. Changez-le enfalsesi vous voulez voir ce qu'il se passe.const page = await browser.newPage();: Ouvre un nouvel onglet (une nouvellePage) dans l'instance du navigateur.await page.setViewport({ width: 1280, height: 800 });: Définit la taille de la fenêtre d'affichage de la page. C'est important pour les captures d'écran et pour simuler différentes tailles d'écran.await page.goto('https://www.example.com', { waitUntil: 'networkidle2' });: Navigue vers l'URLhttps://www.example.com.waitUntil: 'networkidle2'est une option importante. Elle indique à Puppeteer d'attendre que la page soit considérée comme "chargée" et que le trafic réseau soit minimal avant de continuer. Ceci est crucial pour les pages qui chargent du contenu via JavaScript.
await page.screenshot({ path: 'example_screenshot.png', fullPage: true });: Prend une capture d'écran de la page.pathspécifie le nom du fichier de sortie.fullPage: trueprend une capture d'écran de toute la hauteur de la page, même si elle est plus longue que la fenêtre d'affichage.
await browser.close();: Très important ! Ferme l'instance du navigateur et libère toutes les ressources. Oublier cette étape peut laisser des processus Chromium en cours d'exécution.run().catch(console.error);: Exécute notre fonctionrunet attrape les erreurs potentielles.
Pour exécuter ce script, ouvrez votre terminal dans le répertoire où vous avez sauvegardé screenshot.js et tapez :
node screenshot.js
Vous devriez voir un fichier example_screenshot.png apparaître dans le même répertoire.
5. Interaction de Base : Naviguer, Cliquer, Taper du Texte
Maintenant, allons un peu plus loin en interagissant avec les éléments d'une page : nous allons chercher quelque chose sur un moteur de recherche.
Créez un fichier nommé search.js :
const puppeteer = require('puppeteer');
async function searchWithPuppeteer() {
const browser = await puppeteer.launch({ headless: false, defaultViewport: null }); // 'headless: false' pour voir l'action
const page = await browser.newPage();
try {
// 1. Naviguer vers la page d'accueil de Google
await page.goto('https://www.google.com', { waitUntil: 'networkidle2' });
// 2. Attendre que le champ de recherche soit disponible
// Nous utilisons un sélecteur CSS commun pour le champ de recherche de Google.
const searchInputSelector = 'textarea[name="q"]';
await page.waitForSelector(searchInputSelector);
// 3. Taper du texte dans le champ de recherche
// L'option { delay: 100 } simule une frappe humaine, utile pour certains sites.
await page.type(searchInputSelector, 'Puppeteer tutoriel', { delay: 100 });
// 4. Appuyer sur Entrée pour soumettre le formulaire (ou cliquer sur le bouton de recherche)
// On peut simuler la pression d'une touche...
await page.keyboard.press('Enter');
// ...ou cliquer sur le bouton de recherche si son sélecteur est connu.
// await page.click('input[name="btnK"]'); // Attention, ce sélecteur peut varier et nécessiter un waitForSelector avant.
// 5. Attendre la navigation après la soumission du formulaire
// C'est important pour s'assurer que la page des résultats de recherche est chargée.
await page.waitForNavigation({ waitUntil: 'networkidle2' });
// 6. Prendre une capture d'écran des résultats de recherche
await page.screenshot({ path: 'google_search_results.png', fullPage: true });
// 7. Afficher le titre de la page des résultats pour confirmation
const pageTitle = await page.title();
console.log(`Titre de la page des résultats: "${pageTitle}"`);
} catch (error) {
console.error('Une erreur est survenue :', error);
} finally {
// 8. Fermer le navigateur, que l'opération réussisse ou échoue
await browser.close();
}
}
searchWithPuppeteer().catch(console.error);
Explication du code :
headless: false, defaultViewport: null: Nous lançons le navigateur en mode visible (headless: false) pour que vous puissiez voir l'automatisation en action.defaultViewport: nullsignifie que Puppeteer n'essaiera pas de définir une taille de fenêtre par défaut, et utilisera la taille par défaut du navigateur.await page.goto('https://www.google.com', { waitUntil: 'networkidle2' });: Navigue vers Google.const searchInputSelector = 'textarea[name="q"]';: Nous définissons le sélecteur CSS du champ de recherche de Google. Il est bon de vérifier ce sélecteur si le site change.await page.waitForSelector(searchInputSelector);: Très important ! Avant d'interagir avec un élément, nous devons nous assurer qu'il est présent et visible sur la page. Cette méthode attend que l'élément avec le sélecteurtextarea[name="q"]apparaisse dans le DOM.await page.type(searchInputSelector, 'Puppeteer tutoriel', { delay: 100 });: Tape la chaîne de caractères "Puppeteer tutoriel" dans le champ de recherche.delay: 100: Introduit un délai de 100 millisecondes entre chaque frappe de caractère, ce qui peut rendre l'interaction plus "humaine" et éviter des problèmes sur certains sites sensibles.
await page.keyboard.press('Enter');: Simule l'appui sur la touche "Entrée" du clavier, ce qui soumet généralement un formulaire de recherche.- Alternativement, vous pourriez utiliser
await page.click('le-sélecteur-du-bouton-de-recherche');si vous connaissez le sélecteur du bouton de soumission.
- Alternativement, vous pourriez utiliser
await page.waitForNavigation({ waitUntil: 'networkidle2' });: Attend que la navigation vers la page des résultats de recherche soit terminée et que le réseau soit stable. C'est essentiel après une action qui déclenche une nouvelle page (comme cliquer sur un lien ou soumettre un formulaire).await page.screenshot({ path: 'google_search_results.png', fullPage: true });: Prend une capture d'écran de la page de résultats.const pageTitle = await page.title();: Récupère le titre de la page actuelle.try...catch...finally: Une bonne pratique pour gérer les erreurs et s'assurer que le navigateur est toujours fermé, même en cas de problème.
Pour exécuter ce script, ouvrez votre terminal dans le répertoire où vous avez sauvegardé search.js et tapez :
node search.js
Vous devriez voir une fenêtre Chrome s'ouvrir, naviguer sur Google, taper du texte, et afficher les résultats. Un fichier google_search_results.png sera également créé.
6. Concepts Avancés Abordés Rapidement (pour la suite)
Cette leçon n'est qu'une introduction. Puppeteer offre bien plus de fonctionnalités que nous explorerons dans les futures leçons :
page.evaluate(): Permet d'exécuter du code JavaScript directement dans le contexte du navigateur, ce qui est extrêmement puissant pour manipuler le DOM, interagir avec des fonctions JavaScript côté client ou extraire des données complexes.- Gestion des iFrames : Interaction avec des contenus embarqués.
- Intercepting network requests : Modifier, bloquer ou analyser les requêtes réseau effectuées par la page. Très utile pour bloquer les publicités ou les scripts de suivi, ou pour simuler des réponses API.
- Authentification : Gérer les connexions, les cookies et le stockage local.
- Interaction avancée : Glisser-déposer, survoler des éléments, gestion des boîtes de dialogue (alertes, confirmations, prompts).
- Débogage : Utiliser les outils de développement de Chrome directement avec Puppeteer.
7. Conclusion
Félicitations ! Vous avez fait vos premiers pas avec Puppeteer, une bibliothèque Node.js puissante et polyvalente pour l'automatisation de navigateurs basés sur Chromium.
Dans cette leçon, nous avons couvert :
- La définition et les cas d'utilisation de Puppeteer.
- Les prérequis et le processus d'installation.
- Les concepts fondamentaux tels que
Browser,Page,ElementHandle,Selectoret l'importance deasync/await. - Comment exécuter Puppeteer en mode headless ou headful.
- Vos premiers scripts pratiques : prendre une capture d'écran d'une page et interagir avec des éléments (taper du texte, cliquer) pour effectuer une recherche.
Vous avez maintenant une base solide pour commencer à explorer les vastes possibilités offertes par Puppeteer. Dans les prochaines leçons, nous approfondirons ces concepts et aborderons des scénarios d'automatisation plus complexes. Préparez-vous à débloquer tout le potentiel de l'automatisation de navigateurs !