Avviso legale: Questo articolo copre esclusivamente l'accesso a dati pubblici su Yelp. Prima di qualsiasi attività di scraping, consulta i Termini di Servizio di Yelp, il Computer Fraud and Abuse Act (CFAA) negli Stati Uniti e il GDPR nell'Unione Europea. L'estrazione di dati personali (nomi utenti, foto profilo) può costituire trattamento di dati personali ai sensi del GDPR Article 4 — consulta un legale prima di raccogliere o archiviare tali dati.
Yelp ospita oltre 50 milioni di schede aziendali e centinaia di milioni di recensioni. Per sviluppatori che costruiscono dataset di aziende locali, fare scraping di Yelp nel 2026 è una delle sfide tecniche più stimolanti: la piattaforma combina difese anti-bot sofisticate (PerimeterX/HUMAN), TLS fingerprinting e CAPTCHA aggressive. In questa guida vedremo cosa è accessibile pubblicamente, come configurare proxy residenziali rotanti con ProxyHat, e quando è meglio usare l'API Fusion ufficiale.
Scraping di Yelp nel 2026: cosa è accessibile pubblicamente senza login
Yelp espone pubblicamente, senza richiedere autenticazione, una quantità significativa di dati aziendali. Ogni scheda business è accessibile tramite URL /biz/<slug> e contiene:
- Nome azienda, indirizzo, telefono, sito web
- Valutazione (1-5 stelle) e numero totale di recensioni
- Categorie (es. ristorante italiano, pizzeria)
- Orari di apertura settimanali
- Attributi (parcheggio, Wi-Fi, accessibilità)
- Foto caricate dagli utenti
- Testo delle recensioni — visibile senza login, tipicamente le prime 10-20 recensioni per pagina
La pagina business include anche un blob JSON embedded in window.__INITIAL_STATE__ che contiene tutti questi dati in formato strutturato, evitando la necessità di parsing HTML complesso. Questo è il punto di accesso principale per un Yelp review scraper.
L'API Fusion di Yelp offre un'alternativa ufficiale, ma con limitazioni significative: il endpoint /businesses/{id}/reviews restituisce un massimo di 3 recensioni per azienda, e non include il testo completo di tutte le recensioni disponibili pubblicamente sulla pagina web. Per chi ha bisogno di dati aziendali Yelp su larga scala (valutazioni, categorie, orari), l'API Fusion può bastare; per dataset di recensioni completo, lo scraping resta l'unica via praticabile.
Difese anti-bot di Yelp: PerimeterX, TLS fingerprinting e CAPTCHA
Yelp utilizza HUMAN (ex PerimeterX) come sistema principale di protezione anti-bot. Questo crea tre livelli di difesa che ogni scraper deve affrontare:
1. Cookie _px3 e challenge sensor
Al primo caricamento, il browser riceve un cookie _px3 generato da un challenge JavaScript che raccoglie decine di segnali browser (canvas fingerprint, WebGL, timing, plugin installati). Senza un cookie _px3 valido, le richieste successive vengono bloccate con HTTP 403. I scraper headless che non eseguono JavaScript non possono ottenere questo cookie.
2. TLS fingerprinting (JA3/JA4)
Yelp ispeziona il TLS Client Hello per identificare il client HTTP. requests di Python, curl e node-fetch hanno fingerprint JA3 distinti da browser reali. Un IP datacenter combinato con un fingerprint JA3 di libreria equivale a un blocco quasi istantaneo.
3. IP reputation scoring
Dopo circa 5-10 richieste da un IP datacenter, Yelp serve una CAPTCHA interstitial. Gli IP datacenter sono flaggati quasi immediatamente perché HUMAN mantiene un database di IP noti per attività bot. Gli IP residenziali, invece, hanno reputazione alta perché associati a ISP civili.
Il pattern tipico: prima richiesta 200 OK, seconda 200 OK, terza 403 con redirect a /px/captcha. Con IP datacenter, questo ciclo si completa in meno di 30 secondi.Perché i proxy residenziali rotanti con geo US sono essenziali
I risultati di ricerca su Yelp sono fortemente localizzati. Una ricerca per pizzeria da un IP di Francoforte restituisce risultati diversi rispetto a un IP di Austin, Texas. Per raccogliere dati aziendali Yelp rilevanti, serve un IP nella stessa area geografica del business target.
ProxyHat supporta geo-targeting a livello di paese e città nel campo username, permettendo di simulare traffico da qualsiasi città statunitense:
http://user-country-US-city-austin:pass@gate.proxyhat.com:8080Con proxy residenziali rotanti, ogni richiesta può uscire da un IP civico diverso, distribuendo il carico su centinaia di indirizzi e riducendo il rischio che PerimeterX flagga il pattern come bot. La rotazione per-request è ideale per scraping su larga scala; le sessioni sticky mantengono lo stesso IP per un numero configurabile di richieste, utile per paginare le recensioni di una singola azienda senza innescare sospetti.
Confronto: tipi di proxy per scraping Yelp
| Tipo Proxy | Reputazione IP | Costo indicativo | Affidabilità su Yelp | Caso d'uso |
|---|---|---|---|---|
| Datacenter | Bassa | $0.50-2/GB | Bassa — blocchi dopo ~5 richieste | Testing, prototipi |
| Residenziale | Alta | $3-15/GB | Alta — supera PerimeterX | Produzione, scraping su larga scala |
| Mobile | Altissima | $10-30/GB | Altissima ma costosa | Blocchi persistenti, fallback |
Per la maggior parte dei casi, i proxy residenziali con geo US rappresentano il miglior rapporto costo-affidabilità. Vedi i piani ProxyHat per dettagli sui volumi disponibili.
Implementazione pratica: Python con ProxyHat
Vediamo due approcci pratici per estrarre dati da Yelp: il parsing del blob __INITIAL_STATE__ e l'accesso diretto. Entrambi usano il gateway ProxyHat su porta 8080 con proxy residenziali US.
Esempio 1: Parsing di __INITIAL_STATE__ con Python requests
import requests
import json
import re
# ProxyHat residential proxy with US geo-targeting
proxy_url = 'http://user-country-US-city-austin:pass@gate.proxyhat.com:8080'
proxies = {'http': proxy_url, 'https': proxy_url}
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',
'Accept': 'text/html,application/xhtml+xml',
}
url = 'https://www.yelp.com/biz/the-salt-lick-austin'
resp = requests.get(url, proxies=proxies, headers=headers, timeout=30)
if resp.status_code == 200:
# Extract __INITIAL_STATE__ JSON blob
match = re.search(r'window\.__INITIAL_STATE__\s*=\s*({.+?})\s*;?\s*</script>', resp.text, re.DOTALL)
if match:
state = json.loads(match.group(1))
reviews = state.get('bizDetailsPageReviews', {}).get('reviews', [])
for r in reviews[:3]:
rating = r.get('rating')
author = r.get('author', {}).get('displayName', 'N/A')
text = r.get('comment', {}).get('text', '')[:200]
print(f'Rating: {rating} | Author: {author}')
print(f'Review: {text}...')
print('---')
else:
print('No __INITIAL_STATE__ found - possible CAPTCHA')
else:
print(f'HTTP {resp.status_code} - blocked or rate-limited')Questo snippet estrae un oggetto review troncato con rating, autore e prime 200 caratteri del testo. Il blob __INITIAL_STATE__ contiene anche dati aziendali completi (orari, categorie, attributi) accessibili navigando la struttura JSON. Per un Yelp business data scraper completo, puoi estrarre nome, indirizzo, telefono, categorie e orari dallo stesso blob senza richieste aggiuntive.
Esempio 2: Node.js su SOCKS5 porta 1080
const { SocksProxyAgent } = require('socks-proxy-agent');
const fetch = require('node-fetch');
const agent = new SocksProxyAgent(
'socks5://user-country-US:pass@gate.proxyhat.com:1080'
);
async function scrapeYelp() {
const resp = await fetch('https://www.yelp.com/biz/the-salt-lick-austin', {
agent,
headers: {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
'Accept-Language': 'en-US,en;q=0.9',
},
});
const html = await resp.text();
const match = html.match(/window\.__INITIAL_STATE__\s*=\s*({[\s\S]+?})\s*;?\s*<\/script>/);
if (match) {
const state = JSON.parse(match[1]);
const reviews = (state.bizDetailsPageReviews || {}).reviews || [];
reviews.slice(0, 3).forEach(r => {
const text = (r.comment || {}).text || '';
console.log(`Rating: ${r.rating} | Text: ${text.slice(0, 200)}...`);
});
} else {
console.log('Blocked or CAPTCHA served');
}
}
scrapeYelp();SOCKS5 offre un tunnel a livello TCP che può aggirare alcuni middleware HTTP che ispezionano header proxy. La porta 1080 di ProxyHat supporta SOCKS5 con le stesse opzioni di geo-targeting e sessione della porta HTTP 8080.
Paginazione, rate-limit e sessioni sticky
Yelp pagina le recensioni con il parametro ?start= (incrementi di 10). Per raccogliere tutte le recensioni di un'azienda con 500+ recensioni, servono decine di richieste alla stessa URL. Ecco le strategie chiave per mantenere un Yelp review scraper affidabile su lunghe sequenze.
Sessioni sticky per continuità
Usa il flag -session- nel username ProxyHat per mantenere lo stesso IP per una sequenza di richieste correlate. Questo è importante perché PerimeterX correla il cookie _px3 con l'IP: cambiare IP a metà sessione invalida il cookie e innesca un nuovo challenge.
# Sticky session: same IP for 10 paginated requests
proxy_url = 'http://user-country-US-session-abc123:pass@gate.proxyhat.com:8080'Rate-limit pacing
Yelp non pubblica limiti di rate ufficiali per il traffico web, ma in pratica richieste troppo veloci da un singolo IP innescano CAPTCHA dopo 10-15 richieste in pochi minuti. Una strategia efficace:
- 2-5 secondi di delay tra richieste con stesso IP
- Rotazione IP ogni 10-15 richieste (nuova sessione ProxyHat)
- Backoff esponenziale su HTTP 429 o 403: attendi 30-60s, poi riprova
- Jitter casuale per evitare pattern di timing rilevabili
import time
import random
session_id = 'sess-001'
request_count = 0
for page in range(1, 20):
if request_count > 0 and request_count % 10 == 0:
session_id = f'sess-{page:03d}'
proxy_url = f'http://user-country-US-session-{session_id}:pass@gate.proxyhat.com:8080'
proxies = {'http': proxy_url, 'https': proxy_url}
resp = requests.get(
f'https://www.yelp.com/biz/the-salt-lick-austin?start={page*10}',
proxies=proxies, headers=headers, timeout=30
)
if resp.status_code == 200:
# process page
request_count += 1
elif resp.status_code == 429:
wait = random.uniform(30, 60)
print(f'Rate limited. Waiting {wait:.0f}s...')
time.sleep(wait)
continue
time.sleep(random.uniform(2, 5))Rotazione User-Agent
Oltre alla rotazione IP, ruota anche gli User-Agent per ridurre il rischio di fingerprinting. Usa una pool di 10-20 UA reali di browser correnti (Chrome, Firefox, Safari su diverse piattaforme). Evita UA obsoleti o incongruenti (es. Chrome UA su Windows XP). Mantieni coerenza tra UA e Accept-Language: un UA Chrome en-US non dovrebbe accompagnarsi a Accept-Language de-DE.
Errori comuni e edge case
- Regex troppo avida: il blob
__INITIAL_STATE__può superare 500KB. Usare.DOTALLcon un pattern non-avido (.+?) e imposta un timeout. - JSON malformato: a volte Yelp include trailing commas o caratteri non standard nel blob. Usa
json.loads()con fallback ajson5odemjson3. - CAPTCHA interstitial: se ricevi una pagina con
/px/captchanell'URL, l'IP è stato flaggato. Cambia sessione ProxyHat e attendi 60+ secondi. - Contenuto login-walled: alcune sezioni (messaggi privati, recensioni filtrate) richiedono login. Non tentare di bypassare il login — è una violazione dei ToS e potenzialmente del CFAA.
- Struttura JSON che cambia: Yelp aggiorna la struttura di
__INITIAL_STATE__periodicamente. Implementa defensive parsing con.get()e fallback graceful. - Timeout su pagine pesanti: pagine con molte foto possono superare 2MB. Imposta
timeout=30e gestiscirequests.exceptions.Timeout.
Setup ProxyHat e risorse
Configurare ProxyHat per lo scraping di Yelp richiede pochi minuti. Dopo aver creato un account su dashboard.proxyhat.com, ottieni le credenziali e usa il gateway gate.proxyhat.com sulla porta 8080 (HTTP) o 1080 (SOCKS5).
Risorse utili per approfondire:
- Piani e prezzi ProxyHat — confronta piani residenziali e datacenter
- Caso d'uso: web scraping — pattern generali per scraping con proxy
- Caso d'uso: SERP tracking — tracking SERP con proxy rotanti
- Località disponibili — oltre 195 paesi con geo-targeting a livello di città
- Documentazione ProxyHat — configurazione avanzata e SDK
Scraping etico e quando usare l'API Fusion
Lo scraping di dati pubblici è legale in molte giurisdizioni, ma pubblico non significa senza restrizioni. Ecco i principi da seguire per un approccio etico e sostenibile.
Rispetta robots.txt
Controlla sempre https://www.yelp.com/robots.txt prima di iniziare. Se Yelp disabilita l'accesso a determinati path, rispetta quelle direttive. I motori di ricerca le rispettano; il tuo scraper dovrebbe fare altrettanto. Ignorare robots.txt indebolisce qualsiasi difesa legale in caso di disputa.
Dati personali e GDPR
Le recensioni Yelp contengono dati personali: nomi utenti, foto, testo che può identificare una persona. Secondo il GDPR, raccogliere e memorizzare questi dati richiede una base giuridica (consenso, interesse legittimo). Se il tuo dataset è per analisi di sentiment o ricerca di mercato, considera l'anonimizzazione: rimuovi nomi utenti, mantieni solo rating e testo aggregato. Il GDPR si applica a qualsiasi controller o processor che opera nell'UE, indipendentemente da dove si trova il server.
Quando usare l'API Fusion invece dello scraping
L'API Fusion di Yelp è la via ufficialmente supportata. Usala quando:
- Ti servono solo dati aziendali (nome, indirizzo, telefono, categoria, rating) — l'endpoint
/businesses/searchcopre questo caso - Ti servono fino a 3 recensioni per azienda — l'endpoint
/businesses/{id}/reviewsle fornisce - Vuoi evitare qualsiasi rischio legale associato allo scraping
- Hai un budget API sufficiente (il piano gratuito offre 500 richieste/giorno)
Usa lo scraping quando:
- Ti serve l'intero corpus di recensioni (non solo 3) per un'azienda
- Devi accedere a dati storici o versioni archiviate di schede
- L'API Fusion non copre i campi specifici che ti servono (orari dettagliati, attributi specifici)
Regola pratica: se l'API Fusion copre il 90% del tuo bisogno, usa l'API. Usa lo scraping solo per il gap residuo, e solo su dati pubblici senza login.
Punti chiave
- Yelp espone pubblicamente schede aziendali, valutazioni, categorie, orari e testo recensioni senza login, tramite URL
/biz/<slug>- Il blob
__INITIAL_STATE__contiene tutti i dati in formato JSON strutturato — preferiscilo al parsing HTML- L'API Fusion ufficiale limita a 3 recensioni per azienda — insufficiente per dataset completi
- PerimeterX/HUMAN blocca IP datacenter dopo ~5-10 richieste; i proxy residenziali con geo US sono essenziali
- Usa sessioni sticky (
-session-) per paginare recensioni della stessa azienda, ruota IP ogni 10-15 richieste- Rate-limit: 2-5s tra richieste, backoff su 429, jitter casuale
- Rispetta robots.txt, GDPR per dati personali, e preferisci l'API Fusion dove possibile






