web-dev-qa-db-fra.com

Grattez une page Web et naviguez en cliquant sur les boutons

Je souhaite effectuer les actions suivantes côté serveur:

1) Grattez une page Web
2) Simulez un clic sur cette page, puis accédez à la nouvelle page.
3) Grattez la nouvelle page
4) Simulez quelques clics sur la nouvelle page
5) Renvoyer les données au client via json ou quelque chose

Je pense à l'utiliser avec Node.js.

Mais je ne sais pas quel module dois-je utiliser
a) Zombie
b) Node.io
c) Phantomjs
d) JSDOM
e) Autre chose

J'ai installé le noeud, io mais je ne peux pas l'exécuter via l'invite de commande.

PS: je travaille sur le serveur Windows 2008

30
user2129794

Zombie.js et Node.io fonctionnent sur JSDOM, donc vos options vont soit avec JSDOM (ou tout emballage équivalent), un navigateur sans tête (PhantomJS, SlimerJS) ou Cheerio.

  • JSDOM est assez lent car il doit recréer DOM et CSSOM dans Node.js.
  • PhantomJS/SlimerJS sont des navigateurs sans tête appropriés, donc les performances sont correctes et elles sont également très fiables.
  • Cheerio est une alternative légère à JSDOM. Il ne recrée pas la page entière dans Node.js (il télécharge et analyse simplement le DOM - aucun javascript n'est exécuté). Par conséquent, vous ne pouvez pas vraiment cliquer sur les boutons/liens, mais il est très rapide de gratter les pages Web.

Compte tenu de vos besoins, j'irais probablement avec quelque chose comme un navigateur sans tête. En particulier, je choisirais CasperJS parce qu'il a une API agréable et expressive, il est rapide et fiable (il n'a pas besoin de réinventer la roue pour analyser et rendre le dom ou le CSS comme JSDOM fait) et il est très facile d'interagir avec des éléments tels que des boutons et des liens.

Votre flux de travail dans CasperJS devrait ressembler plus ou moins à ceci:

casper.start();

casper
  .then(function(){
    console.log("Start:");
  })
  .thenOpen("https://www.domain.com/page1")
  .then(function(){
    // scrape something
    this.echo(this.getHTML('h1#foobar'));
  })
  .thenClick("#button1")
  .then(function(){
    // scrape something else
    this.echo(this.getHTML('h2#foobar'));
  })
  .thenClick("#button2")
  thenOpen("http://myserver.com", {
    method: "post",
    data: {
        my: 'data',
    }
  }, function() {
      this.echo("data sent back to the server")
  });

casper.run(); 
43
danielepolencic

Réponse courte (en 2019): Utiliser un marionnettiste

Si vous avez besoin d'un navigateur complet (sans tête), utilisez marionnettiste au lieu de PhantomJS car il propose un navigateur Chromium à jour avec un riche API pour automatiser les tâches d'exploration et de raclage du navigateur. Si vous souhaitez uniquement analyser un document HTML (sans exécuter JavaScript à l'intérieur de la page), vous devriez vérifier jsdom et cheerio .

Explication

Des outils comme jsdom (ou cheerio ) lui permettent d'extraire des informations d'un document HTML en l'analysant. Ceci est rapide et fonctionne bien tant que le site Web ne contient pas de JavaScript. Il sera très difficile, voire impossible, d'extraire des informations d'un site Web construit sur JavaScript. jsdom, par exemple, est capable d'exécuter des scripts, mais les exécute à l'intérieur d'un sandbox dans votre environnement Node.js, ce qui peut être très dangereux et éventuellement planter votre application. Pour citer les docs :

Cependant, cela est également très dangereux lorsqu'il s'agit de contenu non approuvé.

Par conséquent, pour explorer de manière fiable des sites Web plus complexes, vous avez besoin d'un navigateur réel. Pendant des années, la solution la plus populaire pour cette tâche était PhantomJS . Mais en 2018, le développement de PhantomJS était officiellement suspend . Heureusement, depuis avril 2017, l'équipe Google Chrome permet d'exécuter le navigateur Chrome sans tête ( annonce ). possibilité d'explorer des sites Web à l'aide d'un navigateur à jour avec prise en charge complète de JavaScript.

Pour contrôler le navigateur, la bibliothèque marionnettiste , qui est également maintenue par les développeurs Google, propose une riche API à utiliser dans le Node environnement .js.

Exemple de code

Les lignes ci-dessous montrent un exemple simple. Il utilise Promises et la syntaxe async/wait pour exécuter un certain nombre de tâches. Tout d'abord, le navigateur démarre ( puppeteer.launch ) et une URL est ouverte page.goto . Après cela, une fonction comme page.evaluate et page.click sont utilisés pour extraire des informations et exécuter des actions sur la page. Enfin, le navigateur est fermé ( browser.close ).

const puppeteer = require('puppeteer');

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

  await page.goto('https://example.com');

  // example: get innerHTML of an element
  const someContent = await page.$eval('#selector', el => el.innerHTML);

  // Use Promise.all to wait for two actions (navigation and click)
  await Promise.all([
    page.waitForNavigation(), // wait for navigation to happen
    page.click('a.some-link'), // click link to cause navigation
  ]);

  // another example, this time using the evaluate function to return innerText of body
  const moreContent = await page.evaluate(() => document.body.innerText);

  // click another button
  await page.click('#button');

  // close brower when we are done
  await browser.close();
})();
3
Thomas Dondorf

Les modules que vous avez répertoriés font ce qui suit:

  • Phantomjs/Zombie - simule le navigateur (sans tête - rien n'est réellement affiché). Peut être utilisé pour gratter statique ou dynamique. Ou test de vos pages html.
  • Node.io/jsdom - webscraping: extraire des données de la page (statique).

En regardant vos besoins, vous pouvez utiliser fantôme ou zombie.

2
user568109