Cheerio vs. Puppeteer pour le web scraping

Construire un web scraper avec Puppeteer et Cheerio pour obtenir un aperçu des différences entre les deux.
13 min de lecture
Cheerio vs. Puppeteer featured image

Cheerio et Puppeteer sont deux bibliothèques Node.js qui vous permettent de parcourir Internet en écrivant des programmes appropriés. Pour cette raison, ils sont tous les deux populaires auprès de ceux qui souhaitent construire un web scraper Node.js ex nihilo.  

Afin de comparer Cheerio et Puppeteer, nous allons construire un web scraper simple avec Cheerio et un autre web scraper avec Puppeteer. Nous allons utiliser ces deux outils pour collecter tous les liens de blog sur In Plain English, plateforme de programmation bien connue.

Mais avant de commencer, voyons ce que nous allons parler dans cet article :

Les différences entre Cheerio et Puppeteer

Il y a beaucoup de différences entre ces 2 bibliothèques, et chacune d’elles est dotée de ses propres fonctionnalités particulières que vous pouvez mettre à profit pour vos tâches de web scraping.

Cheerio

  • Cheerio est un analyseur DOM, capable d’analyser des fichiers HTML et XML.
  • Il s’agit d’une implémentation rapide et allégée de jQuery spécialement conçue pour le serveur.
  • Si vous prévoyez de l’utiliser pour collecter des données sur un site web, vous devrez utiliser Cheerio en association avec une bibliothèque client http Node.js telle qu’Axios.  
  • Le rendu du site web obtenu avec Cheerio n’est pas semblable à celui obtenu avec un navigateur (Cheerio n’applique pas de CSS et ne charge pas de ressources externes).
  • Pour cette raison, vous aurez du mal à essayer de faire du web scraping sur des SPA (applications monopages) construites avec des technologies frontend telles que React.
  • Cheerio ne peut pas interagir avec un site (par exemple, il ne peut pas cliquer sur des boutons) ou accéder au contenu qui se trouve derrière les scripts.
  • Sa courbe d’apprentissage est rapide grâce à sa syntaxe simple. Les utilisateurs de jQuery se sentiront en terrain connu.
  • Cheerio est plus rapide que Puppeteer.

Puppeteer

  • Puppeteer est un outil d’automatisation de navigateur. Vous avez accès à l’ensemble du moteur de navigation (généralement Chrome).
  • Il s’agit d’une option plus polyvalente que Cheerio.
  • Puppeteer peut exécuter JavaScript, ce qui lui permet de faire du scraping sur des pages dynamiques telles que les applications monopages (SPA).
  • Puppeteer peut interagir avec des sites web, ce qui signifie qu’il peut être utilisé pour cliquer sur des boutons, remplir des formulaires de connexion, etc.
  • Sa courbe d’apprentissage est plus ardue car il a plus de fonctionnalités et exige souvent l’utilisation de code asynchrone (promises/async await).
  • Puppeteer est plus lent que Cheerio.

Construction d’un web scraper avec Cheerio

Tout d’abord, créons un dossier appelé scraper pour notre code. A l’intérieur du dossier scraper, exécutez la commande npm init -y ou yarn init -y, selon que vous ayez choisi d’utiliser npm ou yarn.  

Maintenant que notre dossier est prêt et que notre package.json est initialisé, installons nos paquets.  

Remarque : Vous pouvez consulter notre guide de web scraping avec Node.js, qui aborde plus en détail l’utilisation de Cheerio et d’Axios pour le web scraping.  

Étape 1 : installation de Cheerio

Pour installer Cheerio, exécutez le code suivant sur votre terminal :

// using npm
npm install cheerio

// or using yarn
yarn add cheerio

Étape 2 : installation d’Axios

Axios est une bibliothèque populaire pour lancer des requêtes HTTP dans Node.js. Axios peut être utilisé pour passer des appels d’API, récupérer des données sur des sites web, etc.

Pour l’installer, exécutez le code suivant sur votre terminal :

// using npm
npm install axios

// or using yarn
yarn add axios

Nous utilisons Axios pour envoyer des requêtes HTTP à notre site cible. La réponse que nous recevons du site est au format HTML ; nous pouvons alors l’analyser et extraire les informations dont nous avons besoin avec Cheerio.

Étape 3 : préparation de notre web scraper

Allons dans notre dossier scraper et créons un fichier appelé cheerio.js.  

Voici la structure de code de base qui vous permettra de faire vos premiers pas en web scraping en utilisant Cheerio et Axios :

const axios = require('axios');
const cheerio = require('cheerio');

axios
 .get("https://plainenglish.io/blog")
 .then((response) => {
   // Initialize links array which we will push the links to later
   let links = [];

   // HTML Markup
   const body = response.data;

   // Load HTML data and initialize cheerio
   const $ = cheerio.load(body);

   // CSS selector for the target element
   const element = ".PostPreview_container__82q9E";

   // Loop through each matching element and extract the text content
   $(element).each(function () {
     // Loop through each matching element and get the href attribute of each element
     const _link = $(this).find("a").prop("href");

     // We check if the link is undefined because cheerio will return undefined if the element doesn't exist
     if (_link !== undefined) {
       // Add the link to the links array
       links.push(`https://plainenglish.io` + _link);
     }
   });

   return links;
 })
 .then((response) => {
   console.log(response);
 });

Dans le code ci-dessus, nous incluons d’abord les bibliothèques Axios et Cheerio.

Étape 4 : lancer la requête de données

Nous lançons ensuite une requête get() à “https://plainenglish.io/blog”. Comme Axios est asynchrone, nous enchaînons notre fonction get() avec then().  

Nous initialisons un tableau de liens vide pour capturer les liens que nous prévoyons de collecter.

Nous transmettons ensuite response.data d’Axios à Cheerio avec :  

// HTML Markup
const body = response.data;

// Load HTML data and initialize cheerio
const $ = cheerio.load(body);
We choose which selector we plan to target, in our case:
// CSS selector for the target element
const element = ".PostPreview_container__82q9E";

Étape 5 : le traitement des données

Ensuite, nous faisons une boucle sur chaque élément pour lequel nous trouvons une correspondance, nous trouvons la balise <a> et nous prenons la valeur qui se trouve dans la propriété href. Pour chaque correspondance, nous entrons cette valeur dans notre tableau de liens :  

// Loop through each matching element and extract the text content
$(element).each(function () {
 // Loop through each matching element and get the href attribute of each element
 const _link = $(this).find("a").prop("href");

 // We check if the link is undefined because cheerio will return undefined if the element doesn't exist
 if (_link !== undefined) {
   // Add the link to the links array
   links.push(`https://plainenglish.io` + _link);
 }
});

Nous retournons alors les liens, enchaînons un autre then() et consignons notre réponse avec console.log.  

Étape 6 : résultats finaux

Enfin, si nous ouvrons un terminal depuis l’intérieur de notre dossier scraper, nous pouvons exécuter node.js cheerio.js. Cela entraînera l’exécution de l’intégralité du code de notre fichier cheerio.js. Vous devriez voir les URL de notre tableau de liens affichés sur la console. Cela devrait ressembler à ceci :  

 'https://plainenglish.io/blog/how-to-implement-a-search-bar-in-react-js',
 'https://plainenglish.io/blog/how-to-build-data-driven-surveys-with-react-rest-api-surveyjs',
 'https://plainenglish.io/blog/handle-errors-in-angular-with-httpclient-and-rxjs',
 'https://plainenglish.io/blog/deploying-a-localhost-server-with-node-js-and-express-js',
 'https://plainenglish.io/blog/complete-guide-to-data-center-migration',
 'https://plainenglish.io/blog/build-a-stripe-app-with-typescript-and-node-js-part-2',
 ... 861 more items

C’est fait ! Nous avons réussi à collecter des données sur In Plain English.

À partir de là, nous pouvons aller plus loin et enregistrer les données dans un fichier, plutôt que de simplement les afficher sur la console.

Cheerio et Axios facilitent les tâches de web scraping sous Node.js. Avec quelques lignes de code, vous pouvez collecter des données sur des sites web et les utiliser à diverses fins.  

Construction d’un web scraper avec Puppeteer

Allons dans notre dossier scraper et créons un fichier appelé puppeteer.js. Nous avons déjà initialisé notre package.json, mais si vous avez ignoré cette section, commencez par initialiser ce fichier maintenant.  

Une fois l’initialisation effectuée, poursuivons avec l’installation de Puppeteer.

Étape 1 : installation de Puppeteer

Pour installer Puppeteer, exécutez l’une des commandes suivantes :

// using npm
npm install puppeteer

// or using yarn
yarn add puppeteer

Étape 2 : préparation de notre web scraper

Allons dans notre dossier scraper et créons un fichier appelé puppeteer.js.  

Voici la structure de code de base qui vous permettra de faire vos premiers pas en web scraping avec Puppeteer :

const puppeteer = require("puppeteer");

// Because everything in Puppeteer is asynchronous,
// we wrap all of our code inside of an async IIFE
(async () => {
 // Initialize links array which we will push the links to later
 let links = [];

 // Launch Puppeteer
 const browser = await puppeteer.launch();

 // Create a new page
 const page = await browser.newPage();

 // Go to URL
 await page.goto("https://plainenglish.io/blog");

 // Set screen size
 await page.setViewport({ width: 1080, height: 1024 });

 // CSS selector for the target element
 const element = ".PostPreview_container__82q9E";

 // Get all matching elements
 const elements = await page.$$(element);

 // Wrapped with Promise.all to wait for all promises to resolve before continuing
 const _links = await Promise.all(
   // Get the href attribute of each element
   elements.map(async (el) => el.evaluate((el) => el.children[0].href))
 );

 if (_links.length) {
   // If there are any links
   _links.forEach((url) => {
     // Loop through each link
     links.push(url); // Add the link to the links array
   });
 }

 console.log(links);

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

Dans le code ci-dessus, nous incluons d’abord la bibliothèque Puppeteer.

Étape 3 : création d’une IIFE

Ensuite, nous créons une expression de fonction appelée immédiatement (ou IIFE, immediately invoked function expression). Comme Puppeteer est entièrement asynchrone, nous mettons async au début. En d’autres termes, nous nous retrouvons avec ceci :  

(async () => {
// ...code goes here
}()

À l’intérieur de notre IIFE asynchrone, nous créons un tableau de liens vide, que nous utiliserons pour capturer les liens sur le blog cible.

// Initialize links array which we will push the links to later
let links = []

Nous lançons ensuite Puppeteer, ouvrons une nouvelle page, naviguons jusqu’à une URL, puis définissons la fenêtre d’affichage de la page (la taille de l’écran).

 // Launch Puppeteer
 const browser = await puppeteer.launch();

 // Create a new page
 const page = await browser.newPage();

 // Go to URL
 await page.goto("https://plainenglish.io/blog");

 // Set screen size
 await page.setViewport({ width: 1080, height: 1024 });

Par défaut, Puppeteer fonctionne en « mode sans tête ». Cela signifie qu’il n’ouvre pas un navigateur muni d’une interface graphique. Néanmoins, nous définissons une taille de fenêtre d’affichage car nous voulons que Puppeteer navigue sur le site à des coordonnées bien précises sur la page.

Remarque : si vous décidez que vous aimeriez regarder ce que Puppeteer fait en temps réel, vous pouvez passer l’option headless: false comme paramètre, comme suit :  

// Launch Puppeteer
const browser = await puppeteer.launch({ headless: false });

Étape 4 : lancer la requête de données

À partir de là, nous choisissons le sélecteur que nous prévoyons de cibler, dans notre cas :

// CSS selector for the target element
const element = ".PostPreview_container__82q9E";

Puis nous exécutons ce qui est en quelque sorte l’équivalent de querySelectorAll() pour notre élément cible :  

// Get all matching elements
const elements = await page.$$(element);

Remarque :$$ n’est pas identique à querySelectorAll ; ne vous attendez donc pas à avoir accès exactement aux mêmes choses.  

Étape 5 : le traitement des données

Maintenant que nos éléments sont stockés à l’intérieur d’éléments, nous mappons chaque élément pour extraire la propriété href :  

// Wrapped with Promise.all to wait for all promises to resolve before continuing
const _links = await Promise.all(
 // Get the href attribute of each element
 elements.map(async (el) => el.evaluate((el) => el.children[0].href))
);

Dans notre cas d’utilisation spécifique, il s’agit d’el.children[0], car nous savons que le premier élément enfant de notre élément cible est une balise, et c’est la balise a dont je veux connaître la valeur.  

Ensuite, nous passons en boucle chaque élément mappé et nous entrons la valeur correspondante dans notre tableau de liens, comme ceci :

if (_links.length) {
 // If there are any links
 _links.forEach((url) => {
   // Loop through each link
   links.push(url); // Add the link to the links array
 });
}

Enfin, nous consignons les liens avec console.log, puis fermons le navigateur :  

console.log(links);

await browser.close();

Remarque : si vous ne fermez pas le navigateur, il restera ouvert et votre terminal se bloquera.  

Étape 6 : résultats finaux

Maintenant, si nous ouvrons un terminal depuis l’intérieur de notre dossier scraper, nous pouvons exécuter node.js puppeteer.js. Cela entraînera l’exécution de l’intégralité du code de notre fichier puppeteer.js . Vous devriez voir les URL de notre tableau de liens affichés sur la console. Cela devrait ressembler à ceci :  

'https://plainenglish.io/blog/how-to-implement-a-search-bar-in-react-js',
 'https://plainenglish.io/blog/how-to-build-data-driven-surveys-with-react-rest-api-surveyjs',
 'https://plainenglish.io/blog/handle-errors-in-angular-with-httpclient-and-rxjs',
 'https://plainenglish.io/blog/deploying-a-localhost-server-with-node-js-and-express-js',
 'https://plainenglish.io/blog/complete-guide-to-data-center-migration',
 'https://plainenglish.io/blog/build-a-stripe-app-with-typescript-and-node-js-part-2',
 ... 861 more items

C’est fait ! Nous avons réussi à collecter des données sur le site avec Puppeteer.

Puppeteer est un outil puissant pour le web scraping et l’automatisation des tâches de navigateur. Il fournit une API de qualité pour le web scraping et l’automatisation des tâches de navigateur. Vous pouvez l’utiliser pour extraire des informations sur des sites web, générer des captures d’écran et des PDF, et effectuer bien d’autres types de tâches.

Si vous voulez utiliser Puppeteer pour collecter des données sur des sites web importants, vous devrez envisager d’intégrer Puppeteer avec un proxy afin d’éviter de vous faire bloquer.  

Remarque : il existe d’autres alternatives à Puppeteer, telles que Selenium ou notre Web scraper IDE. Si vous voulez gagner du temps, vous pouvez également renoncer à tout ce processus de web scraping en consultant des jeux de données prêts à l’emploi.  

Conclusion

Si vous cherchez à collecter des données sur des pages statiques et que vous n’avez pas besoin d’interactions telles que des clics et des envois de formulaires (ou tout autre type de gestion d’événement), Cheerio est le choix optimal.

Toutefois, si le site utilise JavaScript pour l’injection de contenu, ou si vous devez gérer des événements, vous aurez besoin de Puppeteer.

Quelle que soit l’approche que vous choisirez, il est à noter que ce cas d’utilisation spécifique était assez simple. Si vous essayez de faire du web scraping dans un cas plus complexe, par exemple sur un site web dynamique (YouTube, Twitter ou Facebook par exemple), vous risquez de vous retrouver dans une situation très compliquée.  

Si vous cherchez à collecter des données sur des sites web et que vous ne voulez pas perdre des semaines à essayer d’élaborer une solution, vous aurez peut-être intérêt à trouver une solution prête à l’emploi telle que le Web Scraper IDE de Bright Data.  

Le Web scraper IDE inclut des fonctions de web scraping préprogrammées, une infrastructure de proxys sophistiquée intégrée pour le déblocage des sites, des scripts de navigateur en JavaScript, des fonctions de débogage et plusieurs modèles de scraping prêts à l’emploi pour les sites les plus populaires.