Les pré-requis
- Un éditeur de fichier comme l’excellent Sublime Text (gratuit) ou simplement Notepad ou TextEdit si vous ne souhaitez pas installer de logiciel
- Un Mac
- Un accès administrateur
- Un accès au terminal
Étape 1 : Installation de puppeteer
Première étape : lancer le terminal. Si vous ne savez pas comment ouvrir le terminal, je vous ai créé un rapide tuto : Ouvrir le terminal sous mac
Seconde étape : se rendre sur notre dossier. Ici il se situe dans ma librairie :
/Users/amaury/cours/
L’objectif est donc d’arriver au dossier et de créer un dossier afin d’installer Puppeteer.
Pour cela, une seule, il suffit de taper 2 lignes que je vous ai écrites ci-dessous.
NB : pensez à changer amaury avec le nom de votre ordinateur. Si vous ne connaissez pas le nom de votre ordinateur, tapez la commande suivante: ls /Users/
Term
cd /Users/amaury/cours/ mkdir puppeteer
Il ne nous reste plus qu’à installer Puppeteer en saississant une commande très simple
Term
npm install puppeteer
Il ne vous reste plus qu’à attendre 1 à 2 minutes selon votre connexion. Lorsque Puppeteer sera installé, vous aurez un écran semblable à celui ci. À noter que les erreurs présentes ici sont dues à la version sélectionnée. Dans cet exemple, cela ne changera rien.
Term
mba:cours amaury$ cd /Users/amaury/cours/
mba:cours amaury$ mkdir puppeteer
mba:cours amaury$ npm install puppeteer
> puppeteer@6.0.0 install /Users/amaury/cours/node_modules/puppeteer
> node install.js
(node:16155) ExperimentalWarning: The fs.promises API is experimental
Downloading Chromium r843427 - 108 Mb [====================] 100% 0.0s
Chromium (843427) downloaded to /Users/amaury/cours/node_modules/puppeteer/.local-chromium/mac-843427
npm WARN saveError ENOENT: no such file or directory, open '/Users/amaury/cours/package.json'
npm notice created a lockfile as package-lock.json. You should commit this file.
npm WARN enoent ENOENT: no such file or directory, open '/Users/amaury/cours/package.json'
npm WARN ws@7.4.3 requires a peer of bufferutil@^4.0.1 but none is installed. You must install peer dependencies yourself.
npm WARN ws@7.4.3 requires a peer of utf-8-validate@^5.0.2 but none is installed. You must install peer dependencies yourself.
npm WARN cours No description
npm WARN cours No repository field.
npm WARN cours No README data
npm WARN cours No license field.
+ puppeteer@6.0.0
added 54 packages from 76 contributors and audited 54 packages in 39.356s
found 0 vulnerabilities
Étape 2 : Création du script
Attaquons nous à la mise en place du script !
Ici, nous utiliserons du Node JS mais pas de panique, je vous explique tout !
Commençons par les bases : les commentaires.
Dans le script que je vous fourni, chaque ligne est commentée afin que vous puissiez comprendre le code. Les commentaires sont précédés de double slash //
Commençons par le code complet
Node
// Ici, on importe Puppeteer const puppeteer = require('puppeteer') // PREMIÈRE PARTIE DU SCRIPT // // On déclare la fonction "récupèrelesurls" qui va gérer toute la première partie du script const récupèrelesurls = async browser => { // On indique à Puppeteer que dès que la fonction "page" est appelée, il faut ouvrir une nouvelle page const page = await browser.newPage() // On indique l'URL à travers la fonction "page" await page.goto('http://books.toscrape.com/') // On demande au script d'attendre le chargement de la page à travers la fonction "page" await page.waitFor('body') // On indique au script, ce qu'on souhaite récupérer : ici les hrefs inclus dans la class .product_pod à travers la fonction "result" const result = await page.evaluate(() => [...document.querySelectorAll('.product_pod a')].map(link => link.href), ) // on affiche le résultat de la fonction "result" return result } // FIN DE LA PREMIÈRE PARTIE DU SCRIPT // // DEUXIÈME PARTIE DU SCRIPT // // On déclare la fonction "récupèrelesrésultats" qui va gérer toute la deuxième partie du script const récupèrelesrésultats = async (browser, url) => { // On indique à Puppeteer que dès que la fonction "page" est appelée, il faut ouvrir une nouvelle page const page = await browser.newPage() // On indique à Puppeteer qu'il faut aller rester sur la page actuelle, appellée nativement "url" await page.goto(url) // On demande au script d'attendre le chargement de la page à travers la fonction "page" await page.waitFor('body') return page.evaluate(() => { // On indique au script, ce qu'on souhaite récupérer : ici les h1 et la class ".price_color" qui définit les prix sur le site let Produit = document.querySelector('h1').innerText let Prix = document.querySelector('.price_color').innerText // on affiche le résultat de la fonction "result" return { Produit, Prix } }) } // FIN DEUXIÈME PARTIE DU SCRIPT // // TROISIÈME PARTIE DU SCRIPT // // Création de la fonction "scraping" const scraping = async () => { // On indique à Puppeteer que l'on souhaite voir qu'il lance une instance (puppeteer.launch()) et que l'on souhaite que Chromium s'ouvre { headless: false } (mettre à true pour qu'il se lance silencieusement) const browser = await puppeteer.launch({ headless: false }) // On récupère toutes nos données scrapées const urlList = await récupèrelesurls(browser) const results = await Promise.all( urlList.map(url => récupèrelesrésultats(browser, url)), ) // On ferme tout browser.close() // On affiche return results } // FIN TROISÈME PARTIE DU SCRIPT // // DERNIÈRE PARTIE DU SCRIPT // // On appelle la fonction "scraping" et on affiche les résultats dans la console log scraping() .then(résultats => { console.log(résultats) })
Dans l’étape suivante, je vais décrypter le script afin que vous puissiez comprendre comment il marche et que vous puissiez reproduire la même chose chez vous.
Si vous souhaitez directement accéder à la mise en fonction du plugin, cliquez ici pour aller à la dernière étape
Étape 3 : Décryptage du script
1. Importation de Puppeteer
Pour commencer à utiliser le script, il convient d’appeler Puppeteer
Node
// Ici, on importe Puppeteer const puppeteer = require('puppeteer')
Dans le cas présent, nous utiliserons la déclaration const pour l’appeler.
C’est un peu comme un raccourci.
Ici, const puppeteer = require(puppeteer')
Pourrait être traduit par puppeteer = require('puppeteer')
Enfin, require('puppeteer')
indique au script que nous aurons besoin de Puppeteer tout le long du code. En cas d’absence de Puppeteer, le script s’arrêtera.
1. Première partie du script
Première partie du script : on indique au script ses principales tâches
Node
// On déclare la fonction "récupèrelesurls" qui va gérer toute la première partie du script const récupèrelesurls = async browser => { // On indique à Puppeteer que dès que la fonction "page" est appelée, il faut ouvrir une nouvelle page const page = await browser.newPage() // On indique l'URL à travers la fonction "page" await page.goto('http://books.toscrape.com/') // On demande au script d'attendre le chargement de la page à travers la fonction "page" await page.waitFor('body') // On indique au script, ce qu'on souhaite récupérer : ici les hrefs inclus dans la class .product_pod à travers la fonction "result" const result = await page.evaluate(() => [...document.querySelectorAll('.product_pod a')].map(link => link.href), ) // on affiche le résultat de la fonction "result" return result }
Comme lors de l’appel de Puppeteer, on va utiliser les déclarations const pour créer des raccourcis qui sera appelés tout au long du script.
Dans la première partie de ce script, on utilisera donc 3 const :
- const récupèrelesrésultats = async (browser, url) => { déclare le raccourci récupèrelesrésultats dans lequel est inclu tout le code compris entre l’accolade d’ouverture { et l’accolade de fermeture }
- const page déclare le raccourci page qui indique qu’il faut ouvrir un nouvel onglet
- const result déclare le raccourci result qui de son côté va récupérer le contenu de la page compris dans les liens incluant la class .product_pod
Ces déclarations expliquées, il nous reste à comprendre le reste du code !
Si vous avez quelques notions d’anglais, l’excercice devrait être relativement facile. Voyons le code en 4 points :
- Await : await browser.newPage() indique qu’il faut ouvrir un nouvel onglet / une nouvelle page. Await page.goto(‘http://books.toscrape.com/’), qu’il faut aller à la page http://books.toscrape.com/ …
- Page.waitFor(‘body’) indique qu’il faut attendre le chargement du body (ndlr de la page)
- Await page.evaluate indique ce que l’on souhaite récupérer. Ici, document.querySelectorAll(‘.product_pod a’), soit le contenu de la page compris dans les liens incluant la class .product_pod
- Enfin, return result qui est chargé d’afficher la décaration result
1. Deuxième partie du script
Seconde partie du script : on indique au script les données à scraper
Node
// On déclare la fonction "récupèrelesrésultats" qui va gérer toute la deuxième partie du script const récupèrelesrésultats = async (browser, url) => { // On indique à Puppeteer que dès que la fonction "page" est appelée, il faut ouvrir une nouvelle page const page = await browser.newPage() // On indique à Puppeteer qu'il faut aller rester sur la page actuelle, appellée nativement "url" await page.goto(url) // On demande au script d'attendre le chargement de la page à travers la fonction "page" await page.waitFor('body') return page.evaluate(() => { // On indique au script, ce qu'on souhaite récupérer : ici les h1 et la class ".price_color" qui définit les prix sur le site let Produit = document.querySelector('h1').innerText let Prix = document.querySelector('.price_color').innerText // on affiche le résultat de la fonction "result" return { Produit, Prix } }) }
Si vous avez suivi la première partie du script, aucune surprise ici, à l’exception d’une déclaration let que l’on retrouve à travers la commande let Produit = document.querySelector(‘h1’).innerText. Let est un peu comme const avec quelques différences que j’expliquerai dans un prochain article.
1. Troisième partie du script
Troisième partie du script : on scrape
Node
// Création de la fonction "scraping" const scraping = async () => { // On indique à Puppeteer que l'on souhaite voir qu'il lance une instance (puppeteer.launch()) et que l'on souhaite que Chromium s'ouvre { headless: false } (mettre à true pour qu'il se lance silencieusement) const browser = await puppeteer.launch({ headless: false }) // On récupère toutes nos données scrapées const urlList = await récupèrelesurls(browser) const results = await Promise.all( urlList.map(url => récupèrelesrésultats(browser, url)), ) // On ferme tout browser.close() // On affiche return results }
Ici, quelques fonctions importantes.
Tout d’abord, vous remarquerez que de nombreuses déclarations const sont appelées. C’est le cas de puppeteer à travers puppeteer.launch, mais également de récupèrelesurls ou encore récupèrelesrésultats
Enfin, à la quatrième ligne, on écrit l’une des lignes les plus importante de notre script : const browser = await puppeteer.launch({ headless: false }). Sans elle, notre script ne fonctionnera pas. Ici, cette ligne indique au script de se lancer avec puppeteer (await puppeteer.launch) et d’ouvrir le navigateur ( { headless: false } )
1. Dernière partie du script
Dernière partie du script : on envoi les résultats à la console
Node
scraping()
.then(résultats => {
console.log(résultats)
})
Étape 4 : Lancement du script
Une fois le code écrit, il ne nous reste plus qu’à l’exécuter. À nouveau dans le Terminal, rendez vous dans votre dossier et tapez la commande suivante :
Term
node puppeteer.js
Chromium va s’ouvrir comme dans la vidéo ci-dessous. Laissez le faire, il se ferma tout seul et vous aurez le même résultat que moi !