Scraping Web avec Puppeteer Advanced Node.JS

Gabriel Cioci le 28 juillet 2021

Plutôt que d'utiliser des outils commerciaux, de nombreux développeurs préfèrent créer leurs propres web scrapers. Bien que les produits disponibles aient des fonctionnalités plus étoffées, nous ne pouvons nier les résultats que ces robots peuvent apporter ni le plaisir de créer le sien.

Dans l'article suivant, vous découvrirez les étapes à suivre pour construire votre propre scraper web en utilisant Node.js et Puppeteer. Nous allons coder une application qui charge un site web, prend une capture d'écran, se connecte au site web à l'aide d'un navigateur sans tête et récupère des données sur plusieurs pages. Votre application deviendra de plus en plus complexe au fur et à mesure que vous progresserez.

Une vue d'ensemble du Web Scraping avec Puppeteer

Google a conçu Puppeteer pour fournir une interface simple mais puissante en Node.js pour automatiser les tests et diverses tâches en utilisant le moteur de navigation Chromium. Il fonctionne par défaut sans tête, mais il peut être configuré pour fonctionner avec Chrome ou Chromium.

L'API créée par l'équipe de Puppeteer utilise le protocole DevTools pour prendre le contrôle d'un navigateur web, comme Chrome, et effectuer différentes tâches, comme par exemple :

  • Effectuer des captures d'écran et générer des PDF des pages
  • Automatiser la soumission des formulaires
  • Tests de l'interface utilisateur (clics sur les boutons, saisie au clavier, etc.)
  • Scraper une SPA et générer du contenu pré-rendu (Server-Side Rendering)

La plupart des actions que vous pouvez effectuer manuellement dans le navigateur peuvent également être réalisées à l'aide de Puppeteer. En outre, elles peuvent être automatisées, ce qui vous permet de gagner du temps et de vous consacrer à d'autres tâches.

Puppeteer a également été conçu pour être convivial pour les développeurs. Les personnes familiarisées avec d'autres frameworks de test populaires, tels que Mocha, se sentiront tout de suite à l'aise avec Puppeteer et trouveront une communauté active offrant un support pour Puppeteer. Cela a conduit à une croissance massive de la popularité parmi les développeurs.

Bien entendu, Puppeteer n'est pas uniquement destiné aux tests. Après tout, s'il peut faire tout ce qu'un navigateur standard peut faire, alors il peut être extrêmement utile pour les scrapeurs web. Il peut notamment aider à exécuter du code javascript afin que le scraper puisse atteindre le code HTML de la page et imiter le comportement normal d'un utilisateur en faisant défiler la page ou en cliquant sur des sections aléatoires.

Ces fonctionnalités indispensables font des navigateurs sans tête un composant essentiel de tout outil commercial d'extraction de données et de tous les scrapeurs web maison, à l'exception des plus simples.

Conditions préalables

Tout d'abord, assurez-vous que vous avez des versions à jour de Node.js et de Puppeteer installées sur votre machine. Si ce n'est pas le cas, vous pouvez suivre les étapes ci-dessous pour installer tous les prérequis.

Vous pouvez télécharger et installer Node.js à partir d'ici. Le gestionnaire de paquets par défaut de Node , npm, est préinstallé avec Node.js.

Pour installer la bibliothèque Puppeteer, vous pouvez exécuter la commande suivante dans le répertoire racine de votre projet :

npm install puppeteer
# ou "yarn add puppeteer"

Notez que lorsque vous installez Puppeteer, il télécharge également la dernière version de Chromium dont le fonctionnement avec l'API est garanti.

Marionnettiste en action

Il y a beaucoup de choses différentes que vous pouvez faire avec la bibliothèque. Puisque nous nous concentrons sur le scraping web, nous parlerons des cas d'utilisation les plus susceptibles de vous intéresser si vous souhaitez extraire des données web.

Faire une capture d'écran

Commençons par un exemple de base. Nous allons écrire un script qui prendra une capture d'écran d'un site web de notre choix.

Gardez à l'esprit que Puppeteer est une bibliothèque basée sur les promesses (elle effectue des appels asynchrones à l'instance Chrome sans tête sous le capot). Gardons donc le code propre en utilisant async/await.

Tout d'abord, créez un nouveau fichier appelé index.js dans le répertoire racine de votre projet.

Dans ce fichier, nous devons définir une fonction asynchrone et l'enrouler autour de tout le code de Puppeteer.

const puppeteer = require('puppeteer')

async function snapScreenshot() {
try {
const URL = 'https://old.reddit.com/'
const browser = await puppeteer.launch()
const page = await browser.newPage()

await page.goto(URL)
await page.screenshot({ path: 'screenshot.png' })

await browser.close()
} catch (error) {
console.error(error)
}
}

snapScreenshot()

Tout d'abord, une instance du navigateur est lancée à l'aide de la commande puppeteer.launch(). Ensuite, nous créons une nouvelle page en utilisant l'instance du navigateur. Pour naviguer vers le site web souhaité, nous pouvons utiliser la méthode goto(), en passant l'URL en paramètre. Pour effectuer une capture d'écran, nous utiliserons la méthode screenshot(). Nous devons également passer l'emplacement où l'image sera sauvegardée.

Notez que Puppeteer fixe la taille initiale de la page à 800×600px, ce qui définit la taille de la capture d'écran. Vous pouvez personnaliser la taille de la page à l'aide de la méthode setViewport().

N'oubliez pas de fermer l'instance du navigateur. Il ne vous reste plus qu'à lancer node index.js dans le terminal.

C'est aussi simple que cela ! Vous devriez maintenant voir un nouveau fichier appelé screenshot.png dans le dossier de votre projet.

Envoi d'un formulaire

Si, pour une raison quelconque, le site web que vous souhaitez récupérer n'affiche pas le contenu si vous n'êtes pas connecté, vous pouvez automatiser le processus de connexion à l'aide de Puppeteer.

Tout d'abord, nous devons inspecter le site web que nous scrappons et trouver les champs de connexion. Nous pouvons le faire en faisant un clic droit sur l'élément et en choisissant l'option Inspecter.

blog-image

Dans mon cas, les entrées se trouvent dans un formulaire avec la classe login-form. Nous pouvons entrer les identifiants de connexion en utilisant la méthode type().

De plus, si vous voulez vous assurer que les actions sont correctes, vous pouvez ajouter le paramètre headless et lui donner la valeur false lorsque vous lancez l'instance de Puppeteer. Vous verrez alors comment Puppeteer effectue l'ensemble du processus à votre place.

const puppeteer = require('puppeteer')

async function login() {
try {
const URL = 'https://old.reddit.com/'
const browser = await puppeteer.launch({headless: false})
const page = await browser.newPage()

await page.goto(URL)

await page.type('.login-form input[name="user"]', 'EMAIL@gmail.com')
await page.type('.login-form input[name="passwd"]', 'PASSWORD')

await Promise.all([
page.click('.login-form .submit button'),
page.waitForNavigation(),
]);

await browser.close()

} catch (error) {
console.error(error)
}
}

login()

Pour simuler un clic de souris, nous pouvons utiliser la méthode click(). Après avoir cliqué sur le bouton de connexion, nous devons attendre que la page se charge. Nous pouvons le faire avec la méthode waitForNavigation().

Si nous avons saisi les informations d'identification correctes, nous devrions être connectés maintenant !

Scraper plusieurs pages

Je vais utiliser le subreddit /r/learnprogramming pour cet article. Nous voulons donc naviguer sur le site web, récupérer le titre et l'URL de chaque message. Nous utiliserons la méthode evaluate() pour cela.

Le code devrait ressembler à ceci :

const puppeteer = require('puppeteer')

async function tutorial() {
try {
const URL = 'https://old.reddit.com/r/learnprogramming/'
const browser = await puppeteer.launch()
const page = await browser.newPage()

await page.goto(URL)
let data = await page.evaluate(() => {
let results = []
let items = document.querySelectorAll('.thing')
items.forEach((item) => {
results.push({
url: item.getAttribute('data-url'),
title: item.querySelector('.title').innerText,
})
})
return results
})

console.log(data)
await browser.close()

} catch (error) {
console.error(error)
}
}

tutorial()

En utilisant la méthode Inspect présentée précédemment, nous pouvons récupérer tous les articles en ciblant le sélecteur .thing. Nous les parcourons, et pour chacun d'entre eux, nous récupérons l'URL et le titre et les plaçons dans un tableau.

Une fois le processus terminé, vous pouvez voir le résultat dans votre console.

blog-image

Génial, nous avons scrapé la première page. Mais comment scraper plusieurs pages de ce subreddit ?

C'est plus simple que vous ne le pensez. Voici le code :

const puppeteer = require('puppeteer')

async function tutorial() {
try {
const URL = 'https://old.reddit.com/r/learnprogramming/'
const browser = await puppeteer.launch({headless: false})
const page = await browser.newPage()

await page.goto(URL)
let pagesToScrape = 5;
let currentPage = 1;
let data = []
while (currentPage <= pagesToScrape) {
let newResults = await page.evaluate(() => {
let results = []
let items = document.querySelectorAll('.thing')
items.forEach((item) => {
results.push({
url: item.getAttribute('data-url'),
text: item.querySelector('.title').innerText,
})
})
return results
})
data = data.concat(newResults)
if (currentPage < pagesToScrape) {
await page.click('.next-button a')
await page.waitForSelector('.thing')
await page.waitForSelector('.next-button a')
}
currentPage++;
}
console.log(data)
await browser.close()
} catch (error) {
console.error(error)
}
}

tutorial()

Nous avons besoin d'une variable pour savoir combien de pages nous voulons récupérer et d'une autre variable pour la page actuelle. Si la page actuelle est inférieure ou égale au nombre de pages que nous voulons récupérer, nous récupérons l'URL et le titre de chaque article de la page. Une fois chaque page récoltée, nous concaténons les nouveaux résultats avec ceux déjà récupérés.

Nous cliquons ensuite sur le bouton "page suivante" et répétons le processus d'extraction jusqu'à ce que nous atteignions le nombre souhaité de pages extraites. Nous devons également incrémenter la page actuelle après chaque page.

Une option encore plus simple

Nous vous félicitons ! Vous avez réussi à construire votre propre scraper web avec Puppeteer. J'espère que vous avez apprécié ce tutoriel !

Malgré cela, le script que nous avons créé dans ce guide ne peut pas faire beaucoup de travail. Il lui manque quelques aspects clés pour que le web scraping soit parfait. L'utilisation de proxys mobiles ou résidentiels et la résolution de CAPTCHAs ne sont que quelques-unes des fonctionnalités manquantes.

Si vous cherchez un moyen plus professionnel d'extraire des données, jetez un coup d'œil à ce que WebScrapingAPI peut accomplir et voyez si cela vous convient. Il existe un pack gratuit, vous n'avez donc qu'à investir 30 minutes de votre temps.

Joyeux web scraping !

Nouvelles et mises à jour

Restez au courant des derniers guides et nouvelles sur le web scraping en vous inscrivant à notre lettre d'information.

We care about the protection of your data. Read our <l>Privacy Policy</l>.Privacy Policy.

Articles connexes

vignette
GuidesApprendre à contourner la détection de Cloudflare avec le meilleur navigateur Selenium

Apprenez quel est le meilleur navigateur pour contourner les systèmes de détection de Cloudflare lorsque vous faites du web scraping avec Selenium.

Mihnea-Octavian Manolache
avatar de l'auteur
Mihnea-Octavian Manolache
9 minutes de lecture
vignette
GuidesComment construire un scraper et télécharger un fichier avec Puppeteer

Découvrez 3 façons de télécharger des fichiers avec Puppeteer et construisez un scraper web qui fait exactement cela.

Mihnea-Octavian Manolache
avatar de l'auteur
Mihnea-Octavian Manolache
8 minutes de lecture
vignette
GuidesLe guide ultime de l'automatisation et de la récupération de données sur le Web de Playwright pour 2023

Apprenez à utiliser Playwright pour le scraping web et l'automatisation grâce à notre guide complet. De la configuration de base aux techniques avancées, ce guide couvre tout.

Suciu Dan
avatar de l'auteur
Suciu Dan
16 minutes de lecture