Yelp héberge des centaines de millions d'avis participatifs sur des commerces locaux, et ces retours publics constituent l'un des signaux les plus riches du web ouvert pour savoir comment un restaurant, une boutique ou un prestataire est réellement perçu. Les analystes les lisent pour suivre le sentiment dans le temps, les exploitants les lisent pour repérer les réclamations récurrentes, et les chercheurs les lisent pour comparer toute une catégorie d'entreprises d'un seul coup. L'essentiel se trouve directement sur chaque page d'établissement : une note en étoiles, le texte de l'avis et la date de publication.

Ce guide vous explique comment crawler et scraper les avis Yelp avec JavaScript et Node.js en utilisant cheerio. Vous construisez un petit scraper fonctionnel qui récupère une page publique d'avis sur un établissement Yelp via la Crawling API, analyse la note, le texte et la date de chaque avis, gère la pagination et exporte le résultat en JSON et CSV. L'ensemble du tutoriel se limite aux données d'avis publics et est conçu pour l'analyse agrégée, non pour profiler des évaluateurs individuels. Lisez la section sur la légalité vers la fin avant de pointer cet outil sur un volume réel.

Ce que vous allez construire

Un script Node.js qui prend l'URL publique d'un établissement Yelp, récupère le HTML rendu via la Crawling API et extrait un enregistrement structuré pour chaque avis de la page. Nous utilisons une page de restaurant comme exemple fil rouge et récupérons ces champs pour chaque avis :

  • Rating la note en étoiles laissée par l'évaluateur, par exemple "4 out of 5".
  • Text le corps public de l'avis, la partie que vous analysez réellement.
  • Date la date à laquelle l'avis a été publié, pour le tri et l'analyse des tendances.

Remarquez ce qui ne figure pas dans cette liste. Nous ne collectons délibérément pas le nom de l'évaluateur, le lien de profil, la photo ou la localisation, et nous ne les indexons pas. Ce sont des données personnelles, et tout l'intérêt de ce tutoriel est l'analyse agrégée : sentiment, thèmes récurrents, distribution des notes dans le temps. Traitez un avis comme une note, un bloc de texte et une date, jamais comme un dossier sur une personne.

Pourquoi une requête simple échoue sur Yelp

Si vous interrogez une URL d'établissement Yelp avec un client HTTP brut, vous obtenez rarement les avis en retour. Deux facteurs jouent contre vous. Premièrement, Yelp affiche la liste des avis dans le navigateur avec JavaScript, de sorte que le HTML initial est une coquille presque vide tant que les scripts de la page ne s'exécutent pas. Deuxièmement, Yelp signale le trafic automatisé de façon agressive : les IP de datacenter et les schémas de requêtes qui ne ressemblent pas à un vrai navigateur sont bloqués par un CAPTCHA, soumis à une limitation de débit ou bloqués avant d'atteindre les avis rendus.

Un scraper Yelp fonctionnel a donc besoin de deux choses en une seule requête : un navigateur qui rend réellement la page et une IP que la plateforme lit comme un vrai visiteur. Vous pouvez assembler cela vous-même avec un navigateur sans tête et un pool de proxies résidentiels tournants, mais assembler ces éléments et les maintenir en bonne santé représente la majorité du travail. La Crawling API regroupe les deux dans un seul appel : vous lui envoyez l'URL, elle rend la page derrière une IP de confiance et renvoie le HTML final que vous pouvez analyser avec cheerio. Yelp est rendu en JavaScript, nous le demandons donc avec le rendu activé.

Aggregate, not individual

Tout ce qui suit est structuré de sorte que la sortie soit utile en volume et inutile en tant que profil. Nous récupérons la note, le texte et la date, et nous laissons l'identité de l'évaluateur sur la page. Si votre analyse doit vraiment pondérer par évaluateur, pseudonymisez ou hachez un identifiant au moment de la collecte afin que l'enregistrement stocké ne relie jamais le texte à une personne nommée.

Prérequis

Quelques éléments doivent être en place avant d'écrire du code. Aucun d'eux ne prend longtemps.

Basic JavaScript and Node.js. Vous devez savoir écrire et exécuter un script Node et installer des paquets avec npm. Si vous débutez avec Node, le guide sur la construction d'un scraper web avec Node.js couvre les bases que ce tutoriel suppose acquises.

Node.js 16 or later. Confirmez 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.

A Crawlbase account and token. Inscrivez-vous, ouvrez votre tableau de bord et copiez votre token de requête JavaScript. L'offre gratuite vous donne 1 000 requêtes sans carte bancaire. Yelp nécessitant le rendu, utilisez le token JavaScript plutôt que le token normal. Traitez le token comme un mot de passe : il authentifie vos requêtes, gardez-le hors 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 yelp-reviews && cd yelp-reviews
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 afin que vous puissiez extraire les champs individuels par sélecteur CSS. L'ancienne version de ce tutoriel utilisait request et cheerio ; nous conservons cheerio et la même approche par sélecteurs, en remplaçant l'appel HTTP brut par le client officiel, de sorte que le rendu et les nouvelles tentatives sont gérés pour vous. Créez un fichier nommé yelp-scraper.js dans ce dossier et ajoutez le code des étapes ci-dessous.

Étape 1 : Récupérer la page d'avis rendue

Commencez par récupérer la page finale. Importez la classe CrawlingAPI, initialisez-la avec votre token JavaScript et demandez l'URL de l'établissement. Yelp rend les avis côté client, nous passons donc pageWait pour laisser aux scripts un moment pour remplir la liste avant que l'API ne capture le HTML. Vérifier le code de statut avant d'analyser permet de faire remonter les erreurs clairement plutôt que silencieusement.

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

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

const yelpPageURL =
  'https://www.yelp.com/biz/sushi-yasaka-new-york';

api
  .get(yelpPageURL, { pageWait: 3000 })
  .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 yelp-scraper.js et vous devriez voir du vrai balisage Yelp en haut du body, pas une coquille allégée. Cela confirme que le rendu fonctionne avant d'écrire un seul sélecteur. L'URL d'exemple pointe vers une page publique de restaurant ; remplacez-la par n'importe quelle autre page d'établissement public et le même flux s'applique.

Crawlbase Crawling API

Cette première requête vient de retourner une page Yelp entièrement rendue sans navigateur sans tête ni proxy de votre côté. La Crawling API exécute la page dans un vrai navigateur, attend que la liste des avis soit remplie, effectue une rotation des IP résidentielles côté serveur et gère les CAPTCHA que Yelp impose aux scrapers, de sorte que vous obtenez le HTML final en un seul appel. Pointez-la vers une page publique d'établissement sur l'offre gratuite d'abord.

Étape 2 : Analyser chaque avis avec cheerio

Une fois le HTML rendu en main, chargez-le dans cheerio et parcourez les blocs d'avis. Yelp organise chaque avis dans un conteneur répété, vous sélectionnez donc chaque avis, puis lisez la note, le texte et la date en son sein. Les anciens sélecteurs pour cette page étaient .review.review--with-sidebar pour le conteneur d'avis et .review-content p pour le corps du texte ; nous les conservons et ajoutons la note et la date. Lire chaque champ de façon défensive évite qu'une valeur manquante fasse planter l'exécution.

javascript
const cheerio = require('cheerio');

function parseReviews(html) {
  const $ = cheerio.load(html);
  const reviews = [];

  // Legacy container selector, kept faithfully
  const blocks = $('.review.review--with-sidebar');

  blocks.each((index, element) => {
    const block = $(element);

    // Public review text
    const text = block.find('.review-content p').text().trim();

    // Rating: read it from the star widget's aria/title text
    const ratingLabel =
      block.find('[role="img"][aria-label*="star"]').attr('aria-label') ||
      block.find('.i-stars').attr('title') ||
      '';
    const ratingMatch = ratingLabel.match(/([\d.]+)\s*star/i);
    const rating = ratingMatch ? parseFloat(ratingMatch[1]) : null;

    // Date the review was posted
    const date = block
      .find('.review-content .rating-qualifier, span[class*="date"]')
      .first()
      .text()
      .trim();

    if (text) {
      reviews.push({ rating, date, text });
    }
  });

  return reviews;
}

Quelques détails maintiennent la fidélité à la page. Le corps de l'avis provient de .review-content p, exactement comme dans le tutoriel original. La note n'est pas du texte brut sur Yelp ; elle se trouve dans un élément de widget d'étoiles dont l'aria-label ou le title indique quelque chose comme "4 star rating", une petite regex en extrait donc le nombre. La date se trouve dans le même bloc review-content. Chaque enregistrement est simplement { rating, date, text }, sans nom d'évaluateur, par conception. Si un avis n'a pas de corps textuel, nous le sautons plutôt que de stocker une ligne vide.

Selectors drift

Les noms de classes de Yelp changent sans préavis, et les sélecteurs exacts de note et de date ci-dessus peuvent nécessiter une mise à jour sur une page en production. Traitez-les comme un modèle de départ, pas comme un contrat. Quand un champ revient vide, réinspectez la page en production dans les outils de développement de votre navigateur et mettez à jour le sélecteur. Si vous souhaitez un rappel sur la construction de sélecteurs robustes, consultez le guide sur le crawl de sites JavaScript. La maintenance périodique des sélecteurs est normale pour tout scraper en production.

Étape 3 : Gérer la pagination des avis

Une seule page n'affiche que le premier lot d'avis. Yelp pagine le reste avec un paramètre de requête start qui avance par paliers (généralement 10 avis par page), donc ?start=10 est la deuxième page, ?start=20 la troisième, et ainsi de suite. Pour collecter les avis d'un établissement, vous parcourez ces décalages jusqu'à ce qu'une page ne renvoie plus de blocs d'avis, en récupérant et en analysant chacun avec les fonctions déjà écrites.

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

async function crawlAllReviews(businessUrl, maxPages = 5) {
  const all = [];

  for (let page = 0; page < maxPages; page++) {
    const start = page * 10;
    const url = `${businessUrl}?start=${start}`;
    const html = await crawlPage(url);
    if (!html) break;

    const pageReviews = parseReviews(html);
    if (pageReviews.length === 0) break; // no more reviews

    all.push(...pageReviews);

    // Pace requests so we stay a polite visitor
    await new Promise((r) => setTimeout(r, 2000));
  }

  return all;
}

La boucle s'arrête à la première page vide, à une réponse non-200 ou lorsqu'elle atteint maxPages, vous ne risquez donc pas de tourner indéfiniment. La pause de deux secondes entre les récupérations maintient votre débit de requêtes modeste, ce qui compte davantage sur une cible difficile comme Yelp que la vitesse brute. Gardez maxPages bas pendant le développement et ne l'augmentez qu'une fois que la sortie d'analyse semble correcte.

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

Assemblez maintenant la récupération, l'analyse et la pagination en un seul script exécutable, puis écrivez les enregistrements agrégés sur disque en JSON et CSV. Le CSV ne contient que la note, la date et le texte, les trois champs qui alimentent l'analyse de sentiment et de thèmes.

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

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

function toCsv(rows) {
  const headers = ['rating', 'date', 'text'];
  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 businessUrl =
    'https://www.yelp.com/biz/sushi-yasaka-new-york';

  const reviews = await crawlAllReviews(businessUrl, 5);
  if (reviews.length === 0) {
    console.log('No reviews parsed; check your selectors.');
    return;
  }

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

main();

Collez les fonctions parseReviews, crawlPage et crawlAllReviews des étapes précédentes dans le même fichier afin que main puisse les appeler. Exécutez avec node yelp-scraper.js et vous obtenez deux fichiers : reviews.json avec les enregistrements structurés complets et reviews.csv prêt à ouvrir dans un tableur ou à injecter dans un pipeline d'analyse. Le helper toCsv met entre guillemets chaque champ et double les guillemets intégrés, ce qui est important ici car le texte des avis est long et contient fréquemment des virgules et des sauts de ligne.

À quoi ressemble le résultat

Le fichier JSON contient un objet par avis, chacun avec la note, la date et le texte. Aucune identité d'évaluateur n'est présente, ce qui est exactement ce que vous souhaitez pour un travail agrégé.

json
[
  {
    "rating": 5,
    "date": "3/14/2024",
    "text": "Consistently fresh fish and quick service at lunch. The omakase set is great value for the quality."
  },
  {
    "rating": 3,
    "date": "2/2/2024",
    "text": "Good food but the wait was long on a weekend. Worth it if you can get there early."
  }
]

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

csv
rating,date,text
"5","3/14/2024","Consistently fresh fish and quick service at lunch. The omakase set is great value for the quality."
"3","2/2/2024","Good food but the wait was long on a weekend. Worth it if you can get there early."

Transformer les avis en analyse agrégée

L'intérêt de collecter des avis réside dans ce que vous apprenez en volume, pas dans une seule entrée. Une fois les données en JSON ou CSV, vous pouvez calculer la distribution des notes, suivre la note moyenne par mois grâce au champ de date et soumettre le texte des avis à une analyse de sentiment ou un regroupement thématique pour faire remonter les sujets récurrents tels que les temps d'attente, les prix ou le service. Rien de tout cela ne nécessite le nom de l'évaluateur, et exclure les noms du pipeline est à la fois plus propre et plus sûr.

Si vous prévoyez d'injecter le texte dans un modèle, normalisez-le d'abord : supprimez le texte générique, réduisez les espaces et décidez comment gérer les avis non anglophones. Le guide sur la structuration et le nettoyage des données scrapées pour l'IA et le ML détaille cette étape. Pour le schéma plus large consistant à collecter et comparer des retours provenant de plusieurs sources, le guide sur le scraping d'avis clients couvre la même approche axée sur l'agrégat pour d'autres plateformes d'avis.

Rester non bloqué

Même avec le rendu géré, Yelp surveille le trafic qui ressemble à des scrapers. Quelques habitudes maintiennent une exécution en bonne santé, et elles s'appliquent à toute cible commerciale difficile.

  • Pace your requests. Maintenez le délai entre les récupérations paginées, comme le fait le script. Espacer les requêtes est le facteur le plus déterminant pour rester sous les limites de débit de Yelp.
  • Lean on rotation. Un pool d'IP résidentielles répartit les requêtes sur de nombreuses adresses d'utilisateurs réels afin qu'aucune ne déclenche de limite ou de CAPTCHA. La Crawling API gère cela pour vous ; si vous construisez votre propre infrastructure, c'est la partie à bien maîtriser.
  • Read the status codes. Une exécution qui commence à renvoyer des challenges ou des réponses non-200 vous indique que le débit ou le niveau d'IP actuel ne suffit plus. Traitez cela comme un signal pour ralentir, pas comme du bruit à ignorer.

Pour le manuel de stratégie complet, consultez comment scraper des sites sans être bloqué.

Est-il légal de scraper les avis Yelp ?

La légalité du scraping de Yelp dépend des conditions d'utilisation de Yelp, de votre juridiction et de l'usage que vous faites des données. Les conditions d'utilisation de Yelp restreignent explicitement la copie ou le scraping du contenu du site, que ce soit manuellement ou avec des bots, des extensions ou des logiciels, de sorte que la collecte automatisée peut contrevenir à ces conditions quelle que soit la prudence de vos outils. Aucun des codes présentés ici ne change cela ; il se contente de faire fonctionner la partie technique. Lisez les conditions d'utilisation de Yelp et son robots.txt, et traitez les deux comme la limite de ce que vous collectez. La voie la plus propre pour tout volume réel ou usage commercial est l'API officielle Yelp Fusion API, qui expose les données d'établissements et d'avis sous des conditions claires et sanctionnées.

Le texte des avis et les notes en étoiles affichés sur une page d'établissement sont publics, mais les personnes qui les ont rédigés ne sont pas anonymes aux yeux du droit à la vie privée. Les noms des évaluateurs, les liens de profil, les photos et les localisations sont des données personnelles. En vertu du RGPD et du CCPA, le traitement de ces données nécessite une base légale, et les individus conservent des droits sur celles-ci. C'est pourquoi ce tutoriel collecte délibérément uniquement la note, le texte et la date, et pourquoi nous vous recommandons de ne pas stocker, indexer ni republier l'avis d'une personne lié à son identité. Maintenez votre analyse à un niveau agrégé : sentiment, thèmes et tendances de notation, jamais un profil d'un évaluateur individuel.

Quelques principes à respecter. Collectez uniquement le contenu public des avis, scrapez à un rythme lent et respectueux, et maintenez votre volume de requêtes assez bas pour ne pas surcharger les serveurs de Yelp. Restez à l'écart de tout ce qui se trouve derrière une connexion. Ne redistribuez pas le contenu protégé par le droit d'auteur de Yelp, y compris les médias d'avis, comme s'il était le vôtre. Si vous opérez dans ou collectez des données sur des personnes dans une juridiction RGPD ou CCPA et que votre usage touche des données personnelles, demandez un avis juridique avant de procéder. En cas de doute, la Yelp Fusion API ou un accord de données est la bonne voie, pas un scraper plus astucieux.

Récapitulatif

Points clés

  • Yelp renders reviews client-side and blocks hard. Une requête simple renvoie une coquille vide ou un CAPTCHA, vous devez donc rendre la page derrière une IP de confiance avant de l'analyser.
  • The Crawling API does both in one call. Elle rend la page avec le token JavaScript, attend que la liste des avis soit remplie, effectue une rotation des IP résidentielles et gère les CAPTCHA, renvoyant le HTML final à analyser avec cheerio.
  • Parse rating, text, and date only. Conservez les anciens sélecteurs .review.review--with-sidebar et .review-content p, ajoutez la note du widget d'étoiles et la date, et parcourez le décalage start pour la pagination.
  • Stay aggregate and privacy-safe. Laissez les noms des évaluateurs hors de l'enregistrement ; analysez le sentiment, les thèmes et les tendances de notation, et ne créez jamais un profil d'un individu ni ne republiez un avis lié à une personne.
  • Prefer the official API for volume. Respectez les CGU et le robots.txt de Yelp, tenez compte du RGPD et du CCPA pour les données personnelles, et utilisez la Yelp Fusion API ou un accord de données pour un usage commercial ou à grande échelle.

Foire aux questions

Puis-je scraper légalement les avis Yelp ?

Cela dépend des conditions d'utilisation de Yelp, de votre juridiction et de votre usage. Les conditions de Yelp restreignent le scraping de son contenu, la collecte automatisée peut donc y contrevenir. Le texte des avis et les notes sont publics, mais l'identité des évaluateurs est une donnée personnelle couverte par des lois comme le RGPD et le CCPA. Limitez la collecte au contenu public des avis, restez agrégé, scrapez lentement et préférez la Yelp Fusion API officielle pour tout volume réel ou usage commercial.

Pourquoi une simple requête renvoie-t-elle des données incomplètes depuis Yelp ?

Parce que Yelp rend sa liste d'avis côté client avec JavaScript et challenge le trafic automatisé avec des CAPTCHA. Une requête HTTP brute depuis une IP de datacenter renvoie généralement une coquille vide ou une page de blocage plutôt que les avis. Pour obtenir une page complète, vous devez la rendre derrière une IP de confiance et laisser le temps aux scripts de remplir la liste, ce que la Crawling API gère pour vous.

Comment récupérer tous les avis plutôt que la seule première page ?

Yelp pagine les avis avec un paramètre de requête start qui avance par paliers d'environ dix, donc ?start=10 est la page deux, ?start=20 la page trois, et ainsi de suite. Parcourez ces décalages en boucle, récupérez et analysez chaque page, et arrêtez lorsqu'une page ne renvoie plus de blocs d'avis ou que vous atteignez votre limite de pages. La fonction crawlAllReviews dans ce guide fait exactement cela, avec une pause entre les récupérations.

Dois-je stocker les noms des auteurs d'avis ?

Non. Les noms des évaluateurs, les liens de profil et les photos sont des données personnelles, et ce tutoriel est conçu pour l'analyse agrégée, pas le profilage. Stockez uniquement la note, le texte et la date. Si votre analyse doit vraiment distinguer les évaluateurs, pseudonymisez ou hachez un identifiant au moment de la collecte afin que l'enregistrement stocké ne relie jamais le texte à une personne nommée, et respectez les obligations RGPD ou CCPA applicables.

Ma note ou ma date revient vide. Qu'est-ce qui a changé ?

Très probablement le balisage de Yelp. Ses noms de classes et la structure du widget d'étoiles changent sans préavis, les sélecteurs qui fonctionnaient avant peuvent donc se casser. Réinspectez un bloc d'avis en production dans les outils de développement de votre navigateur, confirmez où se trouvent maintenant l'aria-label ou le title de la note et la date, et mettez à jour les sélecteurs. La maintenance périodique des sélecteurs est normale pour tout scraper en production.

Existe-t-il un moyen officiel d'obtenir les données d'avis Yelp ?

Oui. La Yelp Fusion API est le programme sanctionné de Yelp pour accéder aux informations d'établissements et à un ensemble limité de données d'avis sous des conditions claires. Pour les projets commerciaux, les volumes importants ou lorsque vous avez besoin d'une structure garantie et de droits d'utilisation, la Fusion API ou un accord de données direct est le bon outil, pas un scraper.

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