Tutoriel Google Puppeteer : 12 exemples de code

Tutoriel Google Puppeteer : 12 exemples de code

Bonjour! Dans ce tutoriel je vais vous montrer 12 exemples intéressants que vous pourriez faire avec Google Puppeteer : L’API créée par l’équipe Google Chrome Lab qui permet de manipuler un navigateur sans tête (headless). Scrapper des données sur le web, tester vos interfaces utilisateurs, faire le rendu de votre site pour vérifier des aspects liés au SEO : sont des cas d’utilisation couverts dans cet article. Vous souhaitez savoir ce que c’est Puppeteer et comment l’installer ? Allez à la fin de l’article. Maintenant, regardons les exemples de code et les cas d’utilisation :

Tutorial Puppeteer, exemples de codes :

1.Visiter un site internet :

La première chose basique qu’on peut faire avec Puppeteer c’est de visiter un site web. setViewport permet de définir la résolution de l’écran (1280 X 800).

const puppeteer = require('puppeteer'); 
puppeteer.launch().then(async browser => { const page = await browser.newPage();
await page.setViewport({ width: 1280, height: 800 })
await page.goto('https://www.aymen-loukil.com');
await browser.close(); });

Vous lancez l’exécution du script et rien ne se passe. C’est normal car n’oubliez pas Puppeteer est en mode sans tête (sans interface utilisateur) par default. Pour voir ce que Puppeteer fait, il faut donc expliciter avec l’option {headless:false}

puppeteer.launch({headless: false}).then(async browser => {

Oh super ! on voit Google Chrome (Chromium) qui s’affiche et qui charge mon site.

2.Prendre une impression d’écran (screenshot) :

Maintenant voyons comment prendre un impression écran avec Google Puppeteer.

const puppeteer = require('puppeteer'); 
puppeteer.launch({headless: false}).then(async browser => { const page = await browser.newPage();
await page.setViewport({ width: 1280, height: 800 })
await page.goto('https://www.aymen-loukil.com');
await page.screenshot({ path: 'myscreenshot.png', fullPage: true });
await browser.close(); });

page.Screenshot() peut prendre quelques paramètres. fullPage est utile pour avoir une impression écran en plein écran. Et si je veux prendre une région spécifique de la page ? Un exemple de cas d’utilisation, je veux automatiser le screenshotting du header d’Amazon (navigation) pour des raisons de tests : C’est possible avec le paramètre ‘Clip’. Il suffit de préciser les coordonnées x, y et la largeur et la hauteur.

const puppeteer = require('puppeteer');  
const options = { path: 'amazon-header.png', fullPage: false, clip: { x: 0, y: 0, width: 1280, height: 150 } } puppeteer.launch().then(async browser => { const page = await browser.newPage();
await page.setViewport({ width: 1280, height: 800 })
await page.goto('https://www.amazon.com');
await page.screenshot(options);
await browser.close(); });

Super !

Amazon header screenshot taken with Puppeteer Google

3.Exemple d’émulation d’un terminal mobile :

Dans cet exemple de Puppeteer, on veut émuler un terminal mobile ensuite prendre un screenshot pour voir le rendu d’une page web. Grâce au « puppeteer/DeviceDescriptors » on peut choisir le terminal d’émulation. Cherchez le terminal dans ce fichier

const puppeteer = require('puppeteer'); const devices = require('puppeteer/DeviceDescriptors'); 
const iPhonex = devices['iPhone X']; puppeteer.launch({headless:false}).then(async browser => { const page = await browser.newPage();

//We use here page.emulate so no more need to set the viewport separately
//await page.setViewport({ width: 1280, height: 800 })

await page.emulate(iPhonex);
await page.goto('https://www.homedepot.com/'); await page.screenshot({ path: 'homedepot-iphoneX.png'});
await browser.close(); });

4. Récupérer le titre d’un page <title>

const puppeteer = require('puppeteer'); 
puppeteer.launch().then(async browser => { const page = await browser.newPage();
await page.goto('https://www.google.com');
const title = await page.title()
console.log(title)
await browser.close(); });

5. Contrôler le clavier :

const puppeteer = require('puppeteer');
const devices = require('puppeteer/DeviceDescriptors');
const iPhonex = devices['iPhone X']; (async () => { const browser = await puppeteer.launch()
const page = await browser.newPage()
await page.emulate(iPhonex);
await page.goto('https://www.google.fr')

await page.focus('#tsf > div:nth-child(2) > div.A7Yvie.emca > div.zGVn2e > div > div.a4bIc > input')
await page.keyboard.type('i am typing using puppeteer !');

await page.screenshot({ path: 'keyboard.png' })
await browser.close() })()

6. Scrapper des liens d’un site :

On va scrapper des liens intéressant depuis Sparktoro Trending portal (Aggrégateur d’articles intéressants dans le marketing) :

const puppeteer = require('puppeteer'); (async () => {  const browser = await puppeteer.launch();   
const page = await browser.newPage();
await page.setExtraHTTPHeaders({Referer: 'https://sparktoro.com/'})
await page.goto('https://sparktoro.com/trending');
await page.waitForSelector('div.title > a');
const stories = await page.evaluate(() => { const links = Array.from(document.querySelectorAll('div.title > a'))
return links.map(link => link.href).slice(0, 10) })
console.log(stories);
await browser.close(); })();

Voici un aperçu :

Sparktoro trending stories

Cool ! Maintenant je vois que vous vous demandez : Comment mettre en place un Proxy pour pouvoir scrapper sereinement ?

const puppeteer = require('puppeteer'); 
(async() => { const browser = await puppeteer.launch({args: [ '--proxy-server=127.0.0.1:3030' ], headless:false});
const page = await browser.newPage();
await page.goto('https://www.amazon.com');
await browser.close(); })();

6.Emuler le WRS de Googleblot pour le SEO :

Màj: Suite à la remarque de Eric Bidelman sur Twitter, cette solution ne fonctionnera pas pour le moment car Chrome 41 est basé sur une ancienne API qui n’est plus compatible avec Puppeteer. Merci pour la clarification Eric! Le principe de l’opération reste intéressant sachant que Googlebot sera bientôt (personne ne sait :p ) mis à jour.

Note : If you install Chrome 41, it will automatically update to latest version. So you should turn off updates as described here : https://support.google.com/chrome/a/answer/187207 and here https://support.google.com/chrome/a/answer/187202?hl=en

Voici comment on demande à Puppeteer à se lancer sur une version bien particulière de Chrome :

const puppeteer = require('puppeteer'); 
const browserFetcher = puppeteer.createBrowserFetcher();
puppeteer.launch({executablePath: 'c:/pathToChrome'}, {headless: false}).then(async browser => { const page = await browser.newPage();
await page.goto('https://www.google.com'); });

Vérifier que votre site est compatible avec Googlebot

Eric Bidelman, ingénieur Google travaillant sur headless Chrome, a publié un script intéressant qui vérifie un site Web par rapport aux fonctionnalités de Google WRS et vous alerte si votre site implémente des éléments non pris en charge. Récupérez le ici : https://github.com/GoogleChromeLabs/puppeteer-examples/blob/master/google_search_features.js.

7.Bloquer des requêtes d’un certain domaine :

Voici une autre chose utile avec Puppeteer: nous pouvons intercepter les requêtes HTTP et en abandonner certaines d’entre elles en fonction de l’URL de la requête, du type de la ressource..etc. Nous pourrions utiliser cette fonctionnalité pour automatiser l’audit de performance des scripts tiers (3rd party). Nous bloquons les scripts et évaluons combien ils coûtent réellement pour la performance d’un site Web.

Dans cet exemple je vais bloquer le CDN images de Amazon

const puppeteer = require('puppeteer'); 
(async() => { const browser = await puppeteer.launch();
const page = await browser.newPage(); await page.setRequestInterception(true);
page.on('request', request => { //lazy way to extract domain from an URL
var match = request.url().replace('http://','').replace('https://','').split(/[/?#]/)[0];
console.log(match);
if (match === 'images-na.ssl-images-amazon.com') request.abort();
else request.continue(); });
await page.goto('https://www.amazon.com'); await page.screenshot({path: 'amazon-noimg.png'});
await browser.close(); })();

Voici à quoi ressemble Amazon sans images :

Amazon without images

8. Désactiver le JavaScript :

Maintenant si le type d’une ressource est ‘script’, on abandonne la requête :

const puppeteer = require('puppeteer');
(async() => { const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.setRequestInterception(true);
page.on('request', request => { if (request.resourceType() === 'script') request.abort();
else request.continue(); });
await page.goto('https://www.youtube.com');
await page.screenshot({path: 'youtube-nojs.png'});
await browser.close(); })();

Voici à quoi ressemble Youtube sans JavaScript. C’est beau!

Youtube without javascript screenshot

9.Récupérer le code source d’une page :

Vous auriez besoin de récupérer la source HTML d’une page chargée? L’API de Puppeteer vous donne cette possibilité avec « page.content () »

const puppeteer = require('puppeteer'); 
const fs = require('fs');
(async() => { const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.goto('https://www.youtube.com', {waitUntil: 'networkidle0'});
const html = await page.content();
//save our html in a file fs.writeFile('page.html', html, _ => console.log('HTML saved'));
//... do some stuff
await browser.close(); })();

10.Utiliser Google Peppeteer pour tester les interfaces utilisateurs :

Discussion on twitter between Aymen Loukil and Bill Slawski

On va tester ici mon formulaire de contact pour vérifier son fonctionnement

const puppeteer = require('puppeteer'); 
(async () => { const browser = await puppeteer.launch({headless:false, slowMo: 100});
const page = await browser.newPage();
//Go to my page and wait until the page loads
await page.goto('https://www.aymen-loukil.com/en/contact-aymen/', {waitUntil: 'networkidle2'}); await page.waitForSelector('#genesis-content > article > header > h1');

//type the name
await page.focus('#wpcf7-f97-p311-o1 > form > p:nth-child(2) > label > span > input')
await page.keyboard.type('PuppeteerBot');

//type the email
await page.focus('#wpcf7-f97-p311-o1 > form > p:nth-child(3) > label > span > input') await page.keyboard.type('PuppeteerBot@mail.com');

//type the message
await page.focus('#wpcf7-f97-p311-o1 > form > p:nth-child(4) > label > span > textarea')
await page.keyboard.type("Hello Aymen ! It is me your PuppeteerBot, i test your contact form !");

//Click on the submit button
await page.click('#wpcf7-f97-p311-o1 > form > p:nth-child(5) > input')
await page.screenshot({ path: 'form.png', fullPage: true }); })();

Le process est simple :

  • Visiter la page
  • Faire focus sur chaque élément du formulaire et taper la data
  • Soumettre le formulaire en cliquant sur le bouton

Note : Voici comment récupérer facilement les sélecteurs sur n’importe quel formulaire web

how to get any web element selector
  • Inspecter l’élément
  • Click droit>Copier le selecteur

Utile mais ponctuel ! On va le cronifier pour qu’il s’exécute une fois toutes les X heures, jours, ..etc

var CronJob = require('cron').CronJob; 
var job = new CronJob({
//runs every monday cronTime: '0 10 * * *', onTick: function() { const puppeteer = require('puppeteer'); (async () => {

//previous script starts here
await page.goto('https://www.aymen-loukil.com/en/contact-aymen/', {waitUntil: 'networkidle2'}); await page.waitForSelector('#genesis-content > article > header > h1');

//type the name
await page.focus('#wpcf7-f97-p311-o1 > form > p:nth-child(2) > label > span > input')
await page.keyboard.type('PuppeteerBot');

//type the email
await page.focus('#wpcf7-f97-p311-o1 > form > p:nth-child(3) > label > span > input') await page.keyboard.type('PuppeteerBot@mail.com');

//type the message
await page.focus('#wpcf7-f97-p311-o1 > form > p:nth-child(4) > label > span > textarea')
await page.keyboard.type("Hello Aymen ! It is me your PuppeteerBot, i test your contact form !");

//Click on the submit button
await page.click('#wpcf7-f97-p311-o1 > form > p:nth-child(5) > input')
await page.screenshot({ path: 'form.png', fullPage: true }); })();

//The previous script end })(); }, start: false, timeZone: 'Europe/London' }); job.start();

Chaque lundi à 10h du matin nous recevrons un testmail de notre formulaire.

11.Automatiser le code coverage :

Un avant dernier exemple utile, vérifier le pourcentage de code (CSS, JS) non utilisé sur une page web. Vous pouvez l’avoir manuellement avec Google Lighthouse ou sur la console de Google Chrome. Cet exemple permet de le faire en automatique, ça peut servir pour l’intégrer à une intégration continue.

const puppeteer = require('puppeteer');
puppeteer.launch().then(async browser => { const page = await browser.newPage();

//start coverage trace
await Promise.all([ page.coverage.startJSCoverage(), page.coverage.startCSSCoverage() ]);
await page.goto('https://www.cnn.com');

//stop coverage trace
const [jsCoverage, cssCoverage] = await Promise.all([ page.coverage.stopJSCoverage(), page.coverage.stopCSSCoverage(), ]);
let totalBytes = 0; let usedBytes = 0;
const coverage = [...jsCoverage, ...cssCoverage];
for (const entry of coverage) { totalBytes += entry.text.length; for (const range of entry.ranges) usedBytes += range.end - range.start - 1; }

const usedCode = ((usedBytes / totalBytes)* 100).toFixed(2);
console.log('Code used by only', usedCode, '%'); await browser.close(); });

Result :

Code coverage audit

12.Créer un tracing de devtools

Dernier exemple permet de générer un ‘tracing Devtools’ en format JSON. On peut par la suite l’importer sur Google Chrome pour auditer des problèmes de performance web.

const puppeteer = require('puppeteer');
const devices = require('puppeteer/DeviceDescriptors');
const iPhonex = devices['iPhone X']; (async () => {
const browser = await puppeteer.launch()
const page = await browser.newPage()
await page.emulate(iPhonex);
//start the tracing
await page.tracing.start({path: 'trace.json',screenshots:true});
await page.goto('https://www.bmw.com')
//stop the tracing
await page.tracing.stop();
await browser.close() })()
Load performance profile Chrome tools

On peut également le visualiser en ligne sur cet outil : https://chromedevtools.github.io/timeline-viewer/

Google Puppeteer :

Puppeteer is utile pour :

  • Scrapper du contenu
  • Automatiser des tâches sur le web
  • Tester des interfaces utilisateur (UI)
  • Tester la compatibilité avec Google Chrome
  • Prendre des impressions d’écran et générer des PDF
  • Identifier des problèmes de performance
  • N’importe quelle tâche faisable avec Google Chrome, la seule limite est votre imagination

L’architecture de Google Puppeteer :

puppeteer architecture
Puppeteer API architecture – [Puppeteer Github repository]


Liens utiles :

Essayez Puppeteer en ligne : https://try-puppeteer.appspot.com/

Documentation : https://pptr.dev/

Laisser un commentaire