Le fait de ne connaßtre qu'une seule approche du grattage Web résout le problÚme à court terme, mais toutes les méthodes ont leurs forces et leurs faiblesses. La prise de conscience de cela fait gagner du temps et aide à résoudre le problÚme plus efficacement.

De nombreuses ressources parlent de la seule véritable méthode de récupération des données d'une page Web. Mais la réalité est que pour cela, vous pouvez utiliser plusieurs solutions et outils.
- Quelles sont les options de récupération par programme des données d'une page Web?
- Avantages et inconvénients de chaque approche?
- Comment utiliser les ressources cloud pour augmenter le degré d'automatisation?
L'article aidera à obtenir des réponses à ces questions.
Je suppose que vous savez déjà ce que sont
les requĂȘtes
HTTP ,
DOM (Document Object Model),
HTML , les
sélecteurs CSS et
Async JavaScript .
Sinon, je vous conseille de vous plonger dans la théorie, puis de revenir à l'article.
Contenu statique
Sources HTMLCommençons par l'approche la plus simple.
Si vous envisagez de supprimer des pages Web, c'est la premiÚre chose à commencer. Il nécessitera peu de puissance informatique et un minimum de temps.
Cependant, cela ne fonctionne que si le code source HTML contient les données que vous ciblez. Pour tester cela dans Chrome, cliquez avec le bouton droit sur la page et sélectionnez Afficher le code de page. Vous devriez maintenant voir le code source HTML.
Une fois que vous avez trouvé les données, écrivez un
sélecteur CSS qui appartient à l'élément d'habillage afin d'avoir un lien plus tard.
Pour l'implĂ©mentation, vous pouvez envoyer une requĂȘte HTTP GET Ă l'URL de la page et rĂ©cupĂ©rer le code source HTML.
Dans
Node, vous pouvez utiliser l'outil
CheerioJS pour
analyser du code HTML brut et récupérer des données à l'aide d'un sélecteur. Le code ressemblera à ceci:
const fetch = require('node-fetch'); const cheerio = require('cheerio'); const url = 'https://example.com/'; const selector = '.example'; fetch(url) .then(res => res.text()) .then(html => { const $ = cheerio.load(html); const data = $(selector); console.log(data.text()); });
Contenu dynamique
Dans de nombreux cas, vous ne pouvez pas accĂ©der aux informations Ă partir du code HTML brut car le DOM Ă©tait contrĂŽlĂ© par JavaScript exĂ©cutĂ© en arriĂšre-plan. Un exemple typique de ceci est un SPA (application d'une seule page), oĂč un document HTML contient un minimum d'informations et JavaScript le remplit au moment de l'exĂ©cution.
Dans cette situation, la solution consiste Ă crĂ©er le DOM et Ă exĂ©cuter les scripts situĂ©s dans le code source HTML, comme le fait le navigateur. AprĂšs cela, les donnĂ©es peuvent ĂȘtre extraites de cet objet Ă l'aide de sĂ©lecteurs.
Navigateurs sans tĂȘteLe navigateur sans tĂȘte est le mĂȘme qu'un navigateur normal, mais sans interface utilisateur. Il s'exĂ©cute en arriĂšre-plan et vous pouvez le contrĂŽler par programme au lieu de cliquer et de taper Ă partir du clavier.
Puppeteer est l' un des navigateurs sans tĂȘte les plus populaires. Il s'agit d'une bibliothĂšque de nĆuds facile Ă utiliser qui fournit une API de haut niveau pour gĂ©rer Chrome hors connexion. Il peut ĂȘtre configurĂ© pour fonctionner sans en-tĂȘte, ce qui est trĂšs pratique lors du dĂ©veloppement. Le code suivant fait la mĂȘme chose qu'auparavant, mais il fonctionnera avec les pages dynamiques:
const puppeteer = require('puppeteer'); async function getData(url, selector){ const browser = await puppeteer.launch(); const page = await browser.newPage(); await page.goto(url); const data = await page.evaluate(selector => { return document.querySelector(selector).innerText; }, selector); await browser.close(); return data; } const url = 'https://example.com'; const selector = '.example'; getData(url,selector) .then(result => console.log(result));
Bien sûr, vous pouvez faire des choses plus intéressantes avec Puppeteer, alors consultez la
documentation . Voici un extrait de code qui navigue dans l'URL, prend une capture d'écran et l'enregistre:
const puppeteer = require('puppeteer'); async function takeScreenshot(url,path){ const browser = await puppeteer.launch(); const page = await browser.newPage(); await page.goto(url); await page.screenshot({path: path}); await browser.close(); } const url = 'https://example.com'; const path = 'example.png'; takeScreenshot(url, path);
Le navigateur nécessite beaucoup plus de puissance de calcul que d'envoyer une simple demande GET et d'analyser la réponse. Par conséquent, l'exécution est relativement lente. Non seulement cela, mais l'ajout d'un navigateur en tant que dépendance rend le package massif.
En revanche, cette mĂ©thode est trĂšs flexible. Vous pouvez l'utiliser pour parcourir les pages, simuler les clics, les mouvements de la souris et utiliser le clavier, remplir des formulaires, crĂ©er des captures d'Ă©cran ou crĂ©er des pages PDF, exĂ©cuter des commandes dans la console, sĂ©lectionner des Ă©lĂ©ments pour extraire du contenu texte. Fondamentalement, tout ce qui peut ĂȘtre fait manuellement dans un navigateur.
Construire un DOMVous penserez qu'il n'est pas nécessaire de simuler un navigateur entier juste pour créer un DOM. En fait, c'est vrai, du moins dans certaines circonstances.
Jsdom est une bibliothĂšque de nĆuds qui analyse le HTML en cours de transmission, tout comme le fait un navigateur. Cependant, ce n'est pas un navigateur, mais un
outil pour construire le DOM à partir d'un code source HTML donné , ainsi que pour exécuter du code JavaScript dans ce HTML.
GrĂące Ă cette abstraction, Jsdom peut fonctionner plus rapidement qu'un navigateur sans tĂȘte. Si c'est plus rapide, pourquoi ne pas l'utiliser tout le temps Ă la place des navigateurs sans tĂȘte?
Citation de la documentation :
Les gens ont souvent des problÚmes avec le chargement asynchrone des scripts lors de l'utilisation de jsdom. De nombreuses pages chargent les scripts de maniÚre asynchrone, mais il est impossible de déterminer quand cela s'est produit, et donc quand exécuter le code et vérifier la structure DOM résultante. Il s'agit d'une limitation fondamentale.
Cette solution est illustrée dans l'exemple. Toutes les 100 ms, il est vérifié si un élément est apparu ou un timeout s'est produit (aprÚs 2 secondes).
Il donne également souvent des messages d'erreur lorsque Jsdom n'implémente pas certaines fonctionnalités du navigateur sur la page, telles que: "
Erreur: Non implĂ©mentĂ©: window.alert ..." ou "Erreur: Non implĂ©mentĂ©: window.scrollTo ... ". Ce problĂšme peut Ă©galement ĂȘtre rĂ©solu avec certaines solutions de contournement (
consoles virtuelles ).
Il s'agit gĂ©nĂ©ralement d'une API de niveau infĂ©rieur Ă Puppeteer, vous devez donc implĂ©menter certaines choses vous-mĂȘme.
Cela complique un peu l'utilisation, comme le montre l'exemple.
Jsdom propose une solution rapide pour le mĂȘme travail.
Regardons le mĂȘme exemple, mais en utilisant
Jsdom :
const jsdom = require("jsdom"); const { JSDOM } = jsdom; async function getData(url,selector,timeout) { const virtualConsole = new jsdom.VirtualConsole(); virtualConsole.sendTo(console, { omitJSDOMErrors: true }); const dom = await JSDOM.fromURL(url, { runScripts: "dangerously", resources: "usable", virtualConsole }); const data = await new Promise((res,rej)=>{ const started = Date.now(); const timer = setInterval(() => { const element = dom.window.document.querySelector(selector) if (element) { res(element.textContent); clearInterval(timer); } else if(Date.now()-started > timeout){ rej("Timed out"); clearInterval(timer); } }, 100); }); dom.window.close(); return data; } const url = "https://example.com/"; const selector = ".example"; getData(url,selector,2000).then(result => console.log(result));
Rétro-ingénierieJsdom est une solution rapide et facile, mais vous pouvez la rendre encore plus simple.
Faut-il modéliser le DOM?
La page Web que vous souhaitez supprimer est constituĂ©e des mĂȘmes HTML et JavaScript, les mĂȘmes technologies que vous connaissez dĂ©jĂ . Ainsi,
si vous trouvez un morceau de code Ă partir duquel les donnĂ©es cibles ont Ă©tĂ© obtenues, vous pouvez rĂ©pĂ©ter la mĂȘme opĂ©ration pour obtenir le mĂȘme rĂ©sultat .
Pour simplifier les choses, les donnĂ©es que vous recherchez pourraient ĂȘtre:
- une partie du code source HTML (comme on peut le voir dans la premiĂšre partie de l'article),
- partie d'un fichier statique référencé dans un document HTML (par exemple, une ligne dans un fichier javascript),
- rĂ©ponse Ă une requĂȘte rĂ©seau (par exemple, du code JavaScript a envoyĂ© une requĂȘte AJAX Ă un serveur qui a rĂ©pondu avec une chaĂźne JSON).
Ces sources de donnĂ©es sont accessibles Ă l'aide de requĂȘtes rĂ©seau . Peu importe si la page Web utilise HTTP, WebSockets ou tout autre protocole de communication, car ils sont tous reproductibles en thĂ©orie.
Une fois que vous avez trouvĂ© une ressource contenant des donnĂ©es, vous pouvez envoyer une demande rĂ©seau similaire au mĂȘme serveur que la page d'origine. En consĂ©quence, vous obtiendrez une rĂ©ponse contenant les donnĂ©es cibles, qui peuvent ĂȘtre facilement extraites en utilisant des expressions rĂ©guliĂšres, des mĂ©thodes de chaĂźne, JSON.parse, etc.
En termes simples, vous pouvez utiliser la ressource sur laquelle se trouvent les donnĂ©es, au lieu de traiter et de charger tout le matĂ©riel. Ainsi, le problĂšme montrĂ© dans les exemples prĂ©cĂ©dents peut ĂȘtre rĂ©solu avec une seule requĂȘte HTTP au lieu de contrĂŽler un navigateur ou un objet JavaScript complexe.
Cette solution semble simple en théorie, mais dans la plupart des cas, elle peut prendre du temps et nécessite une expérience avec les pages Web et les serveurs.
Commencez par surveiller le trafic réseau. Un excellent outil pour cela est l'onglet
Réseau dans Chrome DevTools . Vous verrez toutes les demandes sortantes avec des réponses (y compris les fichiers statiques, les demandes AJAX, etc.) pour les parcourir et rechercher des données.
Si la rĂ©ponse est modifiĂ©e par un code quelconque avant d'ĂȘtre affichĂ©e Ă l'Ă©cran, le processus sera plus lent. Dans ce cas, vous devez trouver cette partie du code et comprendre ce qui se passe.
Comme vous pouvez le voir, une telle méthode peut nécessiter beaucoup plus de travail que les méthodes décrites ci-dessus. En revanche, il offre les meilleures performances.
Le diagramme montre la durée d'exécution et la taille de paquet requises par rapport à Jsdom et Puppeteer:

Les résultats ne sont pas basés sur des mesures précises et peuvent varier, mais montrent de bonnes différences approximatives entre ces méthodes.
Intégration de services cloud
Supposons que vous ayez implémenté l'une de ces solutions. Une façon d'exécuter le script consiste à allumer l'ordinateur, à ouvrir le terminal et à le démarrer manuellement.
Mais cela deviendra ennuyeux et inefficace, il serait donc préférable de simplement télécharger le script sur le serveur et d'exécuter le code réguliÚrement en fonction des paramÚtres.
Pour ce faire, démarrez le serveur réel et définissez les rÚgles d'exécution du script. Dans d'autres cas, la fonction cloud est un moyen plus simple.
Les fonctions cloud sont des stockages conçus pour exécuter du code téléchargé lorsqu'un événement se produit. Cela signifie que vous n'avez pas besoin de gérer les serveurs, cela se fait automatiquement par votre fournisseur de cloud.
Un dĂ©clencheur peut ĂȘtre une planification, une demande rĂ©seau et de nombreux autres Ă©vĂ©nements. Vous pouvez enregistrer les donnĂ©es collectĂ©es dans une base de donnĂ©es, les Ă©crire sur une
feuille Google ou les envoyer par
e-mail . Tout dépend de votre imagination.
Fournisseurs de cloud populaires -
Amazon Web Services (AWS),
Google Cloud Platform (GCP) et
Microsoft Azure :
Vous pouvez utiliser ces services gratuitement, mais pas pour longtemps.
Si vous utilisez Puppeteer,
les fonctionnalités de Google Cloud sont la solution la plus simple. La taille du package au format Headless Chrome (~ 130 Mo) dépasse la taille d'archive maximale autorisée dans AWS Lambda (50 Mo). Il existe plusieurs méthodes pour le faire fonctionner avec Lambda, mais les fonctions GCP
prennent en charge par défaut
Chrome sans en-tĂȘte , il vous suffit d'inclure Puppeteer comme dĂ©pendance dans
package.json .
Si vous souhaitez en savoir plus sur les fonctionnalités du cloud en général, consultez les informations sur l'architecture sans serveur. De nombreux bons didacticiels ont déjà été écrits sur ce sujet, et la plupart des fournisseurs ont une documentation facile à comprendre.