Retour au blog
Guides
Raluca PenciucLast updated on Apr 28, 202616 min read

Comment gratter Yelp avec Python : Critiques, listes et pipelines de données prêts pour le LLM

Comment gratter Yelp avec Python : Critiques, listes et pipelines de données prêts pour le LLM
En bref : ce guide vous explique pas à pas comment créer un outil complet de scraping de Yelp en Python, couvrant les résultats de recherche, les informations sur les entreprises et les avis, avec du code fonctionnel. Vous apprendrez également à contourner les protections anti-bot, à exporter les données au format CSV ou JSON, et à intégrer les avis récupérés dans un modèle de langage de grande capacité (LLM) pour l'analyse des sentiments, un aspect que nul autre tutoriel de scraping de Yelp n'aborde.

Introduction

Yelp détient l'une des collections les plus riches de données sur les entreprises locales du Web : notes, avis, horaires, catégories, photos et bien plus encore, le tout lié à des millions d'entreprises réparties dans des centaines de villes. Si vous avez besoin de comprendre comment scraper Yelp par programmation, Python est l'outil le plus pratique pour cette tâche.

Le scraping de Yelp consiste à extraire des données structurées des pages publiques de Yelp (généralement des résultats de recherche, des fiches d'entreprises individuelles et des avis d'utilisateurs) à l'aide de requêtes HTTP et d'analyse HTML, plutôt que par copier-coller manuel. Que vous développiez un tableau de bord de veille concurrentielle, que vous surveilliez le sentiment des avis ou que vous génériez des prospects à partir d'annuaires locaux, le workflow sous-jacent est le même : récupérer la page, analyser le code HTML et stocker les résultats.

Ce tutoriel vous propose un projet complet de bout en bout. Vous commencerez par le scraping des résultats de recherche, passerez à l'extraction des détails des entreprises, puis vous vous attaquerez à la collecte des avis avec pagination. À partir de là, nous aborderons les stratégies anti-bot, la mise à l'échelle asynchrone, l'exportation de données et un workflow unique pour acheminer les données Yelp vers un LLM en vue d'un résumé automatisé. Chaque extrait de code est exécutable, et chaque section explique le « pourquoi » en plus du « comment ».

Pourquoi extraire les données de Yelp ? Des cas d'utilisation professionnels qui méritent d'être développés

Avant de se plonger dans le code, il est utile de comprendre pourquoi les données de Yelp sont si précieuses. Yelp n’est pas seulement un site d’avis ; c’est un annuaire structuré contenant des signaux granulaires difficiles à trouver ailleurs. Voici les cas d’utilisation qui justifient l’effort d’ingénierie nécessaire au scraping de Yelp.

Veille concurrentielle et benchmarking. Si vous gérez un restaurant, un salon de coiffure ou toute autre entreprise de services locale, les avis Yelp vous indiquent exactement ce que les clients aiment (et détestent) chez vos concurrents. Le scraping des notes par étoiles, du nombre d’avis et des taux de réponse au sein d’une catégorie vous permet de comparer votre entreprise au paysage local.

Suivi des avis et analyse des sentiments. Le suivi des avis au fil du temps révèle des tendances : les clients se plaignent-ils davantage des temps d'attente ce trimestre ? Les avis Yelp extraits alimentent directement les pipelines d'analyse des sentiments, vous fournissant des signaux quantitatifs à partir de retours qualitatifs.

Génération de prospects. Les fiches Yelp comprennent les noms d'entreprise, les numéros de téléphone, les adresses et les catégories. Pour les équipes de vente B2B ciblant les entreprises locales (comme les fournisseurs de systèmes de caisse ou les agences de marketing), un scraper Yelp est un moteur de génération de prospects.

Audits SEO locaux. Comparer l'exhaustivité de votre fiche Yelp (photos, horaires, catégories, taux de réponse) à celle des concurrents les mieux classés révèle les lacunes de votre présence locale.

Études de marché et sélection de sites. Vous lancez un nouvel établissement ? Scrapez Yelp pour cartographier la densité de la concurrence, les notes moyennes et le volume d'avis par quartier. Ces données alimentent directement les modèles de sélection de sites.

Le fait est qu'apprendre à scraper Yelp n'est pas un simple exercice théorique. Ces données alimentent de véritables décisions commerciales.

Prérequis et configuration du projet

Vous aurez besoin de Python 3.9 ou d'une version ultérieure. Créez un nouveau répertoire de projet et installez les dépendances principales :

pip install requests beautifulsoup4 lxml

Voici ce que fait chaque paquet :

  • requests : gère les requêtes HTTP vers les pages de Yelp
  • beautifulsoup4 : analyse le code HTML renvoyé pour le transformer en une arborescence navigable
  • lxml : un analyseur HTML/XML rapide que BeautifulSoup utilise comme backend

Pour les sections suivantes, vous aurez également besoin de :

pip install httpx openai

httpx vous offre une prise en charge HTTP asynchrone pour le scraping simultané, et openai (ou n'importe quel client LLM) alimente le pipeline de transformation des données en informations que nous construirons à la fin.

Créez un scraper.py fichier et ajoutez les importations standard :

import requests
from bs4 import BeautifulSoup
import csv
import json
import time
import random

Voilà votre base. Toutes les sections ci-dessous s'appuient sur cette configuration.

Scraping des résultats de recherche Yelp

La première étape de tout projet de scraping de Yelp consiste à collecter les fiches d'entreprises à partir des pages de résultats de recherche. Lorsque vous recherchez quelque chose comme « pizza » à « New York, NY » sur Yelp, l'URL suit un schéma prévisible :

https://www.yelp.com/search?find_desc=pizza&find_loc=New+York%2C+NY&start=0

Le start paramètre contrôle la pagination, en augmentant de 10 pour chaque nouvelle page. Créons un scraper qui collecte les fiches sur plusieurs pages.

def scrape_search_results(query, location, max_pages=5):
    results = []
    headers = {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
                       "AppleWebKit/537.36 (KHTML, like Gecko) "
                       "Chrome/120.0.0.0 Safari/537.36",
        "Accept-Language": "en-US,en;q=0.9",
    }

    for page in range(max_pages):
        offset = page * 10
        url = (
            f"https://www.yelp.com/search?"
            f"find_desc={query}&find_loc={location}&start={offset}"
        )
        response = requests.get(url, headers=headers)

        if response.status_code != 200:
            print(f"Blocked or error on page {page}: {response.status_code}")
            break

        soup = BeautifulSoup(response.text, "lxml")
        cards = soup.select('[data-testid="serp-ia-card"]')

        if not cards:
            break

        for card in cards:
            name_tag = card.select_one("a.css-19v1rkv")
            rating_tag = card.select_one('[aria-label*="star rating"]')
            review_count_tag = card.select_one("span.css-chan6m")

            results.append({
                "name": name_tag.get_text(strip=True) if name_tag else None,
                "url": "https://www.yelp.com" + name_tag["href"] if name_tag else None,
                "rating": rating_tag["aria-label"] if rating_tag else None,
                "review_count": review_count_tag.get_text(strip=True) if review_count_tag else None,
            })

        time.sleep(random.uniform(2, 5))

    return results

Quelques remarques concernant la stratégie de sélection. Les noms de classe de Yelp sont générés dynamiquement (ces css-* chaînes de caractères), ils peuvent donc changer d'un déploiement à l'autre. Les data-testid attributs ont tendance à être plus stables car ils sont utilisés pour les tests internes. Vérifiez toujours vos sélecteurs par rapport à la page en ligne avant de les exécuter à grande échelle.

Yelp expose également un point de terminaison de recherche qui peut renvoyer directement du JSON, ce qui permettrait d'éviter complètement l'analyse du code HTML. Cependant, la disponibilité et la structure de ce point de terminaison peuvent changer sans préavis ; l'approche HTML décrite ci-dessus constitue donc la base de référence fiable.

La boucle de pagination augmente start de 10 à chaque itération et s'arrête lorsqu'il n'y a plus de fiches d'annonces. Le délai aléatoire entre les requêtes est essentiel pour éviter les limites de débit, un sujet que nous aborderons en détail plus tard.

Extraction des informations sur les entreprises à partir des pages de fiches Yelp

Les résultats de recherche vous fournissent les noms et les notes, mais ce sont les pages individuelles des entreprises qui contiennent les données vraiment utiles : adresse complète, numéro de téléphone, horaires d'ouverture, catégories, fourchette de prix, etc. Voici comment extraire les données des entreprises à partir des pages de listes Yelp.

def scrape_business_details(business_url, headers):
    response = requests.get(business_url, headers=headers)
    if response.status_code != 200:
        return None

    soup = BeautifulSoup(response.text, "lxml")

    def safe_text(selector):
        tag = soup.select_one(selector)
        return tag.get_text(strip=True) if tag else None

    # Extract business_id from meta or script tags for API use
    meta_biz = soup.select_one('meta[name="yelp-biz-id"]')
    business_id = meta_biz["content"] if meta_biz else None

    details = {
        "business_id": business_id,
        "name": safe_text("h1"),
        "rating": None,
        "phone": safe_text('[data-testid="phone-info"] p'),
        "address": safe_text("address"),
        "categories": [],
        "hours": {},
    }

    # Star rating from aria-label
    rating_el = soup.select_one('[aria-label*="star rating"]')
    if rating_el:
        details["rating"] = rating_el["aria-label"]

    # Categories
    cat_links = soup.select('span.css-1xfc281 a')
    details["categories"] = [a.get_text(strip=True) for a in cat_links]

    # Hours table
    hours_rows = soup.select("table.hours-table tr")
    for row in hours_rows:
        cols = row.select("td, th")
        if len(cols) >= 2:
            day = cols[0].get_text(strip=True)
            time_range = cols[1].get_text(strip=True)
            details["hours"][day] = time_range

    return details

L' business_id extrait de la balise meta est particulièrement utile. Yelp utilise cet identifiant en interne, et il peut servir de clé pour la déduplication ou pour construire des URL permettant d'accéder aux points de terminaison. Lorsque vous effectuez un scraping à grande échelle des données d'entreprises sur Yelp, il est essentiel de disposer d'un identifiant stable par entreprise pour maintenir des ensembles de données propres.

Gardez à l'esprit que la structure HTML de Yelp varie légèrement en fonction de la catégorie de l'entreprise. Une page de restaurant comporte une section « menu », contrairement à celle d'un plombier. Votre code d'analyse doit gérer les éléments manquants de manière élégante (c'est ce que fait l' safe_text helper). Vérifiez la valeur de retour de chaque sélecteur avant d'essayer d'accéder aux attributs ou au texte.

Extraction à grande échelle des avis Yelp

Les avis constituent souvent la partie la plus précieuse de l'extraction de données Yelp. Chaque avis comprend le nom de l'auteur, une note par étoiles, la date et le texte complet, ce qui correspond exactement à ce dont vous avez besoin pour l'analyse des sentiments ou la veille concurrentielle.

Yelp pagine les avis à l'aide d'un start paramètre de requête, affichant généralement 10 avis par page. Voici un scraper qui parcourt les pages d'avis :

def scrape_reviews(business_url, max_pages=10, headers=None):
    reviews = []

    for page in range(max_pages):
        offset = page * 10
        url = f"{business_url}?start={offset}&sort_by=date_desc"
        response = requests.get(url, headers=headers or {})

        if response.status_code != 200:
            print(f"Review page {page} returned {response.status_code}")
            break

        soup = BeautifulSoup(response.text, "lxml")
        review_containers = soup.select('[data-testid="review"]')

        if not review_containers:
            break

        for container in review_containers:
            user_tag = container.select_one("a.css-19v1rkv")
            rating_tag = container.select_one('[aria-label*="star rating"]')
            date_tag = container.select_one("span.css-chan6m")
            text_tag = container.select_one("p.comment__09f24__D0cxf span")

            reviews.append({
                "user": user_tag.get_text(strip=True) if user_tag else None,
                "rating": rating_tag["aria-label"] if rating_tag else None,
                "date": date_tag.get_text(strip=True) if date_tag else None,
                "text": text_tag.get_text(strip=True) if text_tag else None,
            })

        time.sleep(random.uniform(2, 5))

    return reviews

Gestion du chargement dynamique des avis. Yelp charge parfois les avis via JavaScript après le rendu initial de la page. Si votre requestsscraper basé sur JavaScript renvoie moins d'avis que ce que vous voyez dans le navigateur, la page est probablement en train d'hydrater le contenu des avis côté client. Dans ce cas, vous avez deux options : utiliser un navigateur headless (comme Playwright ou Puppeteer) pour exécuter le JavaScript, ou rechercher les appels API sous-jacents effectués par la page.

Certains indices suggèrent que Yelp utilise en interne un point de terminaison GraphQL pour récupérer les données d'avis au format JSON structuré. Si cette option est disponible, elle vous permettrait de contourner entièrement l'analyse HTML et d'obtenir des données d'avis propres et structurées. Cependant, l'URL exacte du point de terminaison et la structure de la charge utile doivent être vérifiées sur le site en ligne, car les API internes sont susceptibles d'être modifiées sans préavis. L'approche de scraping HTML présentée ci-dessus reste la méthode la plus fiable pour une extraction cohérente des avis Yelp.

Tri des avis. Le sort_by=date_desc dans l'URL vous garantit d'obtenir les avis les plus récents en premier. D'autres options incluent rating_desc et rating_asc. Pour les cas d'utilisation liés à la surveillance, le scraping trié par date vous permet de détecter les nouveaux avis en les comparant à l'horodatage de votre dernier scraping.

Gestion des protections anti-bot et des limites de débit

Yelp prend très au sérieux la protection de ses données. Si vous envoyez des centaines de requêtes rapides à partir d’une seule adresse IP, attendez-vous à être bloqué. Voici une stratégie en plusieurs étapes pour scraper Yelp de manière fiable.

Faites tourner les chaînes User-Agent. Envoyer le même en-tête User-Agent à chaque requête revient à laisser une empreinte digitale. Tenez à jour une liste de chaînes User-Agent de navigateurs réalistes et faites-les tourner de manière aléatoire. Vous pouvez trouver des chaînes UA à jour sur des ressources telles que user-agents.net.

import random

USER_AGENTS = [
    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 Chrome/120.0.0.0",
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 14_0) AppleWebKit/605.1.15 Safari/605.1.15",
    "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 Chrome/119.0.0.0 Safari/537.36",
]

def get_headers():
    return {
        "User-Agent": random.choice(USER_AGENTS),
        "Accept-Language": "en-US,en;q=0.9",
        "Accept": "text/html,application/xhtml+xml",
    }

Ajoutez des délais réalistes. Des délais aléatoires compris entre 2 et 5 secondes imitent les habitudes de navigation humaines. Pour les opérations à grande échelle, envisagez un délai plus long (10 à 30 secondes) entre les pages de détails des entreprises, car il s'agit de requêtes plus lourdes qui ressortent dans les journaux du serveur.

Rotation des proxys. Lorsque vous effectuez un scraping de Yelp au-delà de quelques dizaines de pages, il est essentiel de faire tourner vos adresses IP. Vous pouvez configurer votre propre pool de proxys ou utiliser un service de rotation de proxys. L'essentiel est de répartir les requêtes sur de nombreuses adresses IP afin qu'aucune adresse unique ne déclenche de limites de débit.

def make_request(url, proxies_list):
    proxy = random.choice(proxies_list)
    proxy_dict = {"http": proxy, "https": proxy}
    headers = get_headers()
    try:
        response = requests.get(url, headers=headers, proxies=proxy_dict, timeout=15)
        return response
    except requests.RequestException as e:
        print(f"Request failed via {proxy}: {e}")
        return None

Logique de réessai avec délai d'attente exponentiel. Lorsque vous obtenez une réponse 429 (limitation de débit) ou 403 (bloqué), ne réessayez pas immédiatement. Attendez, puis réessayez avec un délai plus long :

def fetch_with_retry(url, max_retries=3):
    for attempt in range(max_retries):
        response = requests.get(url, headers=get_headers(), timeout=15)
        if response.status_code == 200:
            return response
        wait = (2 ** attempt) + random.uniform(0, 1)
        print(f"Retrying in {wait:.1f}s (status {response.status_code})")
        time.sleep(wait)
    return None

Respectez le fichier robots.txt. À l'heure où nous écrivons ces lignes, le fichier robots.txt de Yelp robots.txt restreint l'exploration de certains chemins et spécifie des préférences de délai d'exploration. Vérifiez toujours les directives en vigueur avant de lancer un scraper. Ignorer robots.txt ne risque pas seulement de vous faire bloquer ; cela soulève des questions éthiques et potentiellement juridiques. Un scraping responsable consiste à rester dans les limites publiées par le site.

Accélérer votre scraper grâce aux requêtes asynchrones

Le scraper synchrone ci-dessus fonctionne bien pour les petites tâches, mais si vous collectez des données sur des milliers d'entreprises Yelp, l'attente séquentielle de chaque réponse HTTP s'accumule rapidement. Le HTTP asynchrone vous permet d'envoyer plusieurs requêtes simultanément, ce qui réduit considérablement le temps total de scraping.

Voici un modèle asynchrone minimal utilisant httpx:

import httpx
import asyncio

async def fetch_page(client, url):
    try:
        response = await client.get(url, timeout=15)
        return response.text if response.status_code == 200 else None
    except httpx.RequestError:
        return None

async def scrape_urls_async(urls, concurrency=5):
    semaphore = asyncio.Semaphore(concurrency)
    results = []

    async def bounded_fetch(client, url):
        async with semaphore:
            html = await fetch_page(client, url)
            results.append((url, html))
            await asyncio.sleep(random.uniform(1, 3))

    async with httpx.AsyncClient(headers=get_headers()) as client:
        tasks = [bounded_fetch(client, url) for url in urls]
        await asyncio.gather(*tasks)

    return results

Le Semaphore avec concurrency=5 vous limite à cinq requêtes simultanées. Ceci est important : bombarder Yelp avec 50 connexions simultanées est le moyen le plus rapide de faire bloquer toutes les adresses IP de votre pool. Commencez par 3 à 5 requêtes simultanées et augmentez prudemment tout en surveillant votre taux de réussite.

Chaque tâche inclut également un délai aléatoire après son achèvement. Cela évite le scénario de « troupeau déchaîné » où les cinq slots se libèrent simultanément et lancent immédiatement cinq nouvelles requêtes d’un seul coup.

Le scraping asynchrone est particulièrement efficace lorsque vous disposez déjà d'une liste d'URL à visiter (par exemple, les URL de pages d'entreprises collectées lors de la phase de résultats de recherche). Vous analysez les réponses HTML avec le même code BeautifulSoup que précédemment, car la logique d'analyse ne change pas simplement parce que la récupération est asynchrone.

Stockage et exportation de vos données Yelp

Le scraping n'est utile que si vous stockez les résultats dans un format compatible avec vos outils en aval. Voici trois méthodes d'exportation courantes pour les données Yelp récupérées.

L'exportation CSV est l'option la plus simple et fonctionne avec pratiquement tous les outils d'analyse :

def export_to_csv(data, filename="yelp_data.csv"):
    if not data:
        return
    keys = data[0].keys()
    with open(filename, "w", newline="", encoding="utf-8") as f:
        writer = csv.DictWriter(f, fieldnames=keys)
        writer.writeheader()
        writer.writerows(data)
    print(f"Exported {len(data)} records to {filename}")

L'exportation au format JSON préserve les structures imbriquées (comme les horaires ou les listes d'avis) qui s'aplatissent de manière peu pratique au format CSV :

def export_to_json(data, filename="yelp_data.json"):
    with open(filename, "w", encoding="utf-8") as f:
        json.dump(data, f, indent=2, ensure_ascii=False)
    print(f"Exported {len(data)} records to {filename}")

SQLite est un bon compromis lorsque vous souhaitez un stockage interrogeable sans avoir à configurer de serveur de base de données :

import sqlite3

def export_to_sqlite(data, db_name="yelp.db", table="businesses"):
    conn = sqlite3.connect(db_name)
    cursor = conn.cursor()
    if data:
        cols = ", ".join(f"{k} TEXT" for k in data[0].keys())
        cursor.execute(f"CREATE TABLE IF NOT EXISTS {table} ({cols})")
        placeholders = ", ".join("?" for _ in data[0])
        for row in data:
            cursor.execute(
                f"INSERT INTO {table} VALUES ({placeholders})",
                list(row.values())
            )
    conn.commit()
    conn.close()

Pour la plupart des projets de scraping de Yelp, commencez par JSON (qui gère naturellement les données d'avis imbriquées), puis aplatissez-les en CSV lorsque vous devez charger les données dans des feuilles de calcul ou des DataFrames Pandas. SQLite est judicieux lorsque vous effectuez des scrapes répétés et que vous souhaitez interroger des données historiques sans tout charger en mémoire.

Transformer les données Yelp en informations exploitables par les modèles de langage de grande envergure

C'est là que ce tutoriel se distingue de tous les autres guides de scraping de Yelp. Une fois que vous avez collecté les avis, vous pouvez les faire passer par un grand modèle linguistique pour en extraire des informations qui prendraient des heures à compiler manuellement.

Le workflow comporte trois étapes : nettoyer les données, les formater en une invite structurée, puis appeler le LLM.

Étape 1 : Convertissez les avis en un bloc de résumé au format Markdown. Les LLM fonctionnent mieux lorsque les données d'entrée sont clairement structurées :

def reviews_to_markdown(reviews, business_name):
    lines = [f"# Reviews for {business_name}\n"]
    for r in reviews:
        lines.append(f"- **{r['rating']}** ({r['date']}): {r['text']}\n")
    return "\n".join(lines)

Étape 2 : Créez une requête demandant des résultats spécifiques. Ne vous contentez pas de dire « résumez ces avis ». Soyez précis quant à ce que vous attendez :

def build_analysis_prompt(markdown_reviews):
    return (
        "Analyze the following Yelp reviews and provide:\n"
        "1. A 2-sentence overall summary\n"
        "2. Top 3 positive themes with example quotes\n"
        "3. Top 3 negative themes with example quotes\n"
        "4. An estimated sentiment score (1-10)\n\n"
        f"{markdown_reviews}"
    )

Étape 3 : Envoyez-la au LLM de votre choix. Voici un exemple minimal utilisant le client OpenAI, mais n'importe quelle API LLM (ou un modèle local) fonctionne :

from openai import OpenAI

def analyze_reviews(reviews, business_name):
    client = OpenAI()
    md = reviews_to_markdown(reviews, business_name)
    prompt = build_analysis_prompt(md)

    response = client.chat.completions.create(
        model="gpt-4o-mini",
        messages=[{"role": "user", "content": prompt}],
        temperature=0.3,
    )
    return response.choices[0].message.content

Ce pipeline transforme les avis bruts de Yelp en veille concurrentielle structurée. Vous pourriez l'appliquer à tous les concurrents d'une catégorie et générer un rapport qui cartographie automatiquement le paysage des sentiments. Pour la génération de prospects, vous pourriez repérer les entreprises dont le sentiment est en baisse comme des prospects pour votre service.

L'idée clé est que les données Yelp extraites gagnent considérablement en valeur lorsque vous y ajoutez une couche de synthèse LLM. L'extraction vous fournit la matière première ; le LLM la transforme en décisions.

Bonnes pratiques et directives éthiques en matière de scraping

Scraper Yelp (ou tout autre site) de manière responsable ne consiste pas seulement à éviter les blocages. Il s'agit d'opérer d'une manière durable et défendable.

Limitez fortement le débit. Ce n’est pas parce que vous pouvez envoyer 100 requêtes par seconde que vous devez le faire. Un scraping agressif dégrade l’expérience des utilisateurs réels. Respectez des délais d’au moins 2 à 5 secondes entre les requêtes et réduisez votre concurrence pendant les heures de pointe.

Mettez les réponses en cache. Si vous effectuez des itérations sur votre parseur, mettez le code HTML brut en cache localement afin de ne pas solliciter les serveurs de Yelp à plusieurs reprises pendant le débogage des sélecteurs. Un simple cache basé sur des fichiers (enregistrer chaque page sous {business_id}.html) réduit considérablement le nombre de requêtes.

Gérez les données de manière responsable. Les avis contiennent des informations personnelles (noms des auteurs, parfois des lieux). Si vous stockez ces données, appliquez des contrôles d'accès et des politiques de conservation appropriés. Si vous êtes dans l'UE ou si vous traitez des données d'utilisateurs de l'UE, le RGPD s'applique.

Ne republiez pas de contenu récupéré. Utiliser les données de Yelp à des fins d'analyse interne est très différent de republier des avis sur votre propre site. La première pratique est généralement justifiable ; la seconde soulève des problèmes juridiques et éthiques.

Points clés

  • Commencez par les résultats de recherche, puis élargissez votre champ d'action. Un scraper Yelp efficace passe par trois phases : les listes de recherche, les détails des entreprises, puis les avis. Développez et validez chaque phase avant de passer à la suivante.
  • La stabilité des sélecteurs est importante. Les attributs data-testid sont plus fiables que les noms de classes CSS générés. Vérifiez toujours les sélecteurs par rapport à la page en ligne et intégrez des solutions de secours élégantes.
  • La limitation du débit est votre mesure anti-blocage la plus importante. Les délais aléatoires, la rotation des proxys et la randomisation de l'User-Agent fonctionnent ensemble, mais le rythme de vos requêtes est la tactique la plus efficace.
  • Le format d'exportation dépend de votre workflow en aval. Utilisez JSON pour les données d'avis imbriquées, CSV pour l'analyse en feuille de calcul et SQLite pour les extractions répétées avec un historique consultable.
  • Les pipelines LLM transforment les avis bruts en informations exploitables. L'injection de données d'avis structurées dans un LLM pour l'analyse des sentiments et l'extraction de thèmes est un multiplicateur de puissance qu'aucune lecture manuelle ne peut égaler.

FAQ

Est-il légal de scraper des données sur Yelp ?

La légalité dépend de votre juridiction, de la manière dont vous accédez aux données et de l'usage que vous en faites. Les tribunaux font généralement la distinction entre l'extraction de données accessibles au public et le contournement des contrôles d'accès. Les conditions d'utilisation de Yelp interdisent l'accès automatisé, mais leur applicabilité varie selon les juridictions. Consultez un professionnel du droit pour votre cas d'utilisation spécifique, et évitez toujours d'extraire des données derrière des barrières d'authentification ou de contourner les restrictions techniques.

Yelp dispose-t-il d'une API publique que je peux utiliser à la place du scraping ?

Yelp propose l'API Yelp Fusion, qui offre un accès structuré à la recherche d'entreprises, aux informations sur les entreprises et aux avis. Cependant, cette API présente des limitations importantes : les données d'avis sont plafonnées à trois extraits par entreprise, les limites de débit sont relativement strictes et certains champs disponibles sur le site web ne sont pas accessibles via l'API. Pour une collecte complète d'avis ou des besoins en données à grande échelle, le scraping est souvent l'alternative la plus pratique.

Comment éviter que mon adresse IP soit bloquée lors du scraping de Yelp ?

Faites tourner les adresses IP à l'aide d'un pool de proxys, randomisez les en-têtes User-Agent et ajoutez des délais réalistes (2 à 5 secondes) entre les requêtes. Mettez en place un backoff exponentiel en cas de réponses 429 ou 403. Maintenez un faible niveau de concurrence (3 à 5 requêtes simultanées). Surveillez votre taux de réussite et réduisez la fréquence si celui-ci descend en dessous de 90 %. Les proxys résidentiels sont plus difficiles à détecter par les sites que les proxys de centre de données.

Puis-je extraire les avis Yelp sans utiliser de navigateur headless ?

Oui, pour la plupart des entreprises. Yelp affiche le premier lot d'avis dans le code HTML côté serveur, que vous pouvez analyser avec requests et BeautifulSoup. La pagination fonctionne via le start . Les navigateurs sans interface utilisateur ne sont nécessaires que lorsque Yelp charge les avis de manière dynamique via JavaScript pour des pages spécifiques, ce qui est moins courant pour la pagination standard des avis.

Quelle est la meilleure bibliothèque Python pour scraper Yelp ?

Pour la plupart des projets, la combinaison de requests (récupération HTTP) et de BeautifulSoup avec le lxml parser (analyse HTML) constitue le meilleur point de départ. Si vous avez besoin d'une prise en charge asynchrone pour une collecte à grande échelle, httpx est une excellente alternative à requests. Pour les pages nécessitant un rendu JavaScript, Playwright ou Selenium sont les options de prédilection, bien qu’elles soient nettement plus lentes.

Conclusion

Vous disposez désormais d’une boîte à outils complète pour scraper Yelp avec Python. De la collecte des résultats de recherche et de l’analyse des informations sur les entreprises à l’extraction d’avis à grande échelle, chaque étape du pipeline est couverte par du code fonctionnel. Les modèles asynchrones vous permettent de faire évoluer votre infrastructure lorsque le projet l’exige, et l’intégration du LLM transforme le texte brut des avis en informations structurées sur lesquelles vous pouvez agir.

Le plus grand défi dans tout projet de scraping de Yelp n'est pas l'analyse, mais le maintien d'un accès fiable. Entre les blocages d'IP, les défis CAPTCHA et les structures HTML changeantes, la couche de requêtes mobilise plus de temps d'ingénierie que la logique d'extraction des données. Si vous préférez vous concentrer sur ce que vous faites avec les données plutôt que de lutter contre les systèmes anti-bot, notre API Scraper gère la rotation des proxys, les CAPTCHA et les tentatives de reconnexion derrière un seul point de terminaison, afin que votre code BeautifulSoup reste exactement le même.

Quelle que soit l'approche que vous choisissez, commencez modestement, validez vos sélecteurs sur des pages en ligne et développez progressivement. Les cas d'utilisation que nous avons abordés (analyse des sentiments, benchmarking concurrentiel, génération de prospects) partent tous du même principe : des données Yelp propres et structurées, collectées de manière fiable au fil du temps.

À propos de l'auteur
Raluca Penciuc, Développeur full-stack @ WebScrapingAPI
Raluca PenciucDéveloppeur full-stack

Raluca Penciuc est développeuse Full Stack chez WebScrapingAPI ; elle conçoit des robots de collecte de données, améliore les techniques de contournement et recherche des moyens fiables de réduire le risque de détection sur les sites cibles.

Commencez à créer

Prêt à faire évoluer votre système de collecte de données ?

Rejoignez plus de 2 000 entreprises qui utilisent WebScrapingAPI pour extraire des données Web à l'échelle de l'entreprise, sans aucun coût d'infrastructure.