Comment créer un grattoir de produit Amazon avec Node.js
Publié: 2022-03-10Avez-vous déjà été dans une position où vous avez besoin de connaître intimement le marché d'un produit particulier ? Peut-être que vous lancez un logiciel et que vous avez besoin de savoir comment le tarifer. Ou peut-être avez-vous déjà votre propre produit sur le marché et souhaitez-vous voir quelles fonctionnalités ajouter pour un avantage concurrentiel. Ou peut-être que vous voulez simplement acheter quelque chose pour vous-même et que vous voulez vous assurer d'obtenir le meilleur rapport qualité-prix.
Toutes ces situations ont une chose en commun : vous avez besoin de données précises pour prendre la bonne décision . En fait, il y a une autre chose qu'ils partagent. Tous les scénarios peuvent bénéficier de l'utilisation d'un web scraper.
Le scraping Web consiste à extraire de grandes quantités de données Web à l'aide de logiciels. Donc, en substance, c'est un moyen d'automatiser le processus fastidieux consistant à appuyer sur "copier" puis "coller" 200 fois. Bien sûr, un bot peut le faire dans le temps qu'il vous a fallu pour lire cette phrase, donc c'est non seulement moins ennuyeux mais aussi beaucoup plus rapide.
Mais la question brûlante est : pourquoi quelqu'un voudrait-il gratter les pages Amazon ?
Vous êtes sur le point de le savoir ! Mais tout d'abord, j'aimerais clarifier quelque chose dès maintenant - bien que le fait de supprimer des données accessibles au public soit légal, Amazon a pris certaines mesures pour l'empêcher sur ses pages. En tant que tel, je vous exhorte à toujours garder à l'esprit le site Web lors du grattage, à ne pas l'endommager et à suivre les directives éthiques.
Lecture recommandée : "Le guide du scraping éthique des sites Web dynamiques avec Node.js et Puppeteer" par Andreas Altheimer
Pourquoi devriez-vous extraire les données produit d'Amazon
Étant le plus grand détaillant en ligne de la planète, il est prudent de dire que si vous voulez acheter quelque chose, vous pouvez probablement l'obtenir sur Amazon. Il va donc sans dire à quel point le site Web est un trésor de données.
Lorsque vous grattez le Web, votre principale question devrait être de savoir quoi faire de toutes ces données. Bien qu'il existe de nombreuses raisons individuelles, cela se résume à deux cas d'utilisation importants : optimiser vos produits et trouver les meilleures offres.
"
Commençons par le premier scénario. À moins que vous n'ayez conçu un nouveau produit vraiment innovant, il y a de fortes chances que vous puissiez déjà trouver quelque chose d'au moins similaire sur Amazon. Le grattage de ces pages de produits peut vous rapporter des données inestimables telles que :
- La stratégie de prix des concurrents
Ainsi, vous pouvez ajuster vos prix pour être compétitifs et comprendre comment les autres gèrent les offres promotionnelles ; - Avis clients
Pour voir ce qui intéresse le plus votre future clientèle et comment améliorer son expérience ; - Fonctionnalités les plus courantes
Pour voir ce que propose votre concurrence pour savoir quelles fonctionnalités sont cruciales et lesquelles peuvent être laissées pour plus tard.
Essentiellement, Amazon a tout ce dont vous avez besoin pour une analyse approfondie du marché et des produits. Vous serez mieux préparé à concevoir, lancer et étendre votre gamme de produits avec ces données.
Le deuxième scénario peut s'appliquer à la fois aux entreprises et aux particuliers. L'idée est assez similaire à ce que j'ai mentionné plus tôt. Vous pouvez gratter les prix, les caractéristiques et les critiques de tous les produits que vous pourriez choisir, et ainsi, vous pourrez choisir celui qui offre le plus d'avantages au prix le plus bas. Après tout, qui n'aime pas les bonnes affaires ?
Tous les produits ne méritent pas ce niveau d'attention aux détails, mais cela peut faire une énorme différence avec des achats coûteux. Malheureusement, bien que les avantages soient clairs, de nombreuses difficultés accompagnent le grattage d'Amazon.
Les défis du scraping des données produit Amazon
Tous les sites Web ne sont pas identiques. En règle générale, plus un site Web est complexe et répandu, plus il est difficile de le gratter. Vous souvenez-vous quand j'ai dit qu'Amazon était le site de commerce électronique le plus important ? Eh bien, cela le rend à la fois extrêmement populaire et raisonnablement complexe.
Tout d'abord, Amazon sait comment agissent les robots de grattage, de sorte que le site Web a mis en place des contre-mesures. À savoir, si le scraper suit un schéma prévisible, en envoyant des requêtes à intervalles fixes, plus rapidement qu'un humain ne le pourrait ou avec des paramètres presque identiques, Amazon remarquera et bloquera l'IP. Les proxies peuvent résoudre ce problème, mais je n'en ai pas eu besoin car nous n'allons pas gratter trop de pages dans l'exemple.
Ensuite, Amazon utilise délibérément différentes structures de page pour ses produits. C'est-à-dire que si vous inspectez les pages de différents produits, il y a de fortes chances que vous trouviez des différences significatives dans leur structure et leurs attributs. La raison derrière cela est assez simple. Vous devez adapter le code de votre scraper pour un système spécifique , et si vous utilisez le même script sur un nouveau type de page, vous devrez en réécrire certaines parties. Donc, ils vous font essentiellement travailler plus pour les données.
Enfin, Amazon est un vaste site Web. Si vous souhaitez collecter de grandes quantités de données, l'exécution du logiciel de grattage sur votre ordinateur peut s'avérer prendre beaucoup trop de temps pour vos besoins. Ce problème est encore renforcé par le fait qu'aller trop vite bloquera votre raclette. Donc, si vous voulez des tonnes de données rapidement, vous aurez besoin d'un grattoir vraiment puissant.
Bon, assez parlé des problèmes, concentrons-nous sur les solutions !
Comment créer un grattoir Web pour Amazon
Pour garder les choses simples, nous allons adopter une approche étape par étape pour écrire le code. N'hésitez pas à travailler en parallèle avec le guide.
Recherchez les données dont nous avons besoin
Alors, voici un scénario : je déménage dans quelques mois dans un nouvel endroit, et j'aurai besoin de quelques nouvelles étagères pour ranger des livres et des magazines. Je veux connaître toutes mes options et obtenir le meilleur accord possible. Alors, allons sur le marché Amazon, recherchons des "étagères", et voyons ce que nous obtenons.
L'URL de cette recherche et la page que nous allons récupérer se trouvent ici.
Ok, faisons le point sur ce que nous avons ici. En jetant un coup d'œil à la page, nous pouvons obtenir une bonne image de :
- à quoi ressemblent les étagères ;
- ce que le forfait comprend ;
- comment les clients les évaluent ;
- leur prix;
- le lien vers le produit ;
- une suggestion pour une alternative moins chère pour certains des articles.
C'est plus que nous pourrions demander !
Obtenez les outils nécessaires
Assurons-nous que tous les outils suivants sont installés et configurés avant de passer à l'étape suivante.
- Chrome
Nous pouvons le télécharger ici. - VSCode
Suivez les instructions de cette page pour l'installer sur votre appareil spécifique. - Node.js
Avant de commencer à utiliser Axios ou Cheerio, nous devons installer Node.js et le Node Package Manager. Le moyen le plus simple d'installer Node.js et NPM est d'obtenir l'un des programmes d'installation de la source officielle de Node.Js et de l'exécuter.
Maintenant, créons un nouveau projet NPM. Créez un dossier pour le projet et exécutez la commande suivante :
npm init -y
Pour créer le web scraper, nous devons installer quelques dépendances dans notre projet :
- Cheerio
Une bibliothèque open source qui nous aide à extraire des informations utiles en analysant le balisage et en fournissant une API pour manipuler les données résultantes. Cheerio nous permet de sélectionner les balises d'un document HTML en utilisant des sélecteurs :$("div")
. Ce sélecteur spécifique nous aide à choisir tous les éléments<div>
sur une page. Pour installer Cheerio, veuillez exécuter la commande suivante dans le dossier des projets :
npm install cheerio
- Axios
Une bibliothèque JavaScript utilisée pour effectuer des requêtes HTTP à partir de Node.js.
npm install axios
Inspecter la source de la page
Dans les étapes suivantes, nous en apprendrons davantage sur la façon dont les informations sont organisées sur la page. L'idée est de mieux comprendre ce que nous pouvons extraire de notre source.
Les outils de développement nous aident à explorer de manière interactive le modèle d'objet de document (DOM) du site Web. Nous utiliserons les outils de développement de Chrome, mais vous pouvez utiliser n'importe quel navigateur Web avec lequel vous êtes à l'aise.
Ouvrons-le en cliquant avec le bouton droit n'importe où sur la page et en sélectionnant l'option "Inspecter":
Cela ouvrira une nouvelle fenêtre contenant le code source de la page. Comme nous l'avons déjà dit, nous cherchons à récupérer les informations de chaque étagère.
Comme nous pouvons le voir sur la capture d'écran ci-dessus, les conteneurs qui contiennent toutes les données ont les classes suivantes :
sg-col-4-of-12 s-result-item s-asin sg-col-4-of-16 sg-col sg-col-4-of-20
Dans l'étape suivante, nous utiliserons Cheerio pour sélectionner tous les éléments contenant les données dont nous avons besoin.
Récupérer les données
Après avoir installé toutes les dépendances présentées ci-dessus, créons un nouveau fichier index.js
et tapons les lignes de code suivantes :
const axios = require("axios"); const cheerio = require("cheerio"); const fetchShelves = async () => { try { const response = await axios.get('https://www.amazon.com/s?crid=36QNR0DBY6M7J&k=shelves&ref=glow_cls&refresh=1&sprefix=s%2Caps%2C309'); const html = response.data; const $ = cheerio.load(html); const shelves = []; $('div.sg-col-4-of-12.s-result-item.s-asin.sg-col-4-of-16.sg-col.sg-col-4-of-20').each((_idx, el) => { const shelf = $(el) const title = shelf.find('span.a-size-base-plus.a-color-base.a-text-normal').text() shelves.push(title) }); return shelves; } catch (error) { throw error; } }; fetchShelves().then((shelves) => console.log(shelves));
Comme nous pouvons le voir, nous importons les dépendances dont nous avons besoin sur les deux premières lignes, puis nous créons une fonction fetchShelves()
qui, à l'aide de Cheerio, récupère tous les éléments contenant les informations de nos produits à partir de la page.
Il itère sur chacun d'eux et le pousse vers un tableau vide pour obtenir un résultat mieux formaté.
La fonction fetchShelves()
ne renverra que le titre du produit pour le moment, alors obtenons le reste des informations dont nous avons besoin. Veuillez ajouter les lignes de code suivantes après la ligne où nous avons défini le title
de la variable .
const image = shelf.find('img.s-image').attr('src') const link = shelf.find('aa-link-normal.a-text-normal').attr('href') const reviews = shelf.find('div.a-section.a-spacing-none.a-spacing-top-micro > div.a-row.a-size-small').children('span').last().attr('aria-label') const stars = shelf.find('div.a-section.a-spacing-none.a-spacing-top-micro > div > span').attr('aria-label') const price = shelf.find('span.a-price > span.a-offscreen').text() let element = { title, image, link: `https://amazon.com${link}`, price, } if (reviews) { element.reviews = reviews } if (stars) { element.stars = stars }
Et remplacez shelves.push(title)
par shelves.push(element)
.
Nous sélectionnons maintenant toutes les informations dont nous avons besoin et les ajoutons à un nouvel objet appelé element
. Chaque élément est ensuite poussé vers le tableau des shelves
pour obtenir une liste d'objets contenant uniquement les données que nous recherchons.
Voici à quoi devrait ressembler un objet d' shelf
avant d'être ajouté à notre liste :
{ title: 'SUPERJARE Wall Mounted Shelves, Set of 2, Display Ledge, Storage Rack for Room/Kitchen/Office - White', image: 'https://m.media-amazon.com/images/I/61fTtaQNPnL._AC_UL320_.jpg', link: 'https://amazon.com/gp/slredirect/picassoRedirect.html/ref=pa_sp_btf_aps_sr_pg1_1?ie=UTF8&adId=A03078372WABZ8V6NFP9L&url=%2FSUPERJARE-Mounted-Floating-Shelves-Display%2Fdp%2FB07H4NRT36%2Fref%3Dsr_1_59_sspa%3Fcrid%3D36QNR0DBY6M7J%26dchild%3D1%26keywords%3Dshelves%26qid%3D1627970918%26refresh%3D1%26sprefix%3Ds%252Caps%252C309%26sr%3D8-59-spons%26psc%3D1&qualifier=1627970918&id=3373422987100422&widgetName=sp_btf', price: '$32.99', reviews: '6,171', stars: '4.7 out of 5 stars' }
Formater les données
Maintenant que nous avons réussi à récupérer les données dont nous avons besoin, c'est une bonne idée de les enregistrer en tant que fichier .CSV
pour améliorer la lisibilité. Après avoir obtenu toutes les données, nous utiliserons le module fs
fourni par Node.js et enregistrerons un nouveau fichier appelé saved-shelves.csv
dans le dossier du projet. Importez le module fs
en haut du fichier et copiez ou écrivez le long des lignes de code suivantes :
let csvContent = shelves.map(element => { return Object.values(element).map(item => `"${item}"`).join(',') }).join("\n") fs.writeFile('saved-shelves.csv', "Title, Image, Link, Price, Reviews, Stars" + '\n' + csvContent, 'utf8', function (err) { if (err) { console.log('Some error occurred - file either not saved or corrupted.') } else{ console.log('File has been saved!') } })
Comme nous pouvons le voir, sur les trois premières lignes, nous formatons les données que nous avons précédemment recueillies en joignant toutes les valeurs d'un objet shelve à l'aide d'une virgule. Ensuite, à l'aide du module fs
, nous créons un fichier appelé saved-shelves.csv
, ajoutons une nouvelle ligne contenant les en-têtes de colonne, ajoutons les données que nous venons de formater et créons une fonction de rappel qui gère les erreurs.
Le résultat devrait ressembler à ceci :
Astuces bonus !
Gratter les applications d'une seule page
Le contenu dynamique devient la norme de nos jours, car les sites Web sont plus complexes que jamais. Pour offrir la meilleure expérience utilisateur possible, les développeurs doivent adopter différents mécanismes de chargement pour le contenu dynamique , ce qui complique un peu notre travail. Si vous ne savez pas ce que cela signifie, imaginez un navigateur dépourvu d'interface utilisateur graphique. Heureusement, il y a Puppeteer - la bibliothèque de nœuds magique qui fournit une API de haut niveau pour contrôler une instance Chrome via le protocole DevTools. Pourtant, il offre les mêmes fonctionnalités qu'un navigateur, mais il doit être contrôlé par programme en tapant quelques lignes de code. Voyons comment cela fonctionne.
Dans le projet créé précédemment, installez la bibliothèque Puppeteer en exécutant npm install puppeteer
, créez un nouveau fichier puppeteer.js
et copiez ou écrivez les lignes de code suivantes :
const puppeteer = require('puppeteer') (async () => { try { const chrome = await puppeteer.launch() const page = await chrome.newPage() await page.goto('https://www.reddit.com/r/Kanye/hot/') await page.waitForSelector('.rpBJOHq2PR60pnwJlUyP0', { timeout: 2000 }) const body = await page.evaluate(() => { return document.querySelector('body').innerHTML }) console.log(body) await chrome.close() } catch (error) { console.log(error) } })()
Dans l'exemple ci-dessus, nous créons une instance Chrome et ouvrons une nouvelle page de navigateur qui est nécessaire pour accéder à ce lien. Dans la ligne suivante, nous disons au navigateur sans tête d'attendre que l'élément avec la classe rpBJOHq2PR60pnwJlUyP0
apparaisse sur la page. Nous avons également spécifié combien de temps le navigateur doit attendre le chargement de la page (2000 millisecondes).
En utilisant la méthode d' evaluate
sur la variable de page
, nous avons demandé à Puppeteer d'exécuter les extraits de code Javascript dans le contexte de la page juste après le chargement final de l'élément. Cela nous permettra d'accéder au contenu HTML de la page et de renvoyer le corps de la page en sortie. Nous fermons ensuite l'instance Chrome en appelant la méthode close
sur la variable chrome
. Le travail résultant doit consister en tout le code HTML généré dynamiquement. C'est ainsi que Puppeteer peut nous aider à charger du contenu HTML dynamique .
Si vous ne vous sentez pas à l'aise avec Puppeteer, notez qu'il existe quelques alternatives, comme NightwatchJS, NightmareJS ou CasperJS. Ils sont légèrement différents, mais au final, le processus est assez similaire.
Définition user-agent
user-agent
est un en-tête de requête qui indique le site Web que vous visitez sur vous-même, à savoir votre navigateur et votre système d'exploitation. Ceci est utilisé pour optimiser le contenu de votre configuration, mais les sites Web l'utilisent également pour identifier les bots envoyant des tonnes de demandes, même si cela change l'IPS.
Voici à quoi ressemble un en user-agent
:
Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.82 Safari/537.36
Afin de ne pas être détecté et bloqué, vous devez régulièrement modifier cet en-tête. Faites très attention à ne pas envoyer un en-tête vide ou obsolète, car cela ne devrait jamais arriver pour un utilisateur ordinaire, et vous vous démarquerez.
Limitation de débit
Les grattoirs Web peuvent collecter du contenu extrêmement rapidement, mais vous devez éviter d'aller à toute vitesse. Il y a deux raisons à cela :
- Trop de demandes en peu de temps peuvent ralentir le serveur du site Web ou même le faire tomber, causant des problèmes au propriétaire et aux autres visiteurs. Cela peut essentiellement devenir une attaque DoS.
- Sans rotation des proxys, cela revient à annoncer à haute voix que vous utilisez un bot , car aucun humain n'enverrait des centaines ou des milliers de requêtes par seconde.
La solution consiste à introduire un délai entre vos requêtes, une pratique appelée « rate limit ». ( C'est assez simple à mettre en œuvre aussi! )
Dans l'exemple Puppeteer fourni ci-dessus, avant de créer la variable body
, nous pouvons utiliser la méthode waitForTimeout
fournie par Puppeteer pour attendre quelques secondes avant de faire une autre requête :
await page.waitForTimeout(3000);
Où ms
est le nombre de secondes que vous voudriez attendre.
De plus, si nous voulons faire la même chose pour l'exemple axios, nous pouvons créer une promesse qui appelle la méthode setTimeout()
, afin de nous aider à attendre le nombre de millisecondes souhaité :
fetchShelves.then(result => new Promise(resolve => setTimeout(() => resolve(result), 3000)))
De cette façon, vous pouvez éviter de mettre trop de pression sur le serveur ciblé et aussi, apporter une approche plus humaine du web scraping.
Réflexions finales
Et voilà, un guide étape par étape pour créer votre propre grattoir Web pour les données produit Amazon ! Mais rappelez-vous, ce n'était qu'une situation. Si vous souhaitez gratter un site Web différent, vous devrez apporter quelques modifications pour obtenir des résultats significatifs.
Lecture connexe
Si vous souhaitez toujours voir plus de web scraping en action, voici quelques lectures utiles pour vous :
- "Le guide ultime du scraping Web avec JavaScript et Node.Js", Robert Sfichi
- "Grattage Web Node.JS avancé avec Puppeteer", Gabriel Cioci
- "Python Web Scraping : Le guide ultime pour créer votre scraper", Raluca Penciuc