Le Reacteur - LogoLe Reacteur - Logo
Postuler
Tutoriel pour apprendre à scrapper

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 auraient manqué les 2 autres articles, voici les liens :

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”

Tutoriel apprendre à scrapper

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

Tutoriel apprendre à scrapper

3 - Récupérer les titres des produits

Tutoriel apprendre à scrapper

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 le cœur 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 le 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

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

illustration de l'article de blog

Reconversion professionnelle

Bootcamp : ce qu'il faut savoir avant de se lancer

09 mars 2023

Xavier Colombel

Reconversion professionnelle

Bootcamp : ce qu'il faut savoir avant de se lancer

09 mars 2023

Xavier Colombel

En toute transparence, et parce que je veux pouvoir regarder nos élèves dans les yeux, voici les choses que d'autres se garderont de vous dire.

Le Reacteur

55, Rue Etienne Marey

75020 - Paris, France

oi.ruetcaerel@tcatnoc+33 (0)1.79.738.728

Déclaration d'activité n°11755531275

Référencement DataDock n°0029509

Formations

Développeur Web et Web Mobile - E-LearningDeveloppeur Web et Mobile - Temps PleinDeveloppeur Web et Mobile - Temps PartielDeveloppeur Web et Mobile - AlternancePréparation HTML/CSS/JS - Formation gratuite
Logo Ville de ParisLogo Île de FranceLogo NumeumLogo DatadockLogo Défi MétiersLogo La French Tech

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