Wayfair fonctionne avec une tarification dynamique. Un même canapé peut afficher un prix le matin, un autre en soirée et encore un autre le lendemain, le tout piloté par la demande, les stocks et le modèle algorithmique de la plateforme. Pour un acheteur qui attend une bonne affaire ou un analyste qui étudie la catégorie mobilier, ce qui importe n'est pas le prix actuel, mais son évolution dans le temps. Pour observer cette évolution, il faut enregistrer le prix selon un calendrier et conserver un historique.
Ce guide vous montre comment construire un traqueur de prix Wayfair en JavaScript avec Node.js et cheerio. Vous récupérez une page publique de produit ou de catégorie Wayfair via la Crawling API, extrayez le titre et le prix de chaque produit, ajoutez une ligne horodatée à un fichier d'historique et exécutez l'ensemble selon un planning, de sorte que le fichier s'enrichisse progressivement en un journal de prix exploitable sous forme de graphique. Ce tutoriel se limite aux données de listes publiques, et la section sur la légalité en fin d'article est sincère, pas un simple formulaire, alors lisez-la avant de cibler des volumes réels.
Ce que vous allez construire
Un traqueur Node.js qui prend une URL publique de liste Wayfair, récupère le HTML rendu via la Crawling API, analyse chaque fiche produit et écrit un instantané horodaté sur le disque. Exécutez-le une fois et vous obtenez les prix actuels ; exécutez-le selon un planning et le fichier d'historique devient une série temporelle que vous pouvez analyser. Chaque enregistrement contient les champs suivants :
- Timestamp une chaîne ISO indiquant le moment de la prise de vue, la colonne qui transforme les lignes en série temporelle.
- Title le nom du produit lu sur la fiche de listing, par exemple « Mahwah 98'' Chenille Square Arm Sofa ».
- Price le prix tel qu'affiché sur la fiche, comme « $689.99 ».
- URL la page de listing source dont provient l'instantané, ce qui permet de regrouper l'historique par page.
Pourquoi une requête simple échoue sur Wayfair
Si vous demandez une URL de listing Wayfair avec un client HTTP nu, vous obtenez rarement la grille de produits en retour. Deux facteurs jouent contre vous. Premièrement, Wayfair affiche ses fiches de listing dans le navigateur avec JavaScript : le HTML initial est une coquille presque vide tant que les scripts de la page n'ont pas été exécutés, et les prix recherchés se trouvent dans ce rendu dynamique. Deuxièmement, Wayfair détecte le trafic automatisé : les requêtes provenant d'adresses IP de datacenter et les comportements ne ressemblant pas à un vrai navigateur sont mis en défi, limités en débit ou bloqués avant d'atteindre les données produit rendues.
Un traqueur Wayfair fonctionnel a donc besoin de deux choses dans une seule requête : un navigateur qui rend réellement la page et une adresse IP que la plateforme perçoit comme un visiteur réel. Vous pouvez assembler cela vous-même avec un navigateur sans interface graphique et un pool de proxies résidentiels rotatifs, mais relier ces éléments et les maintenir en état représente l'essentiel du travail, et c'est peu adapté à quelque chose que vous souhaitez exécuter sans surveillance sur un minuteur. La Crawling API combine les deux en un seul appel : vous lui envoyez l'URL, elle rend la page derrière une IP fiable et vous renvoie le HTML finalisé à analyser avec cheerio.
Prérequis
Quelques éléments doivent être en place avant d'écrire du code. Aucun n'est long à mettre en oeuvre.
JavaScript et Node.js de base. Vous devez être à l'aise pour écrire et exécuter un script Node, installer des packages avec npm, et travailler avec des variables, des fonctions et des boucles. Si vous débutez avec Node, la documentation officielle et tout cours pour débutants vous amèneront au niveau que ce tutoriel suppose.
Node.js 16 ou ultérieur. Vérifiez votre version avec node --version. Node exécute JavaScript localement, ce qui rend possible un suivi planifié et sans surveillance. Si vous ne l'avez pas encore, 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 depuis la page des docs du compte. Le niveau gratuit vous donne 1 000 requêtes sans carte bancaire, ce qui est largement suffisant pour construire et tester un traqueur. Traitez le token comme un mot de passe : il authentifie vos requêtes, donc ne le placez pas dans le contrôle de version.
Configurer le projet
Créez un dossier de projet, initialisez-le et installez les bibliothèques dont le traqueur a besoin.
node --version mkdir wayfair-price-tracker && cd wayfair-price-tracker npm init -y npm install crawlbase cheerio
Deux dépendances font le travail : crawlbase est le client Node officiel pour la Crawling API, et cheerio analyse le HTML renvoyé avec une API de style jQuery qui permet d'extraire des champs individuels par sélecteur CSS. Le module intégré fs de Node gère l'écriture du fichier d'historique, il n'y a donc rien d'autre à installer. Créez un fichier nommé tracker.js dans ce dossier et ajoutez le code des étapes ci-dessous.
Étape 1 : Récupérer la page Wayfair rendue
Commencez par obtenir la page finalisée. Importez la classe CrawlingAPI, initialisez-la avec votre token et demandez l'URL du listing. Nous utilisons la page de catégorie canapés comme exemple fil conducteur. Vérifier le code de statut avant d'analyser permet de rendre les échecs visibles plutôt que silencieux.
const { CrawlingAPI } = require('crawlbase'); const api = new CrawlingAPI({ token: 'YOUR_CRAWLBASE_TOKEN' }); const wayfairPageURL = 'https://www.wayfair.com/furniture/sb0/sofas-c413892.html'; api .get(wayfairPageURL) .then((response) => { if (response.statusCode === 200) { console.log(response.body.slice(0, 500)); } }) .catch((error) => console.error('API request error:', error));
Exécutez le script avec node tracker.js et vous devriez voir le vrai balisage du listing Wayfair en tête du corps, et non une coquille dépouillée. Cela confirme que le rendu fonctionne avant d'écrire un seul sélecteur. Les pages de meubles de Wayfair sont fortement rendues via JavaScript, c'est donc cette étape de rendu qui fait apparaître les prix dans le HTML renvoyé.
Cette première requête vient de renvoyer une page Wayfair entièrement rendue sans navigateur sans interface graphique ni proxy de votre côté. La Crawling API exécute la page dans un vrai navigateur, fait tourner les IPs résidentielles côté serveur et gère les défis que Wayfair impose aux scrapers, de sorte que vous obtenez le HTML finalisé en un seul appel, ce qui est exactement ce dont un traqueur planifié a besoin pour fonctionner sans surveillance. Testez-la sur la page des canapés avec le niveau gratuit en premier.
Étape 2 : Extraire le titre et le prix avec cheerio
Avec le HTML rendu en main, chargez-le dans cheerio et parcourez les fiches produit. Wayfair dispose chaque produit dans un conteneur répétitif marqué data-hb-id="Card", vous sélectionnez donc chaque fiche, puis vous lisez le titre et le prix à l'intérieur. Pour trouver ces éléments vous-même sur une page en direct, faites un clic droit sur un produit et choisissez « Inspecter », puis recherchez l'élément de fiche et les attributs qui étiquettent le nom et le prix. Les champs ci-dessous sont ceux que Wayfair expose via des attributs data-test-id.
const cheerio = require('cheerio'); function parseProducts(html) { const $ = cheerio.load(html); const products = []; // Each listing sits in a card container $('div[data-hb-id="Card"]').each((index, element) => { const card = $(element); let productName = card .find('p[data-test-id="ListingCard-ListingCardName-Text"]') .text() .trim(); const productPrice = card .find('span[data-test-id="PriceDisplay"]') .text() .trim(); // Fall back to a label when the name is missing if (productName === '') { productName = 'Name is not available'; } if (productPrice) { products.push({ title: productName, price: productPrice }); } }); return products; }
Quelques détails garantissent la fidélité à la page. Le nom du produit provient de l'élément p[data-test-id="ListingCard-ListingCardName-Text"], et le prix de l'élément span[data-test-id="PriceDisplay"]. La méthode .text() récupère le texte interne et .trim() supprime les espaces environnants pour obtenir une valeur propre comme « $689.99 ». Lorsqu'une fiche n'a pas de nom lisible, l'analyseur substitue « Name is not available » plutôt que d'abandonner la ligne, ce qui correspond à la façon dont Wayfair affiche parfois les emplacements publicitaires ou sponsorisés sans titre standard.
Les attributs de Wayfair (data-hb-id, les valeurs data-test-id) sont liés à son build front-end et peuvent changer sans préavis. Considérez les sélecteurs ci-dessus comme un modèle de départ, non comme un contrat. Quand un champ revient vide, réinspectez la page en direct dans les outils de développement de votre navigateur et mettez à jour le sélecteur. La maintenance périodique des sélecteurs est normale pour tout traqueur en production, ce n'est pas le signe que quelque chose est cassé.
Étape 3 : Enregistrer les prix dans le temps au format JSON
C'est l'étape qui transforme un scraping ponctuel en traqueur. Au lieu d'écraser un fichier à chaque exécution, vous lisez l'historique existant, ajoutez le nouvel instantané avec un horodatage et réécrivez l'enregistrement combiné. Chaque exécution ajoute un lot de lignes estampillées du moment où elle s'est déroulée, de sorte que le fichier accumule un historique de prix que vous pouvez représenter graphiquement ou comparer ultérieurement.
const fs = require('fs'); const HISTORY_FILE = 'price-history.json'; function loadHistory() { if (!fs.existsSync(HISTORY_FILE)) return []; return JSON.parse(fs.readFileSync(HISTORY_FILE, 'utf-8')); } function appendSnapshot(products, pageUrl) { const timestamp = new Date().toISOString(); const rows = products.map((p) => ({ timestamp, title: p.title, price: p.price, url: pageUrl, })); const history = loadHistory(); history.push(...rows); fs.writeFileSync(HISTORY_FILE, JSON.stringify(history, null, 2)); console.log(`Logged ${rows.length} prices at ${timestamp}`); }
L'aide-mémoire loadHistory renvoie un tableau vide à la première exécution, quand le fichier n'existe pas encore, il n'y a donc pas de cas particulier à gérer ailleurs. appendSnapshot estampille chaque ligne d'une même exécution avec le même horodatage ISO, ce qui permet de regrouper facilement une exécution ultérieurement ou de comparer le prix d'un produit entre deux timestamps. Comme chaque ligne porte son url source, vous pouvez suivre plusieurs pages Wayfair dans le même fichier tout en les distinguant lors de l'analyse.
Étape 4 : Assembler le traqueur complet
Reliez maintenant la récupération, l'analyse et l'enregistrement en un script exécutable unique. Voici le traqueur complet : exécutez-le et il enregistre un instantané.
const fs = require('fs'); const { CrawlingAPI } = require('crawlbase'); const cheerio = require('cheerio'); const api = new CrawlingAPI({ token: 'YOUR_CRAWLBASE_TOKEN' }); const HISTORY_FILE = 'price-history.json'; const wayfairPageURL = 'https://www.wayfair.com/furniture/sb0/sofas-c413892.html'; async function crawl(pageUrl) { const response = await api.get(pageUrl); if (response.statusCode === 200) return response.body; console.error(`Request failed: ${response.statusCode}`); return null; } function parseProducts(html) { const $ = cheerio.load(html); const products = []; $('div[data-hb-id="Card"]').each((index, element) => { const card = $(element); let productName = card .find('p[data-test-id="ListingCard-ListingCardName-Text"]') .text() .trim(); const productPrice = card .find('span[data-test-id="PriceDisplay"]') .text() .trim(); if (productName === '') productName = 'Name is not available'; if (productPrice) products.push({ title: productName, price: productPrice }); }); return products; } function loadHistory() { if (!fs.existsSync(HISTORY_FILE)) return []; return JSON.parse(fs.readFileSync(HISTORY_FILE, 'utf-8')); } function appendSnapshot(products, pageUrl) { const timestamp = new Date().toISOString(); const rows = products.map((p) => ({ timestamp, title: p.title, price: p.price, url: pageUrl })); const history = loadHistory(); history.push(...rows); fs.writeFileSync(HISTORY_FILE, JSON.stringify(history, null, 2)); console.log(`Logged ${rows.length} prices at ${timestamp}`); } async function track() { const html = await crawl(wayfairPageURL); if (!html) return; const products = parseProducts(html); appendSnapshot(products, wayfairPageURL); } track();
Exécutez avec node tracker.js. La première exécution crée price-history.json et enregistre les prix actuels des canapés ; chaque exécution ultérieure ajoute un nouveau lot horodaté au même fichier. Les étapes de récupération, d'analyse et d'enregistrement sont chacune petites et indépendantes, ce qui rend le script facile à étendre, par exemple pour suivre une catégorie différente en changeant une seule URL.
À quoi ressemble la sortie
Le fichier d'historique contient un objet par produit par exécution, chacun portant le timestamp, le titre, le prix et l'URL source. Après deux exécutions espacées de quelques heures, un même produit apparaît deux fois avec le même titre et peut-être un prix différent, ce qui est exactement le signal qu'un traqueur est conçu pour capturer.
[ { "timestamp": "2024-03-18T09:00:00.000Z", "title": "Mahwah 98'' Chenille Square Arm Sofa", "price": "$689.99", "url": "https://www.wayfair.com/furniture/sb0/sofas-c413892.html" }, { "timestamp": "2024-03-18T09:00:00.000Z", "title": "Adelmina 88.6'' Upholstered Sofa", "price": "$444.99", "url": "https://www.wayfair.com/furniture/sb0/sofas-c413892.html" }, { "timestamp": "2024-03-18T21:00:00.000Z", "title": "Mahwah 98'' Chenille Square Arm Sofa", "price": "$649.99", "url": "https://www.wayfair.com/furniture/sb0/sofas-c413892.html" } ]
Exporter l'historique en CSV
Le JSON est pratique pour le journal en cours, mais un CSV s'ouvre directement dans Excel ou Google Sheets, où tracer une courbe de prix dans le temps ne prend que quelques clics. Cet utilitaire lit l'historique JSON et écrit un fichier plat price-history.csv avec une ligne par instantané. Il reprend l'approche classique d'écriture des colonnes nom et prix, avec le timestamp ajouté pour que l'historique soit traçable.
const fs = require('fs'); function exportCsv() { const history = JSON.parse(fs.readFileSync('price-history.json', 'utf-8')); const headers = ['timestamp', 'title', 'price', 'url']; const escape = (value) => `"${String(value).replace(/"/g, '""')}"`; const lines = [headers.join(',')]; for (const row of history) { lines.push(headers.map((h) => escape(row[h])).join(',')); } fs.writeFileSync('price-history.csv', lines.join('\n')); console.log(`Exported ${history.length} rows to price-history.csv`); } exportCsv();
L'utilitaire escape encadre chaque champ de guillemets et double les guillemets intégrés, ce qui importe car les titres de produits Wayfair sont longs et contiennent souvent des virgules, des marques de pouce et d'autres signes de ponctuation. Le résultat est une série temporelle propre : une colonne pour le quand, une pour quel produit, une pour le prix, prête à pivoter sur le titre et à tracer la courbe de prix par article. C'est le même modèle que vous utiliseriez pour tout flux de veille tarifaire.
Exécuter selon un planning
Un traqueur n'est utile que s'il fonctionne seul. Deux options simples s'offrent à vous. La plus simple est le planificateur du système d'exploitation : sur macOS ou Linux, une entrée cron exécute le script à intervalle fixe, chaque exécution ajoutant un instantané.
# Open your crontab crontab -e # Run the tracker every day at 9am and 9pm 0 9,21 * * * cd /path/to/wayfair-price-tracker && node tracker.js
Si vous préférez garder le planning dans Node, pour qu'il voyage avec le projet et s'exécute partout où Node tourne, installez node-cron et encapsulez la fonction track existante dans un planning.
// npm install node-cron const cron = require('node-cron'); // At minute 0 of hours 9 and 21, every day cron.schedule('0 9,21 * * *', () => { console.log('Running scheduled price check...'); track(); });
Gardez un intervalle de collecte raisonnable. Deux fois par jour suffit pour capturer la plupart des mouvements de prix de Wayfair sans imposer une charge inutile au site, et un rythme de requêtes calme est également le facteur le plus important pour rester non bloqué. Sur quelques semaines de fonctionnement, le fichier d'historique devient un véritable enregistrement de l'évolution du prix de chaque canapé, ce qui est tout l'intérêt du suivi plutôt que des vérifications ponctuelles. La même série enregistrée s'intègre naturellement dans un outil de comparaison de prix si vous commencez à suivre des listings concurrents aux côtés de ceux de Wayfair.
Rester non bloqué
Même avec le rendu pris en charge, Wayfair surveille le trafic qui ressemble à un scraper, et un traqueur qui fonctionne indéfiniment est plus exposé qu'une exécution ponctuelle. Quelques bonnes pratiques le maintiennent en bonne santé.
- Espacez vos requêtes. Un traqueur n'a pas besoin de collecter souvent. Une exécution toutes les quelques heures capture la tendance de prix et vous maintient bien en dessous de toute limite de débit. Résistez à la tentation de scraper en boucle serrée.
- Misez sur la rotation. Un pool d'IPs résidentielles distribue les requêtes sur de nombreuses adresses d'utilisateurs réels, de sorte qu'aucune ne déclenche une limite ou un défi. La Crawling API gère cela pour vous ; si vous construisez votre propre stack, c'est la partie à soigner.
- Lisez les codes de statut. Un job planifié qui commence à renvoyer des réponses non-200 vous indique que le débit actuel ou le niveau d'IP n'est plus suffisant. Consignez ces réponses et reculez plutôt que de laisser un échec silencieux polluer votre historique avec des lacunes.
Pour le guide complet sur comment maintenir un job longue durée en vie, voyez comment scraper des sites sans être bloqué. Si vous souhaitez étendre la même approche à un autre marché, le guide sur comment scraper les prix Walmart facilement suit le même schéma récupération-puis-analyse pour un autre magasin.
Est-il légal de scraper Wayfair ?
Utiliser un traqueur de prix Wayfair est généralement défendable lorsqu'il surveille uniquement des informations de listing accessibles au public, mais le mot « généralement » fait un vrai travail dans cette phrase. La légalité de votre usage spécifique dépend des conditions de service de Wayfair, de votre juridiction et de ce que vous faites des données. Les conditions de Wayfair restreignent l'accès automatisé, le scraping peut donc aller à l'encontre de ces conditions quelle que soit la prudence de vos outils. Aucun code ici ne change cela ; il ne fait que rendre la partie technique fonctionnelle. Lisez les Conditions d'utilisation de Wayfair et son fichier robots.txt, et traitez les deux comme la limite de ce que vous collectez.
Quelques règles à respecter. Ne collectez que les données publiques sur les produits : le titre et le prix que n'importe qui peut voir sur une page de listing sans compte. Limitez le traqueur à un usage personnel ou de recherche, espacez-le doucement et gardez votre volume de requêtes assez bas pour ne pas solliciter les serveurs de Wayfair. Évitez les données personnelles, y compris tout ce qui est lié à des évaluateurs identifiables au-delà du texte public des avis et des notes affichés sur la page. Ne redistribuez pas les médias protégés par le droit d'auteur de Wayfair, comme les photos de produits, comme s'ils vous appartenaient. Si vous prévoyez de réutiliser les données commercialement, obtenez une permission ou un accord officiel plutôt que de supposer que le silence vaut consentement.
Ce guide est délibérément limité aux prix de listing publics, car c'est la ligne qui maintient le travail défendable. Il ne couvre rien derrière une connexion, les données de compte client ou vendeur, l'historique des commandes, ni aucune tentative de contourner une authentification ou un défi auquel vous n'étiez pas censé faire face. Si votre projet nécessite plus que les listings publics, un accord de données sanctionné avec Wayfair est la voie correcte, non un scraper plus agressif. En cas de doute sur un usage commercial, consultez un conseiller juridique avant de monter en charge.
Points clés
- Le suivi signifie enregistrer dans le temps. La tarification dynamique de Wayfair rend le prix actuel moins utile que la tendance, un traqueur ajoute donc des instantanés horodatés plutôt que d'écraser une valeur unique.
- Wayfair rend les prix côté client. Une requête simple renvoie une coquille vide, vous devez donc rendre la page derrière une IP fiable avant que cheerio puisse lire le titre et le prix.
- La Crawling API fait les deux en un seul appel. Elle rend la page, fait tourner les IPs résidentielles et gère les défis, renvoyant le HTML finalisé, ce qui permet à un traqueur planifié de fonctionner sans surveillance.
-
cheerio extrait les champs. Sélectionnez chaque conteneur
data-hb-id="Card", puis lisez le nom depuis l'élémentListingCard-ListingCardName-Textet le prix depuisPriceDisplay, en anticipant que ces attributs évolueront avec le temps. - Planifiez et restez sur les données publiques. Exécutez deux fois par jour avec cron ou node-cron, exportez l'historique en CSV pour les graphiques et limitez le traqueur aux prix de listing publics qui respectent les CGU et le robots.txt de Wayfair.
Foire aux questions
Qu'est-ce qu'un traqueur de prix Wayfair ?
Un traqueur de prix Wayfair est un petit programme qui enregistre les prix des produits listés sur Wayfair selon un planning et conserve un historique. Au lieu de vérifier un prix manuellement, il récupère la page du listing, lit le titre et le prix de chaque produit, et ajoute une ligne horodatée à un fichier. Au fil du temps, ce fichier devient un journal de prix que vous pouvez représenter graphiquement, vous permettant de voir les fluctuations, de repérer les réductions et de chronométrer un achat autour d'une baisse de prix.
Pourquoi une requête simple renvoie-t-elle des données incomplètes de Wayfair ?
Parce que Wayfair rend ses fiches produit côté client avec JavaScript et met au défi le trafic automatisé. Une requête HTTP brute depuis une IP de datacenter renvoie généralement une coquille presque vide ou une page de blocage plutôt que les fiches de listing, les prix ne sont donc pas dans le HTML que vous récupérez. Pour obtenir une page complète, vous devez la rendre derrière une IP fiable, ce que la Crawling API gère pour vous.
Comment fonctionne la tarification de Wayfair ?
Wayfair utilise un modèle de tarification dynamique influencé par la demande, la disponibilité, la concurrence et son propre système de tarification algorithmique, qui collecte et analyse des données en temps réel. Les vendeurs fixent leurs propres prix, et Wayfair s'ajuste pour rester compétitif, de sorte que le même produit peut afficher des prix différents selon les localisations et même au cours d'une même journée. Cette volatilité est exactement la raison pour laquelle enregistrer les prix selon un planning est plus utile que de les vérifier une seule fois.
Comment puis-je suivre les baisses de prix sur Wayfair ?
Exécutez le traqueur selon un planning pour qu'il ajoute un instantané horodaté à chaque fois, puis comparez le prix d'un produit entre deux timestamps dans le fichier d'historique. Quand un prix ultérieur est inférieur à un prix antérieur pour le même titre, il s'agit d'une baisse. Représenter le CSV dans un tableur rend les baisses évidentes comme des creux dans la courbe de prix, et vous pouvez ajouter une alerte par-dessus les mêmes données une fois l'historique constitué.
Mes sélecteurs renvoient des valeurs vides. Qu'est-ce qui a changé ?
Très certainement le balisage de Wayfair. Les attributs data-hb-id et data-test-id sur lesquels l'analyseur s'appuie sont liés au build front-end de Wayfair et peuvent changer sans préavis, de sorte que les sélecteurs qui fonctionnaient le mois dernier peuvent casser. Réinspectez une page de listing en direct dans les outils de développement de votre navigateur et mettez à jour les sélecteurs. La maintenance périodique des sélecteurs est normale pour tout traqueur en production.
Comment éviter d'être bloqué lors du suivi des prix Wayfair ?
Gardez un intervalle de collecte modéré, quelques fois par jour suffisent pour les tendances de prix, et acheminez les requêtes via des IPs résidentielles rotatives pour qu'aucune adresse unique ne déclenche une limite de débit ou un défi. La Crawling API gère la rotation, un pool d'IPs fiables et la gestion des défis pour vous ; si vous construisez votre propre stack, c'est la partie sur laquelle investir. Surveillez les codes de statut de vos exécutions planifiées et reculez quand vous commencez à voir des réponses non-200.
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.
