Farfetch est l'un des plus grands marchés de mode de luxe, mettant en relation les acheteurs avec des boutiques et des marques haut de gamme à travers des milliers d'annonces de vêtements, chaussures et accessoires. Ses pages de produits publiques portent le type de données qui intéressent les analystes de mode, les suiveurs de prix et les équipes e-commerce : quelles marques sont référencées, quels sont les articles, comment ils sont tarifés et où chacun renvoie. Surveiller ce catalogue dans le temps vous indique comment les produits de luxe sont tarifés par marque et par catégorie et quelles enseignes sont en tendance.

Ce guide vous montre comment extraire des données retail Farfetch avec JavaScript et Node.js en utilisant cheerio. Vous construisez un petit scraper fonctionnel qui récupère une page de liste Farfetch via la Crawling API, analyse la marque, le nom du produit, le prix et le lien de chaque article, gère la pagination et exporte le résultat au format JSON et CSV. L'ensemble du guide se limite aux données publiques de pages de liste de produits, et la section sur la légalité vers la fin n'est pas un texte boilerplate, alors lisez-la avant de l'utiliser à grande échelle.

Ce que vous allez construire

Un script Node.js qui prend une URL de catégorie Farfetch publique, récupère le HTML rendu via la Crawling API, et extrait un enregistrement structuré pour chaque carte de produit sur la liste. Nous utilisons une catégorie de chaussures pour hommes comme exemple de référence et extrayons ces champs par article :

  • Marque le nom de la marque de luxe affiché sur la carte, par exemple « Gucci ».
  • Description le court descriptif du produit qui identifie l'article, comme « Screener leather sneakers ».
  • Prix le prix affiché sur la carte, y compris le symbole de devise.
  • Remise le libellé de remise lorsque l'article est en solde, sinon « N/A ».
  • Lien l'URL absolue vers la page individuelle du produit sur farfetch.com.

Pourquoi une requête simple échoue sur Farfetch

Si vous demandez une URL de catégorie Farfetch avec un client HTTP brut, vous obtenez rarement la grille de produits en retour. Farfetch rend ses cartes de listes dans le navigateur avec JavaScript, de sorte que le HTML initial est une coquille presque vide jusqu'à ce que les scripts de la page s'exécutent. Par-dessus cela, Farfetch surveille le trafic automatisé : les adresses IP de centre de données et les schémas de requêtes qui ne ressemblent pas à un vrai navigateur sont soumis à des défis, limités en débit ou bloqués avant d'atteindre les données de produits rendues.

Un scraper Farfetch fonctionnel a donc besoin de deux choses en une seule requête : un navigateur qui rend effectivement la page, et une IP que la plateforme reconnaît comme un vrai visiteur. Vous pouvez assembler cela vous-même avec un navigateur sans interface et un pool de proxies résidentiels rotatifs, mais les assembler et les maintenir en bon état représente l'essentiel du travail. La Crawling API réunit les deux en un seul appel : vous lui envoyez l'URL, elle rend la page derrière une IP de confiance et retourne le HTML finalisé que vous pouvez analyser avec cheerio.

Attendre le contenu

Comme Farfetch charge sa grille côté client, vous indiquez à la Crawling API d'attendre que le JavaScript se stabilise avant de capturer le HTML. Définissez ajax_wait: 'true' et un page_wait de quelques milliers de millisecondes pour que les cartes de produits soient présentes dans le balisage que vous récupérez. Le rendu utilise le type de requête JavaScript, c'est pourquoi ces listes ont besoin du token JS plutôt que d'une requête simple.

Prérequis

Vous avez besoin de quelques éléments en place avant d'écrire du code. Aucun d'eux ne prend longtemps.

Connaissances de base en JavaScript et Node.js. Vous devez être à l'aise pour écrire et exécuter un script Node et installer des packages avec npm. Si vous débutez avec Node, la documentation officielle et tout cours pour débutants vous amèneront au niveau supposé par ce tutoriel. Le guide sur la construction d'un scraper web avec Node.js est un bon point de départ si vous en voulez un.

Node.js 16 ou version ultérieure. Confirmez votre version avec node --version. Si vous ne l'avez pas, installez-le depuis le site web de 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 vous donne jusqu'à 5 000 requêtes sans carte bancaire. Farfetch nécessite le rendu, utilisez donc votre token JavaScript pour ces requêtes. Traitez le token comme un mot de passe : il authentifie vos requêtes, gardez-le donc en dehors du contrôle de version.

Configurer le projet

Créez un dossier de projet, initialisez-le et installez les deux bibliothèques dont le scraper a besoin.

bash
node --version

mkdir farfetch-scraper && cd farfetch-scraper
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 retourné avec une API de style jQuery afin que vous puissiez extraire des champs individuels par sélecteur CSS. Créez un fichier nommé farfetch-scraper.js dans ce dossier et ajoutez le code des étapes ci-dessous.

Étape 1 : Récupérer la page de liste rendue

Commencez par obtenir la page finalisée. Importez la classe CrawlingAPI, initialisez-la avec votre token et demandez l'URL de catégorie avec les options d'attente pour que les cartes soient rendues avant que le HTML ne soit capturé. Vérifier le code de statut avant d'analyser permet de rendre les échecs visibles plutôt que silencieux.

javascript
const { CrawlingAPI } = require('crawlbase');

const api = new CrawlingAPI({ token: 'YOUR_CRAWLBASE_TOKEN' });

const options = {
  ajax_wait: 'true',    // wait for the JavaScript grid to load
  page_wait: '5000'     // give the page 5 seconds to settle
};

const listingURL =
  'https://www.farfetch.com/shopping/men/shoes-2/items.aspx';

api
  .get(listingURL, options)
  .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 farfetch-scraper.js et vous devriez voir du vrai balisage de produit Farfetch en haut du corps, pas une coquille dépouillée. Cela confirme que le rendu fonctionne avant d'écrire un seul sélecteur. Les options ajax_wait et page_wait sont ce qui donne au temps à la grille côté client de se remplir ; vous pouvez en savoir plus sur les paramètres de requête disponibles dans la documentation de la Crawling API.

Crawlbase Crawling API

Cette première requête vient de retourner une liste Farfetch entièrement rendue sans navigateur sans interface ni proxy de votre côté. La Crawling API exécute la page dans un vrai navigateur, attend que la grille JavaScript se charge avec ajax_wait et page_wait, fait tourner des IPs résidentielles côté serveur et gère les défis que Farfetch envoie aux scrapers, de sorte que vous obtenez le HTML finalisé en un seul appel. Pointez-la vers une catégorie de chaussures pour hommes sur le niveau gratuit d'abord.

Étape 2 : Analyser chaque carte de produit avec cheerio

Avec le HTML rendu en main, chargez-le dans cheerio et parcourez les cartes de produits. Farfetch organise chaque article comme un élément de liste à l'intérieur de la grille du catalogue, vous sélectionnez donc chaque carte, puis lisez la marque, la description, le prix, la remise et le lien depuis l'intérieur. Lire chaque champ de manière défensive évite qu'une valeur manquante ne fasse planter l'exécution.

javascript
const cheerio = require('cheerio');

function parseListings(html) {
  const $ = cheerio.load(html);
  const products = [];

  const cards = $(
    'ul#catalog-grid > li[data-testid="productCard"]'
  );

  cards.each((index, element) => {
    const card = $(element);

    const brand = card
      .find('p[data-component="ProductCardBrandName"]')
      .text()
      .trim() || 'N/A';

    const description = card
      .find('p[data-component="ProductCardDescription"]')
      .text()
      .trim() || 'N/A';

    const price = card
      .find('p[data-component="Price"], p[data-component="PriceFinal"]')
      .first()
      .text()
      .trim() || 'N/A';

    const discount = card
      .find('p[data-component="PriceDiscount"]')
      .text()
      .trim() || 'N/A';

    const href = card.find('a').first().attr('href');
    const link = href
      ? new URL(href, 'https://www.farfetch.com').href
      : 'N/A';

    products.push({ brand, description, price, discount, link });
  });

  return products;
}

Les sélecteurs viennent directement de la page. Chaque carte est un li[data-testid="productCard"] à l'intérieur de ul#catalog-grid. La marque se trouve dans un p étiqueté data-component="ProductCardBrandName", la description dans ProductCardDescription, et le prix dans Price ou PriceFinal, le sélecteur correspondant donc à l'un ou l'autre et prenant le premier. Lorsqu'un article est en solde, le libellé de remise réside dans PriceDiscount. Le lien produit est le href d'ancre de la carte, que Farfetch sert en tant que chemin relatif, il est donc résolu contre https://www.farfetch.com pour donner une URL absolue qui fonctionne en dehors de la page.

Les sélecteurs évoluent

Les attributs data-component et data-testid de Farfetch sont des points d'accroche stables, mais le balisage change avec le temps. Traitez les sélecteurs ci-dessus comme un modèle de départ, pas comme un contrat. Lorsqu'un champ revient à « N/A » pour toutes les cartes, 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 scraper en production, ce n'est pas le signe que quelque chose est cassé.

Étape 3 : Gérer la pagination

Farfetch répartit ses listes sur de nombreuses pages. Pour collecter une catégorie complète, parcourez les pages en ajoutant un paramètre page à l'URL et exécutez le même fetch-and-parse sur chacune, puis rassemblez tout dans une seule liste.

javascript
async function crawl(pageUrl) {
  const response = await api.get(pageUrl, options);
  if (response.statusCode === 200) return response.body;
  console.error(`Request failed: ${response.statusCode}`);
  return null;
}

async function scrapeMultiplePages(baseUrl, totalPages) {
  const allProducts = [];

  for (let page = 1; page <= totalPages; page++) {
    const paginatedUrl = `${baseUrl}?page=${page}`;
    console.log(`Scraping page: ${page}`);
    const html = await crawl(paginatedUrl);
    if (!html) continue;
    allProducts.push(...parseListings(html));
  }

  return allProducts;
}

Cette boucle va de la page 1 à totalPages, construisant chaque URL de page en ?page=N, la récupérant via la Crawling API avec les mêmes options d'attente, analysant les cartes et répartissant les résultats dans un tableau combiné. Comme chaque page de catégorie partage la même structure de carte, la fonction parseListings que vous avez écrite à l'étape 2 fonctionne sur toutes sans modification.

Étape 4 : Assembler le script complet avec export JSON et CSV

Maintenant, reliez la récupération, l'analyse et la pagination en un script fonctionnel, puis écrivez les enregistrements sur le disque en formats JSON et CSV.

javascript
const fs = require('fs');
const { CrawlingAPI } = require('crawlbase');
const cheerio = require('cheerio');

const api = new CrawlingAPI({ token: 'YOUR_CRAWLBASE_TOKEN' });

const options = { ajax_wait: 'true', page_wait: '5000' };

async function crawl(pageUrl) {
  const response = await api.get(pageUrl, options);
  if (response.statusCode === 200) return response.body;
  console.error(`Request failed: ${response.statusCode}`);
  return null;
}

function parseListings(html) {
  const $ = cheerio.load(html);
  const products = [];

  $('ul#catalog-grid > li[data-testid="productCard"]').each((i, el) => {
    const card = $(el);
    const brand = card.find('p[data-component="ProductCardBrandName"]').text().trim() || 'N/A';
    const description = card.find('p[data-component="ProductCardDescription"]').text().trim() || 'N/A';
    const price = card.find('p[data-component="Price"], p[data-component="PriceFinal"]').first().text().trim() || 'N/A';
    const discount = card.find('p[data-component="PriceDiscount"]').text().trim() || 'N/A';
    const href = card.find('a').first().attr('href');
    const link = href ? new URL(href, 'https://www.farfetch.com').href : 'N/A';

    products.push({ brand, description, price, discount, link });
  });

  return products;
}

async function scrapeMultiplePages(baseUrl, totalPages) {
  const allProducts = [];
  for (let page = 1; page <= totalPages; page++) {
    console.log(`Scraping page: ${page}`);
    const html = await crawl(`${baseUrl}?page=${page}`);
    if (html) allProducts.push(...parseListings(html));
  }
  return allProducts;
}

function toCsv(rows) {
  const headers = ['brand', 'description', 'price', 'discount', 'link'];
  const escape = (value) => `"${String(value).replace(/"/g, '""')}"`;
  const lines = [headers.join(',')];
  for (const row of rows) {
    lines.push(headers.map((h) => escape(row[h])).join(','));
  }
  return lines.join('\n');
}

async function main() {
  const baseUrl = 'https://www.farfetch.com/shopping/men/shoes-2/items.aspx';
  const products = await scrapeMultiplePages(baseUrl, 5);
  if (!products.length) return;

  fs.writeFileSync('farfetch_listings.json', JSON.stringify(products, null, 2));
  fs.writeFileSync('farfetch_listings.csv', toCsv(products));
  console.log(`Saved ${products.length} products to JSON and CSV`);
}

main();

Exécutez-le avec node farfetch-scraper.js et vous obtenez deux fichiers : farfetch_listings.json avec les enregistrements structurés complets et farfetch_listings.csv prêt à être ouvert dans un tableur. L'assistant toCsv met chaque champ entre guillemets et double les guillemets intégrés, ce qui importe ici car les noms de marques et les descriptions de produits contiennent fréquemment des virgules.

À quoi ressemble la sortie

Le fichier JSON contient un objet par carte de produit, chacun avec la marque, la description, le prix, la remise et le lien.

json
[
  {
    "brand": "Gucci",
    "description": "Screener leather sneakers",
    "price": "$890",
    "discount": "N/A",
    "link": "https://www.farfetch.com/shopping/men/gucci-screener-sneakers-item-27582236.aspx"
  },
  {
    "brand": "Common Projects",
    "description": "Original Achilles low-top sneakers",
    "price": "$425",
    "discount": "30% off",
    "link": "https://www.farfetch.com/shopping/men/common-projects-original-achilles-item-12345678.aspx"
  }
]

Le CSV reprend les mêmes lignes avec une ligne d'en-tête, il se charge donc directement dans Excel, Google Sheets ou tout pipeline de données lisant des fichiers délimités.

csv
brand,description,price,discount,link
"Gucci","Screener leather sneakers","$890","N/A","https://www.farfetch.com/shopping/men/gucci-screener-sneakers-item-27582236.aspx"
"Common Projects","Original Achilles low-top sneakers","$425","30% off","https://www.farfetch.com/shopping/men/common-projects-original-achilles-item-12345678.aspx"

Passer à l'échelle avec plusieurs catégories

Une catégorie est une démonstration ; un vrai travail parcourt plusieurs rayons Farfetch. Chaque catégorie réside sous son propre chemin de liste, par exemple chaussures pour hommes, sacs pour femmes ou vêtements pour enfants, vous pouvez donc constituer une liste d'URL de catégories, exécuter scrapeMultiplePages sur chacune, et étiqueter chaque ligne avec sa catégorie avant d'exporter. Comme chaque page de liste partage la même structure de carte, le parseur que vous avez déjà écrit fonctionne sur toutes sans modification.

Ce modèle se transpose directement en recherche de prix et de produits. Pour une vue d'ensemble de l'extraction de données structurées depuis les boutiques en ligne, consultez le guide sur le web scraping e-commerce, et pour transformer ces prix en décisions, consultez comment utiliser le web scraping pour l'intelligence des prix. Si vous voulez la même approche appliquée à un autre revendeur de mode, le guide sur comment créer un scraper Zalando couvre un catalogue JavaScript similaire.

Rester non bloqué

Même avec le rendu géré, Farfetch surveille le trafic ressemblant à des scrapers. Quelques habitudes maintiennent une exécution saine, et elles s'appliquent à toute cible commerciale difficile.

  • Espacez vos requêtes. Introduisez un délai entre les récupérations de pages plutôt que de marteler le catalogue en boucle serrée. Étaler les requêtes est le facteur le plus important pour rester sous les limites de débit d'un site.
  • Misez sur la rotation. Un pool d'adresses IP résidentielles répartit 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 s'en charge pour vous ; si vous construisez votre propre pile, c'est la partie à bien maîtriser.
  • Lisez les codes de statut. Une exécution qui commence à retourner des défis ou des réponses non-200 vous indique que le débit actuel ou le niveau d'IP n'est plus suffisant. Traitez cela comme un signal pour ralentir, pas comme du bruit à ignorer.

Pour le guide général sur ce sujet, consultez comment scraper des sites web sans être bloqué, et pour les mécanismes expliquant pourquoi ces catalogues ont besoin d'un vrai navigateur en premier lieu, le guide sur comment crawler des sites web JavaScript va plus loin.

Est-il légal de scraper Farfetch ?

Savoir si le scraping de Farfetch est autorisé dépend des conditions d'utilisation de Farfetch, de votre juridiction et de ce que vous faites avec les données. Les conditions de Farfetch restreignent l'accès automatisé, donc le scraping peut aller à l'encontre de ces conditions quel que soit le soin apporté à votre outillage. Aucun code ici ne change cela ; il rend seulement la partie technique fonctionnelle. Lisez les Conditions générales d'utilisation de Farfetch et son robots.txt, et traitez les deux comme la limite de ce que vous collectez.

Quelques règles à respecter. Ne collectez que les données de produits publics : la marque, la description, le prix, la remise et le lien produit que tout le monde peut voir sur une page de catégorie sans compte. Respectez les attentes de débit de Farfetch et gardez votre volume de requêtes suffisamment bas pour ne pas surcharger ses serveurs. Évitez les données personnelles, y compris tout ce qui est lié à des évaluateurs identifiables au-delà du texte public affiché sur la page. Ne redistribuez pas les médias protégés par le droit d'auteur de Farfetch, comme les photographies 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.

Pour un usage à grande échelle ou commercial, la bonne démarche est de chercher un canal sanctionné. Farfetch gère des programmes de partenariat et d'affiliation via ses relations avec les boutiques et les marques, et ce sont les bonnes voies lorsque vous avez besoin de grands volumes, d'une structure garantie ou de droits commerciaux. Ce guide se limite délibérément aux données de liste publiques car c'est la ligne qui rend le travail défendable. Il ne couvre rien derrière une connexion, les données personnelles des clients ou des boutiques, l'historique des commandes, ni aucune tentative de contourner l'authentification ou un défi que vous n'étiez pas censé passer. Si votre projet nécessite plus que des listes publiques, un partenariat officiel ou un accord de données est la bonne voie, pas un scraper plus sophistiqué.

Récapitulatif

Points clés

  • Farfetch rend les listes côté client et bloque fortement. Une requête simple retourne une coquille vide, vous devez donc rendre la page derrière une IP de confiance, avec ajax_wait et page_wait définis, avant de l'analyser.
  • La Crawling API fait le gros du travail en un seul appel. Elle rend la page, attend la grille JavaScript, fait tourner les IPs résidentielles et gère les défis, retournant le HTML finalisé que vous analysez avec cheerio.
  • cheerio extrait les champs. Sélectionnez chaque li[data-testid="productCard"], puis lisez la marque, la description, le prix, la remise et le lien produit absolu depuis l'intérieur de chaque carte.
  • Paginez et exportez. Parcourez les pages avec ?page=N, rassemblez les enregistrements et écrivez-les en JSON et CSV, en mettant les champs CSV entre guillemets pour que les noms de marques et descriptions riches en virgules restent intacts.
  • Restez sur les données publiques. Respectez les conditions et robots.txt de Farfetch, espacez vos requêtes, et préférez un partenariat officiel ou un canal d'affiliation pour un usage à grande échelle ou commercial.

Foire aux questions

Comment gérer le contenu JavaScript lors du scraping de Farfetch ?

Farfetch charge sa grille de produits côté client, le HTML brut est donc presque vide jusqu'à ce que les scripts de la page s'exécutent. Routez la requête via la Crawling API avec ajax_wait: 'true' et un page_wait de quelques milliers de millisecondes, ce qui donne au JavaScript le temps de se rendre avant que le HTML ne soit capturé. Utilisez votre token JavaScript pour ces requêtes, puisque le rendu est un type de requête JS.

Puis-je scraper les détails de produits sur plusieurs pages de Farfetch ?

Oui. Farfetch pagine ses catégories, vous ajoutez donc un paramètre page à l'URL de liste, par exemple ?page=2, et bouclez sur les pages souhaitées. Exécutez le même fetch-and-parse sur chaque page et combinez les résultats dans un seul tableau, comme le fait la fonction scrapeMultiplePages dans ce guide. Router chaque page via la Crawling API maintient la rotation et la gestion des défis cohérentes tout au long de l'exécution.

Quels champs ce scraper extrait-il ?

Pour chaque carte de produit, il extrait la marque depuis ProductCardBrandName, la description depuis ProductCardDescription, le prix depuis Price ou PriceFinal, le libellé de remise depuis PriceDiscount, et le lien produit depuis l'ancre de la carte, résolu en URL farfetch.com absolue. Les valeurs manquantes reviennent à « N/A » pour qu'une carte partielle ne casse jamais l'exécution.

Mes sélecteurs retournent « N/A » pour chaque carte. Qu'est-ce qui a changé ?

Presque certainement le balisage de Farfetch. Ses points d'accroche data-component et data-testid sont assez stables mais peuvent changer, et une mise à jour de mise en page peut déplacer un champ. Réinspectez une page de catégorie en direct dans les outils de développement de votre navigateur et mettez à jour les sélecteurs pour correspondre. La maintenance périodique des sélecteurs est normale pour tout scraper en production.

Comment stocker les données extraites ?

Sauvegardez-les dans un format structuré comme JSON ou CSV. Ce guide écrit les deux : farfetch_listings.json pour le code en aval et farfetch_listings.csv pour les tableurs et les outils BI. L'écrivain CSV met chaque champ entre guillemets et échappe les guillemets intégrés pour que les virgules dans les noms de marques ou les descriptions ne décalent pas les colonnes.

Puis-je scraper des données personnelles depuis Farfetch ?

Non, et ce guide ne le couvre pas. Les détails de compte client, l'historique des commandes et tout ce qui se trouve derrière une connexion ne sont pas des données publiques. Scraper du contenu protégé par login, des données personnelles sur les évaluateurs au-delà du texte public affiché sur la page, ou contourner l'authentification est hors du champ ici et va à l'encontre des conditions de Farfetch. Pour un accès sanctionné, la bonne voie est un partenariat officiel ou un accord de données.

Commencer à construire

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.

En libre-service · Sans appel commercial requis · Volumes de crawl entreprise disponibles