Logo Le ReacteurLogo Le Reacteur
Bootcamp
Entreprises
RecruteursÉvénementsBlogPostuler

Tutoriel

L’art du scraping III : Projet Product Hunt

31 juillet, 2017

--- Kévin Lemaire

Le 3ème article de cette série sera l’occasion de revoir l’intégralité des notions abordées dans les 2 précédents tutoriels et d’appréhender la gestion d’une navigation de type ”infinite scroll”.

Pour ceux qui aurait manquer les 2 autres articles, voici les liens :

  • L’art du scraping I : Introduction à PhantomJS & CasperJS
  • L’art du scraping II : Projet LDLC

Vous apprendrez comment :

  • Appréhender la pagination de type “infinite scroll”
  • Scroller une page afin de charger des éléments en ajax
  • Récupérer des éléments texte d’une page

Il s’agit toujours d’un exemple donné à titre éducatif uniquement (😈) !

Les objectifs

Pour ce projet, nous allons choisir une rubrique du site Product Hunt. Ce site met en avant les nouveaux produits hi-tech, tel que des apps, des livres, des podcasts et des objets connectés. C’est d’ailleurs cette dernière catégorie que nous allons utiliser pour l’exemple.

Lien utilisé pour l’exemple : https://www.producthunt.com/topics/wearables?subtopic=232

1 - Charger une page de type “infinite scroll”

crédit

2 - Vérifier que la page et tous les éléments ont été chargés

crédit

3 - Récupérer les titres des produits

crédit

Du code, du code et du code

Pour bien commencer, créons un nouveau fichier JavaScript appelé : producthunt.js qui contiendra notre script.

~ touch producthunt.js

Être un des leurs

Tout comme dans le projet “LDLC”, nous allons personnaliser notre instance casper grâce à la fonction create(). Cette dernière accepte un argument unique, un objet JavaScript standard, contenant tous les paramètres. Pour rappel, cet objet va notamment contenir notre userAgent qui a pour but de faire croire que les requêtes exécutées par notre script sont celles d’un humain.

var casper = require('casper').create({
  verbose: true,
  logLevel: 'error',
  pageSettings: {
    loadImage: false,
    loadPlugins: false,
    userAgent:
      'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.81 Safari/537.36',
  },
});

Le coeur de notre script

Avant de rentrer dans la coeur du sujet, nous allons avoir besoin de 4 variables :

  • L’URL du site que nous allons scraper (url)
  • Un tableau pour stocker les titres des produits (titles)
  • Une variable scrolled pour suivre la hauteur de la page modifiée par les différentes actions de “scroll”
  • Une variable scrollDelta enregistrant la différence de hauteur de la page entre deux “scrolls”, et ainsi déterminer si le bas de la page a été atteint
var url = 'https://www.producthunt.com/topics/wearables?subtopic=232';
var titles = [];
var scrolled = 0;
var scrollDelta = null;

Pour gérer la navigation de type “infinite scroll”, nous allons créer 2 nouvelles variables qui seront complémentaires. La première scrollPage va nous permettre de scroller la page . La seconde isBottomPage va nous permettre de vérifier si la fin de la page est atteint pour éviter de scroller la page indéfiniment - Élémentaire, mon cher Watson.

La variable scrollPage va nous permettre d’atteindre la bas de la page et éventuellement charger de nouveaux produits. Pour cela, nous allons utiliser la fonction scrollToBottom(). Ensuite, nous allons mettre à jour les données contenues dans les variables scrollDelta et scrolled. Un console.log() nous permettra de suivre la progression du “scroll”. Enfin, nous allons appeler notre seconde variable isBottomPage qui nous permettra de vérifier si le bas de la page est atteint.

var scrollPage = function() {
  casper.wait(1000, function() {
    casper.scrollToBottom();
    var newScrolled = casper.evaluate(function() {
      return window.scrollY; // Mesurer la hauteur de la page
    });
    scrollDelta = newScrolled - scrolled;
    scrolled = newScrolled;
    console.log('Hauteur de la page : ', scrolled);
    isBottomPage();
  });
};

La seconde variable isBottomPage va déterminer si un nouveau “scroll” de la page est possible ou pas. Cette opération est assurée en comparant la hauteur de la page entre le dernier et l’avant dernier “scroll” (scrollDelta).

Si la différence est différente de zéro, alors notre variable scrollPage est appelée de nouveau (et ainsi de suite). Dans le cas contraire, nous allons récupérer les titres des produits avec la fonction getTitles() que nous écrirons par la suite.

var isBottomPage = function() {
  casper.then(function() {
    if (scrollDelta != 0) {
      scrollPage();
    } else {
      casper.then(function() {
        this.wait(1000, function() {
          titles = this.evaluate(getTitles);
        });
      });
    }
  });
};

Récupérer les titres des produits

Comme dans le projet “Google”, nous allons faire appel à une fonction permettant de récupérer les éléments contenus sur la page. Cette fois-ci la fonction getTitles() va récupérer tous les sélecteurs ‘.contentdc5c5 .title9ddaf’ qui correspondent aux titres et retourner un tableau avec les éléments texte, grâce à la fonction innerHTML.

function getTitles() {
  var titles = document.querySelectorAll('.content_dc5c5 .title_9ddaf');
  return Array.prototype.map.call(titles, function(e) {
    return e.innerHTML;
  });
}

Initier le script

Dans un premier temps, nous allons charger la page, grâce à la fonction start(), et afficher son titre avec la fonction** getTitle()** (à ne pas confondre avec notre fonction getTitles() !).

casper.start(url, function() {
  this.echo(this.getTitle());
});

Ensuite, nous allons lancer notre fonction scrollToBottom() afin de charger l’intégralité des produits de la page.

scrollToBottom();

Enfin, nous lançons l’exécution du script avec la fonction run() et affichons les résultats avec la fonction echo(). Attention, lorsque nous initions un callback après une fonction run(), il est nécessaire de terminer les instructions avec la fonction exit().

casper.run(function() {
  this.echo(titles.length + ' produits trouvés:');
  this.echo(' - ' + titles.join('\n - ')).exit();
});

Lancer le script

~ casperjs producthunt.js

Le résultat attendu 🤖 :

Wearables topic on Product Hunt
Hauteur de la page :  3077
Hauteur de la page :  5361
Hauteur de la page :  5492
Hauteur de la page :  7769
Hauteur de la page :  7880
Hauteur de la page :  7880
61 produits trouvés:
- Airdog 2
- Hykso 2.0
- Dreem
[...]
- Lumo Lift

crédit

Code complet :

var casper = require('casper').create({
  verbose: true,
  logLevel: 'error',
  pageSettings: {
    loadImage: false,
    loadPlugins: false,
    userAgent:
      'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.81 Safari/537.36',
  },
});
var url = 'https://www.producthunt.com/topics/wearables?subtopic=232';
var titles = [];
var scrolled = 0;
var scrollDelta = null;
var scrollPage = function() {
  casper.wait(1000, function() {
    casper.scrollToBottom();
    var newScrolled = casper.evaluate(function() {
      return window.scrollY; // Mesurer la hauteur de la page
    });
    scrollDelta = newScrolled - scrolled;
    scrolled = newScrolled;
    console.log('Hauteur de la page : ', scrolled);
    isBottomPage();
  });
};
var isBottomPage = function() {
  casper.then(function() {
    if (scrollDelta != 0) {
      scrollPage();
    } else {
      casper.then(function() {
        this.wait(1000, function() {
          titles = this.evaluate(getTitles);
        });
      });
    }
  });
};
function getTitles() {
  var titles = document.querySelectorAll('.content_dc5c5 .title_9ddaf');
  return Array.prototype.map.call(titles, function(e) {
    return e.innerHTML;
  });
}
casper.start(url, function() {
  this.echo(this.getTitle());
});
scrollPage();
casper.run(function() {
  this.echo(titles.length + ' produits trouvés:');
  this.echo(' - ' + titles.join('\n - ')).exit();
});

Si vous souhaitez vous former au JavaScript auprès de passionnés, nous proposons des formations au développement web (React JS) ou mobile (React Native). N’hésitez pas à visiter LeReacteur.io

Kévin Lemaire

Partager l'article

Apprendre à coder

Apprendre à coder : Quelle formation est faite pour vous ?

25 juillet 2019

Xavier Colombel

Apprendre à coder

Apprendre à coder : Quelle formation est faite pour vous ?

25 juillet 2019

Xavier Colombel

Ça y est, 2019 est l’année où vous avez décidé de passer le cap. S’offre alors à vous un choix de formations toutes plus différentes les unes que les autres, que ce soit sur la durée, le mode d’apprentissage, le coût, etc. Bref, il va falloir faire un choix et si possible… le bon : votre avenir professionnel dépend de ça. Mais comment s’y retrouver dans cette jungle digitale ? Je vais essayer de vous donner quelques conseils, le plus objectivement possible.

Le Reacteur

88 rue du Faubourg du Temple

75011 - Paris, France

oi.ruetcaerel@tcatnoc
  • +33 (0)1.79.738.728
  • Déclaration d'activité n° 11755531275

    Référencement DataDock n° 0029509

    Bootcamp

    Developpeur Web et Mobile - Temps PleinDeveloppeur Web et Mobile - Temps Partiel
    Logo Ville de ParisLogo Île de FranceLogo SyntecLogo DatadockLogo Défi Métiers

    2019 © Le Reacteur Tous droits réservés - Made with React