Amazon est l'une des sources les plus riches de données commerciales publiques sur le web : titres de produits, prix, notes, disponibilité et classements des meilleures ventes qui évoluent tout au long de la journée. Extraire ces données une seule fois est utile, mais la vraie valeur apparaît lorsque vous les collectez selon un calendrier, pour suivre l'évolution d'un prix, savoir quand une fiche passe en rupture de stock, ou observer comment un classement progresse sur une semaine. Une seule exécution manuelle ne peut vous dire rien de tout cela.
Ce guide vous montre comment automatiser le scraping Amazon avec JavaScript et Node.js. Vous construirez un scraper qui extrait des données publiques de produits et de recherche via la Crawling API, puis vous l'entourerez des composants qui le rendent autonome : une tâche planifiée qui l'exécute selon un cron, le Crawler asynchrone avec un callback webhook pour les grandes exécutions, un stockage durable des résultats, et une gestion des réessais pour qu'une seule requête ratée ne fasse pas échouer l'ensemble du lot. Nous limitons volontairement la démonstration aux données de produits publiques, et la section sur la légalité vers la fin n'est pas un simple avertissement générique, lisez-la avant de viser un volume réel. Si vous n'avez besoin que d'une extraction ponctuelle, nos guides sur comment scraper les données de produits Amazon et sur comment scraper les meilleures ventes Amazon couvrent le cas d'une seule exécution ; cet article est consacré à les faire tourner automatiquement.
Ce que vous allez construire
Une automatisation Node.js qui scrape des pages de produits et de recherche Amazon publiques selon un calendrier et stocke un enregistrement structuré par exécution. Nous utiliserons une page de résultats de recherche comme exemple fil rouge et extrairons ces champs par article :
- ASIN le numéro d'identification standard Amazon qui identifie de manière unique un produit.
- Titre le nom du produit tel qu'affiché sur la carte.
- Prix le prix affiché tel qu'il apparaît, par exemple "$29.99".
- Note la note moyenne en étoiles lorsqu'elle est présente.
- Avis le nombre d'avis affiché sur la carte.
- URL du produit le lien vers la page du produit individuel.
Autour de ce scraper vous ajouterez quatre composants d'automatisation : un planificateur piloté par cron, une exécution asynchrone avec un callback webhook pour les grandes tâches, un store JSON indexé par horodatage d'exécution, et un wrapper de réessai qui gère les échecs transitoires sans interrompre l'ensemble du lot.
Pourquoi une requête classique échoue sur Amazon
Si vous sollicitez une URL de recherche Amazon avec un client HTTP brut, vous obtenez rarement les données voulues. Amazon rend une grande partie de la page dans le navigateur et challenge agressivement le trafic automatisé. Une adresse IP de datacenter frappant des pages de produits en boucle serrée reçoit un CAPTCHA, un interstitiel "Robot Check", ou un blocage pur et simple bien avant de collecter un échantillon utile. Même lorsqu'une requête réussit, le balisage reçu peut être une coquille dépouillée sans prix ni notes.
Un scraper Amazon fonctionnel a donc besoin de deux éléments réunis en une seule requête : une page qui rend réellement, et une adresse IP que la plateforme perçoit comme un vrai visiteur. Vous pouvez assembler cela vous-même avec un navigateur sans interface graphique et un pool de proxies résidentiels rotatifs, mais connecter ces composants et les maintenir en bonne santé représente l'essentiel du travail, et les choses empirent encore lorsque vous tournez selon un calendrier et que les échecs s'accumulent sans surveillance. La Crawling API les réunit en un seul appel : vous lui envoyez l'URL, elle récupère la page derrière une adresse IP de confiance et rotative, et vous renvoie le HTML final à analyser.
Crawlbase vous donne un token normal et un token JavaScript (JS). Le token normal récupère le HTML statique ; le token JS rend la page dans un vrai navigateur en premier, ce qui coûte plus de crédits. De nombreuses pages de recherche et de produits Amazon s'analysent bien avec le token normal, commencez donc par là et ne passez au token JS que si un champ dont vous avez besoin revient vide.
Prérequis
Quelques éléments doivent être en place avant d'écrire le moindre code. Aucun ne prend longtemps.
JavaScript et Node.js de base. Vous devez être à l'aise pour écrire et exécuter un script Node et installer des paquets avec npm. Si vous débutez avec Node, notre guide sur comment construire un scraper web avec Node.js couvre les bases supposées dans ce tutoriel.
Node.js 16 ou version ultérieure. Vérifiez votre version avec node --version. Si vous ne l'avez pas, installez-le depuis le site Node.js ou via un gestionnaire de versions comme nvm.
Un compte Crawlbase et un token. Inscrivez-vous, ouvrez votre tableau de bord et copiez votre token. Le niveau gratuit inclut jusqu'à 20 000 requêtes sans carte bancaire, ce qui est largement suffisant pour construire et planifier ceci. Traitez le token comme un mot de passe : il authentifie vos requêtes, ne le mettez donc pas dans un dépôt de code et lisez-le depuis une variable d'environnement.
Configurer le projet
Créez un dossier de projet, initialisez-le et installez les bibliothèques nécessaires à l'automatisation.
node --version mkdir amazon-automation && cd amazon-automation npm init -y npm install crawlbase cheerio node-cron
Trois dépendances font le travail : crawlbase est le client Node officiel pour la Crawling API et le Crawler asynchrone, cheerio analyse le HTML renvoyé avec une API de style jQuery pour extraire les champs par sélecteur CSS, et node-cron exécute le scraper selon un calendrier depuis le même processus. Exportez votre token une fois pour que chaque script du dossier puisse le lire :
export CRAWLBASE_TOKEN='YOUR_CRAWLBASE_TOKEN'
Étape 1 : Récupérer et analyser la page de recherche
Commencez par le scraper lui-même, car tout le reste automatise ce cœur. Importez la classe CrawlingAPI, initialisez-la avec votre token, demandez l'URL de recherche et analysez chaque carte de résultat avec cheerio. Vérifier le code de statut avant d'analyser rend les échecs visibles plutôt que silencieux.
const { CrawlingAPI } = require('crawlbase'); const cheerio = require('cheerio'); const api = new CrawlingAPI({ token: process.env.CRAWLBASE_TOKEN }); async function scrapeSearch(searchUrl) { const response = await api.get(searchUrl); if (response.statusCode !== 200) { throw new Error(`Request failed: ${response.statusCode}`); } return parseSearch(response.body); } function parseSearch(html) { const $ = cheerio.load(html); const items = []; $('div[data-asin]').each((_, el) => { const card = $(el); const asin = card.attr('data-asin'); const title = card.find('h2 span').text().trim(); if (!asin || !title) return; items.push({ asin, title, price: card.find('.a-price .a-offscreen').first().text().trim() || null, rating: card.find('.a-icon-alt').first().text().trim() || null, reviews: card.find('.a-size-base.s-underline-text').first().text().trim() || null, productUrl: `https://www.amazon.com/dp/${asin}`, }); }); return items; } const searchUrl = 'https://www.amazon.com/s?k=wireless+headphones'; scrapeSearch(searchUrl).then((items) => { console.log(JSON.stringify(items.slice(0, 3), null, 2)); });
Quelques détails rendent ce code robuste. Amazon appose un attribut data-asin à chaque carte de résultat, c'est l'accroche la plus stable de la page, nous ancrons donc dessus et ignorons toute carte sans ASIN ni titre (les emplacements sponsorisés et les espaceurs de mise en page en ont souvent un mais pas l'autre). Le prix se trouve dans un span caché .a-offscreen qui contient la valeur proprement formatée, ce qui est plus fiable que de scraper le prix visible fractionné. Chaque champ revient à null lorsqu'il est absent, une valeur manquante ne fait donc jamais planter l'exécution. Enregistrez le fichier sous scraper.js et exécutez-le avec node scraper.js ; vous devriez voir un tableau propre d'enregistrements de produits.
Le scraper ci-dessus fonctionne pour une page à la fois, mais une tâche automatisée qui parcourt des centaines de pages Amazon selon un calendrier est là où attendre chaque requête de manière synchrone commence à poser problème. Le Crawler asynchrone prend vos URLs, récupère chacune derrière une adresse IP rotative et de confiance, et pousse les pages finies vers un webhook que vous contrôlez, une exécution planifiée continue donc sans que vous gériez une flotte de navigateurs sans interface ni un pool de proxies. Pointez-le vers des pages publiques sur le niveau gratuit en premier.
Étape 2 : Stocker chaque exécution
L'automatisation n'est utile que si les données persistent, écrivez donc chaque exécution sur disque indexée par un horodatage. Cela vous donne un historique que vous pouvez comparer ultérieurement pour voir comment un prix ou un classement a évolué. Un fichier JSON plat par exécution est le store durable le plus simple et facile à charger dans n'importe quoi d'autre par la suite.
const fs = require('fs'); const path = require('path'); function saveRun(items) { const dir = path.join(__dirname, 'data'); fs.mkdirSync(dir, { recursive: true }); const stamp = new Date().toISOString().replace(/[:.]/g, '-'); const file = path.join(dir, `run-${stamp}.json`); const payload = { scrapedAt: new Date().toISOString(), count: items.length, items }; fs.writeFileSync(file, JSON.stringify(payload, null, 2)); console.log(`Saved ${items.length} items to ${file}`); return file; }
L'horodatage ISO se trie naturellement, lister le répertoire data vous donne donc l'historique des exécutions dans l'ordre. Pour une tâche en production, vous remplaceriez cela par une base de données, mais le contrat est le même : un ensemble d'enregistrements par exécution, horodaté au moment de la collecte. Chaque fichier sauvegardé porte un champ scrapedAt pour qu'une comparaison ultérieure sache exactement à quel moment appartient un prix.
Étape 3 : Ajouter des réessais pour les échecs transitoires
Une tâche planifiée tourne sans surveillance, une seule requête défaillante ne doit donc pas interrompre le lot. Encapsulez la récupération dans un petit wrapper de réessai qui recule entre les tentatives et n'abandonne qu'après quelques essais. La plupart des échecs transitoires (un blocage momentané, un rendu lent, une interruption réseau) se résolvent à la tentative suivante.
function sleep(ms) { return new Promise((resolve) => setTimeout(resolve, ms)); } async function scrapeWithRetry(url, attempts = 3) { for (let i = 1; i <= attempts; i++) { try { return await scrapeSearch(url); } catch (err) { console.warn(`Attempt ${i} failed: ${err.message}`); if (i === attempts) throw err; await sleep(2000 * i); } } }
Le recul multiplie l'attente par le numéro de tentative, les intervalles grandissent donc (2 secondes, puis 4, puis 6) au lieu de marteler une cible qui est déjà en difficulté. Après la dernière tentative, l'erreur est renvoyée, ce qui laisse l'appelant décider de la consigner et de continuer avec le mot-clé suivant ou d'arrêter l'exécution. C'est la différence entre un planificateur qui se remet seul et un que vous devez surveiller.
Étape 4 : Planifier avec cron
Rendez maintenant cela autonome. Le paquet node-cron exécute une fonction selon une expression cron standard depuis votre processus, vous pouvez donc garder le scraper, le store et la logique de réessai au même endroit. Ici nous exécutons la tâche chaque matin à 6h et collectons une liste de mots-clés à chaque fois.
const cron = require('node-cron'); const keywords = ['wireless headphones', 'mechanical keyboard', 'usb c hub']; async function runJob() { console.log(`Run started at ${new Date().toISOString()}`); const all = []; for (const keyword of keywords) { const url = `https://www.amazon.com/s?k=${encodeURIComponent(keyword)}`; try { const items = await scrapeWithRetry(url); all.push(...items.map((it) => ({ ...it, keyword }))); } catch (err) { console.error(`Skipping "${keyword}": ${err.message}`); } await sleep(3000); } saveRun(all); } cron.schedule('0 6 * * *', runJob); console.log('Scheduler running. Daily job at 06:00.');
L'expression 0 6 * * * signifie la minute 0 de l'heure 6, chaque jour. Chaque mot-clé passe par le wrapper de réessai, un mot-clé en échec est consigné et ignoré plutôt que de tuer l'exécution, et une pause de 3 secondes entre les mots-clés maintient un rythme poli. Laissez ce processus tourner (sous un gestionnaire de processus comme pm2 ou un service systemd en production) et il collecte un nouvel instantané chaque matin sans autre intervention. Si vous préférez ne pas maintenir un processus Node actif, supprimez la ligne cron et déclenchez plutôt runJob depuis un crontab système ou une tâche planifiée cloud qui exécute node job.js selon la même expression.
Étape 5 : Passer à l'échelle avec le Crawler asynchrone et un webhook
La boucle synchrone ci-dessus convient pour quelques mots-clés, mais dès qu'une exécution couvre des centaines d'URLs de produits, attendre chaque requête à tour de rôle devient le goulot d'étranglement. Le Crawler asynchrone est conçu pour cela : vous lui poussez des URLs, il récupère chacune derrière une adresse IP de confiance en arrière-plan, et délivre la page finie à un webhook que vous hébergez. Votre planificateur cesse de bloquer sur chaque récupération et se contente d'enqueuer du travail, puis gère les résultats à leur arrivée.
D'abord, enqueueez les URLs. Le client async prend le même token et une URL callback pointant vers votre point de terminaison webhook.
const { CrawlingAPI } = require('crawlbase'); const api = new CrawlingAPI({ token: process.env.CRAWLBASE_TOKEN }); const productUrls = [ 'https://www.amazon.com/dp/B0CHX1W1XY', 'https://www.amazon.com/dp/B09G9FPHY6', ]; async function enqueue() { for (const url of productUrls) { const response = await api.getAsync(url, { callback: 'https://your-server.com/crawlbase-webhook', }); console.log(`Queued ${url} -> rid ${response.json.rid}`); } } enqueue();
Chaque appel renvoie immédiatement un identifiant de requête (rid), la boucle se termine donc rapidement quel que soit le nombre d'URLs enqueueées. Crawlbase effectue la récupération en arrière-plan et, à mesure que chaque page se termine, poste le HTML fini à votre callback. Votre webhook reçoit les pages, les analyse et stocke les résultats, exactement comme le chemin synchrone mais découplé de l'enqueueing.
const express = require('express'); const cheerio = require('cheerio'); const app = express(); app.use(express.text({ type: '*/*', limit: '5mb' })); app.post('/crawlbase-webhook', (req, res) => { const $ = cheerio.load(req.body); const title = $('#productTitle').text().trim(); const price = $('.a-price .a-offscreen').first().text().trim(); if (title) saveRun([{ title, price: price || null }]); res.sendStatus(200); }); app.listen(3000, () => console.log('Webhook listening on 3000'));
L'URL de callback doit être accessible publiquement, pendant le développement exposez donc votre serveur local avec un tunnel comme ngrok et utilisez cette adresse HTTPS comme valeur de callback. Renvoyez toujours un 200 rapidement pour que Crawlbase sache que la page a été reçue ; effectuez l'analyse et le stockage soit avant de répondre, soit dans une tâche en arrière-plan. Pour un regard plus approfondi sur ce schéma, consultez le guide sur l'extraction de données avec le Crawler Crawlbase, qui couvre la file d'attente asynchrone et les callbacks en détail.
À quoi ressemble le résultat
Chaque exécution écrit un seul fichier JSON dans data/, horodaté au moment de la collecte. La forme reste la même que les enregistrements proviennent de la boucle synchrone ou du webhook asynchrone, tout ce qui est en aval lit donc un seul format.
{ "scrapedAt": "2026-06-11T06:00:04.812Z", "count": 2, "items": [ { "asin": "B0CHX1W1XY", "title": "Wireless Over-Ear Headphones, 40H Playtime", "price": "$59.99", "rating": "4.5 out of 5 stars", "reviews": "2,184", "productUrl": "https://www.amazon.com/dp/B0CHX1W1XY", "keyword": "wireless headphones" }, { "asin": "B09G9FPHY6", "title": "Compact Mechanical Keyboard, Hot-Swappable", "price": "$45.99", "rating": "4.4 out of 5 stars", "reviews": "1,073", "productUrl": "https://www.amazon.com/dp/B09G9FPHY6", "keyword": "mechanical keyboard" } ] }
Avec un historique d'exécutions comme celui-ci, l'automatisation porte ses fruits : chargez deux fichiers d'exécution, faites correspondre les articles par ASIN, et vous avez une série prix-dans-le-temps que vous pouvez représenter graphiquement ou sur laquelle déclencher des alertes. Le même store alimente un tracker de meilleures ventes ou un notificateur de changement de stock sans modifier le scraper.
Rester non bloqué
Même avec la Crawling API gérant le rendu et la rotation, une tâche planifiée qui tourne sans surveillance a besoin de bonnes pratiques pour rester en bonne santé sur des semaines, pas seulement lors d'une bonne exécution.
- Cadencez le calendrier, pas seulement la boucle. Tourner toutes les quelques minutes en continu ne ressemble en rien à un humain et consomme rapidement des crédits. Une cadence quotidienne ou horaire est amplement suffisante pour le suivi des prix et des classements, et maintient votre empreinte réduite.
- Laissez la rotation faire son travail. La Crawling API répartit les requêtes sur de nombreuses adresses IP résidentielles pour qu'aucune n'atteigne un seuil de débit. Si vous constituez jamais votre propre pile, c'est la partie à bien soigner, et notre guide sur comment scraper des sites sans se faire bloquer couvre l'ensemble de la stratégie.
- Surveillez les codes de statut dans vos journaux. Une exécution planifiée qui commence à renvoyer des réponses autres que 200 vous indique que quelque chose a changé. Comme la tâche consigne chaque échec et que le wrapper de réessai recule, vous avez un journal plutôt qu'un vide silencieux dans vos données.
Est-il légal d'automatiser le scraping Amazon ?
La légalité du scraping Amazon dépend des conditions d'utilisation d'Amazon, de votre juridiction et de ce que vous faites des données. Les conditions d'Amazon restreignent l'accès automatisé, de sorte que le scraping peut aller à l'encontre de ces conditions quelle que soit la prudence de votre outillage. Aucun des codes présentés ici ne change cela ; il rend simplement la partie technique fonctionnelle. Lisez les Conditions d'utilisation d'Amazon et son fichier robots.txt, et traitez les deux comme la limite de ce que vous collectez.
Quelques lignes directrices à respecter. Collectez uniquement les données publiques de produits : le titre, le prix, la note, le nombre d'avis, l'ASIN et le lien du produit que n'importe qui peut voir sans compte. Respectez les attentes de débit d'Amazon et maintenez votre volume planifié suffisamment bas pour ne pas solliciter excessivement ses serveurs, c'est exactement pourquoi la cadence cron et le rythme de ce guide sont importants. Évitez les données personnelles, y compris tout ce qui est lié à des évaluateurs identifiables au-delà du texte d'avis public sur une page. Si vous envisagez de réutiliser les données commercialement, obtenez une autorisation ou un accord de licence plutôt que de supposer que le silence vaut consentement.
Pour un usage en volume ou commercial, Amazon propose des voies officielles, notamment l'API Product Advertising et l'API Selling Partner côté vendeur, et ce sont les bons outils lorsque vous avez besoin de grands volumes, d'une structure garantie ou de droits commerciaux. Ce guide est délibérément limité aux pages publiques de produits et de recherche car c'est la limite qui rend ce travail défendable. Il ne couvre rien derrière une connexion, les données de compte acheteur ou vendeur, l'historique de commandes, les messages privés, ni aucune tentative de contournement de l'authentification. Si votre projet nécessite plus que des données publiques, les API officielles d'Amazon ou un accord de données sont la bonne voie, non un scraper plus astucieux ou un calendrier plus rapide.
Points clés
- L'automatisation est ce qui rend les données précieuses. Un seul scraping est un instantané ; un scraping planifié vous donne les changements de prix, de classement et de stock dans le temps.
-
La Crawling API gère le rendu et la rotation. Vous ancrez sur les cartes
data-asind'Amazon et extrayez le prix, la note et les avis avec cheerio, tandis que l'API gère les blocages et les adresses IP. - Les réessais et le rythme maintiennent une tâche sans surveillance en bonne santé. Un wrapper de recul récupère des échecs transitoires, et un mot-clé ignoré ne tue jamais l'ensemble de l'exécution.
-
Cron la rend autonome.
node-cronou un planificateur système exécute la tâche selon une expression fixe, et chaque exécution est stockée sous forme de fichier JSON horodaté que vous pouvez comparer. - Le Crawler asynchrone la fait passer à l'échelle. Pour les grands lots, enqueueez des URLs avec un callback webhook pour que la récupération se fasse en arrière-plan au lieu de bloquer votre boucle.
Foire aux questions
Comment planifier l'exécution automatique d'un scraper Amazon ?
Le chemin le plus simple dans Node est node-cron, qui exécute une fonction selon une expression cron standard depuis votre processus. Écrivez votre logique de scrape-et-store comme une seule fonction, puis planifiez-la, par exemple 0 6 * * * pour 6h du matin quotidiennement. Si vous préférez ne pas maintenir un processus Node actif, mettez la même logique dans un script et déclenchez-le depuis un crontab système ou une tâche planifiée cloud selon la même expression.
Quand utiliser le Crawler asynchrone plutôt que des requêtes synchrones ?
Utilisez le Crawler asynchrone dès qu'une exécution couvre de nombreuses URLs et qu'attendre chaque requête à tour de rôle devient le goulot d'étranglement. Vous enqueueez des URLs avec un callback webhook, Crawlbase récupère chaque page en arrière-plan derrière une adresse IP de confiance, et la poste à votre point de terminaison. Les requêtes synchrones sont plus simples et conviennent pour quelques pages par exécution.
Comment gérer les échecs dans une tâche de scraping sans surveillance ?
Encapsulez chaque récupération dans un wrapper de réessai qui recule entre les tentatives et abandonne après quelques essais, puis capturez et consignez un échec au niveau du mot-clé pour qu'une mauvaise requête ignore cet élément plutôt que d'interrompre le lot. Consignez chaque statut non-200 pour que votre exécution laisse un journal. La rotation de la Crawling API prévient déjà la plupart des blocages, les réessais couvrent donc principalement les interruptions transitoires.
Ai-je besoin du token JS pour scraper Amazon ?
Souvent non. De nombreuses pages de recherche et de produits Amazon s'analysent bien avec le token normal, qui coûte moins de crédits. Commencez avec le token normal, et ne passez au token JavaScript (JS) que si un champ dont vous avez besoin revient vide parce qu'il se rend côté client. Utiliser le token moins cher là où il fonctionne maintient une tâche planifiée abordable sur le niveau gratuit.
Où stocker les résultats scrapés ?
Pour une petite tâche, un fichier JSON horodaté par exécution est durable et facile à comparer ultérieurement pour suivre les changements de prix ou de classement. À mesure que le volume augmente, passez à une base de données pour pouvoir interroger efficacement entre les exécutions. Dans les deux cas, maintenez la forme des enregistrements stable et horodatez chaque exécution avec un scrapedAt pour qu'une comparaison ultérieure sache à quel moment appartient une valeur.
Est-il légal d'automatiser le scraping Amazon ?
Automatiser ne change pas les règles ; cela exécute simplement le même scraping de manière répétée, ce qui souligne l'importance du rythme. Restez sur les données publiques de produits, respectez les Conditions d'utilisation et le fichier robots.txt d'Amazon, maintenez votre volume planifié modeste, et évitez les données personnelles et tout ce qui se trouve derrière une connexion. Pour un usage en volume ou une réutilisation commerciale, l'API Product Advertising ou Selling Partner officielle d'Amazon est la voie sanctionnée.
Crawlez n'importe quel site à grande échelle, sans combattre l'infrastructure.
Crawlbase gère les proxies, les empreintes et les CAPTCHA afin que votre équipe livre des pipelines de données au lieu de maintenir la plomberie de crawl. 1 000 requêtes gratuites, sans carte requise.
