Puppeteer
est une librairie Nodejs qui fournit des outils pour contrôler Chromium avec le protocole DevTools
. Puppeteer exécute Chrome ou Chromium, sans en entête par défaut.
Sans entête signifie que les opérations dans le navigateur sont réalisées sans interface graphique. Il n’y a aucun bouton ou formulaire à cliquer ou remplir, mais vous pouvez contrôler la page ouverte en javascript. Inversement, Puppeteer
en mode entête affiche le navigateur, ce qui peut être utile pour déboguer.
Installation
Nodejs doit être installé. On tape la commande node -v
pour en être sûr, et l’on crée un projet avec npm
dans un dossier choisi :
1 |
xavier@server:/path/to/project$ npm init -y |
Cela crée un fichier package.json
et un dossier node_modules
. On installe alors puppeteer
:
1 |
xavier@server:/path/to/project$ npm install puppeteer --save |
On crée un fichier javascript exemple.js
dans le dossier project
, qui recevra les instructions.
Prendre un screenshot de la page
On peut ajuster le viewport avec setViewPort()
, attendre un certain temps, histoire que les images soient chargées avec waitForTimeout()
, et prendre un screenshot avec screenshot()
. Les fonctions et options de l’API Puppeteer sont disponible sur le repo github
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
const puppeteer = require('puppeteer'); (async () => { const browser = await puppeteer.launch(); var date = new Date(); date = date.toISOString().slice(0, -8).replace(/[\:\-]/g, ''); const page = await browser.newPage(); try { await page.setViewport({ width: 1200, height: 800, }); await page.goto('https://url/to/page/'); await page.waitForTimeout(6000); await page.screenshot({ type: 'jpeg', path: format + '-' + date + '.jpg' }); console.log(format + '-' + date + '.jpg'); } catch (err) { console.log('error: ', err.message); } finally { await browser.close(); } })(); |
Pour éviter les erreurs de requêtes non prises en charge par Puppeteer, il faut utiliser try
, catch
, finally
. Le bloc finally
sert à fermer le navigateur.
On lance ensuite la commande dans le dossier du projet :
1 |
xavier@server:/path/to/project$ node exemple.js |
La sortie retourne le nom du fichier image qui se trouve dans le dossier du projet.
L’instruction await
est utilisé pour attendre une promesse promise
. Il ne peut être utilisé que dans une fonction asynchrone async
dans le code javascript.
Retourner des éléments de la page evaluate()
La fonction evaluate()
permet de passer en argument une fonction qui retourne une promesse. page.evaluate()
résous la promesse et retourne le résultat. Pour retourner le contenu d’une div
, on sélectionne la div
en javascript, et l’on retourne le contenu :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
(async () => { const browser = await puppeteer.launch(); try { const page = await browser.newPage(); await page.setRequestInterception(true); await page.goto('https://url/to/page'); await page.waitForTimeout(1000); let content = await page.evaluate(() => { const mydiv = document.getElementById('mydiv'); let content = '<div class="myclass">'; content += mydiv.innerHTML; content += '</div>' return content }); console.log(content); } catch (e) { console.log('e.message: ', e.message); } finally { await browser.close(); } })(); |
Si l’on veut voir la sortie de la console du navigateur, on peut écrire :
1 2 3 4 5 6 7 |
page .on('console', message => console.log(`${message.type().toUpperCase()} ${message.text()}`)) .on('pageerror', ({ message }) => console.log(message)) .on('response', response => console.log(`${response.status()} ${response.url()}`)) .on('requestfailed', request => console.log(`${request.failure().errorText} ${request.url()}`)); |
Et hop, on peut visiter un site avec un navigateur headless
et en tirer des informations tel un robot.