17 avril 2020

Casperjs, pupeetter, nightmarejs scrapping

Par ghaliano

Objectif

L’objectif de ce tutorial est de scrapper les résultats de recherche google en utilisant respectivement, Casperjs, pupeetter, nightmarejs et Playwright en fournissant le code source bien sure 🙂 vous pouvez consulter ce tutorial pour une solution de scrapping pour plsueiurs moteur de recherche

Avez vous dis Scrapping ?

Appelé aussi data-minig, ou bien même l’extraction de contenu Web peut servir un nombre illimité de fins.
Cette discipline de collecte de données automatisée, via des robots d’indexation gagne de plus en plus de succès car Que vous soyez une nouvelle entreprise ou une entreprise en croissance, le scraping Web vous aide à multiplier par 10 la croissance de votre entreprise grâce aux données Web.

Enjeux et problématiques lié au scrapping

Problèmes juridiques

Le débat est toujours ouvert car il n’existe pas à l’heure de l’écriture de l’article, un texte claire qui organise cette discipline et l’affaire HIQ VS LINKEDIN dégouline encore beaucoup d’encre,
à part le débat légale ou illégale, il y’a un autre loyale sur l’intégrité des données à scrapper, de plus la proprieté intelectuelle des données

Problématiques techniques

Des barrières techniques de plus en plus répondu par les proprietaries des sites cibles de scrapping pour protéger leurs données avec se qu’on apelle les antibots, on pourra citer les solutions suivantes
https://datadome.co/ (utilisé par leboncoin)
https://cloudfilt.com/

Les développeurs des bots sont ainsi amené à améliorer leurs scripts de bot pour les faires passer comme des vrai navigateurs web.

Techniques & languages

puppeteer
google data mining
casperjs google
nightmare google
puppeteer google
popularité des différents solution 
de scrapping
Statistiques de popularité des différents solution
de scrapping avec ou sans headless browser

Casperjs

Casperjs

Initialement conçue pour faciliter la mise en place des tests fonctionnels (end to en testing), CasperJS se base sur phantomJS qui est un navigateur web sans tête scriptable avec JavaScript (c’est à dire peut être piloté avec uns script javascript). dans cette article, on s’intéresse seulement au scrapping (Un article sur les tests avec CasperJS est en cours de rédaction ! )

CasperJS pourra être facilement utilisé pour récupérer des données en masse (data-mining) via un syntaxe encore plus user friendly par rapport à son père historique PhantomJS

Installation et configuration

Note importante

Depuis 2019, CasperJS ne semble plus être maintenu.
Pour utiliser casperJS, Installer le binaire casperJS, vous trouverais ici la doc complete d’installation

$ git clone git://github.com/casperjs/casperjs.git
$ cd casperjs
$ ln -sf `pwd`/bin/casperjs /usr/local/bin/casperjs

Exemple d’un script avec CasperJS

Voici un petit snippet de code qui permet de récupérer le résultat d’une recherche google, notant que le script pourra facilement devenir obsolète si google décide changer le UI (User interface) de la page de recherche ou bien de résultat.

var casper = require('casper').create();
var utils = require('utils');

casper.start('https://www.google.com/', function() {
    this.echo(this.getTitle());
    this.fillSelectors('#tsf', {
        'input[name="q"]': "casperjs"
    }, true);
    this.waitForSelector('#foot', function() {
        var links = this.evaluate(function() {
            var links = [];
            __utils__.findAll('h3').forEach(function(a){
                links.push(a.parentNode.getAttribute('href'));
            })

            return links;

        });
        utils.dump(links);
    });
});

casper.run();

Explication

Les deux bous de code les plus importants dans le script sont:

  • this.fillSelectors qui facilite la saisie et l’envoi du formulaire de recherche
  • this.waitForSelector(‘#foot’, function() { permet d’attendre jusqu’a que l’élément avec l’ID foot sera bien chargé dans la page

Puppeteer

pupeetter

Puppeteer est une bibliothèque node qui fournit une API de haut niveau pour contrôler Chrome ou Chromium via le protocole DevTools. Puppeteer fonctionne sans tête (headless) par défaut, mais peut être configuré pour exécuter entièrement Chrome.

Exemple d’un script avec Puppeteer

Toujours la même idée ‘récupérer la liste de résultats d’une recherche google), Le code le plus critique à comprendre et l’aspect synchrone du script géré par async/await

enfaite sans les async/await on devais utiliser des fonction de callback, les async await présente une éléguante solution pour resolver la promesse « Promise » envoyé par async (Rappelons que toute fonction précédé par le môt clé async envoi une « Promise »)

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

    const page = await browser.newPage();
    await page.goto('https://www.google.com/search?q=test');

    //console.log(await page.content());

    const links = await page.evaluate(function() { var links = [];
        document
            .querySelectorAll('h3')
            .forEach(function(a){
                links.push(a.parentNode.getAttribute('href'));
            })

        return links;
    });
    console.log(await links);

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

Nightmare

Nightmare est une bibliothèque d’automatisation de navigateur de haut niveau avec comme objectif principale d’exposer des méthodes simples qui imitent les actions des utilisateurs (comme goto, tapez et cliquez), avec une API qui se sent synchrone pour chaque bloc de script, plutôt que des rappels profondément imbriqués (callback functions). Il est le plus souvent utilisé pour les tests et l’analyse de l’interface utilisateur.

Dans ça cuisine interne, elle utilise Electron, qui est similaire à PhantomJS mais à peu près deux fois plus rapide et plus moderne. voir cette issue github.

Exemple d’un script avec nightmare

const Nightmare = require('nightmare');

const nightmare = Nightmare({
    webPreferences: {javascript: true},
    show: true,
    openDevTools: {
    },
});

nightmare
    .goto('https://www.google.com/search?q=test')
    .useragent('Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36')
    .wait('#foot')
    .evaluate(() => {
        var links = [];
        document.querySelectorAll('h3').forEach((a) => {
            links.push(a.parentNode.getAttribute('href'));
        })

        return links;

    })
    .end()
    .then((links)=>{
        console.log(links);
    })
    .catch(error => {
        console.error('Search failed:', error)
    })

Playwright

En cours de rédaction 😉

Des liens utiles

https://free-proxy-list.net/

Un article intéressant si vous voulez prendre une idée sur le périmètre juridique