Yelp menyimpan 330 juta ulasan kumulatif di lebih dari 8,4 juta halaman bisnis aktif — dan memasukkan data itu ke format yang bisa dipakai sekarang terasa jauh lebih susah. Pembersihan anti-bot Yelp pada 2024–2025 diam-diam bikin sebagian besar tutorial scraping Python yang beredar jadi kurang relevan.
Kalau akhir-akhir ini Anda sempat coba jalankan Yelp scraper lalu mentok di error 403, respons HTML kosong, atau CAPTCHA yang dulu belum muncul enam bulan lalu, itu bukan salah lihat. Sekarang Yelp memakai fingerprinting TLS/JA3, nama class CSS yang terus diacak, dan penilaian reputasi IP yang agresif — artinya pendekatan lama requests + BeautifulSoup yang masih sering direkomendasikan di banyak tutorial bakal gagal di request pertama. Saya menghabiskan berminggu-minggu menguji berbagai pendekatan terhadap sistem Yelp saat ini, dan panduan ini membahas semua yang benar-benar masih jalan di 2025: Fusion API resmi (dan kenapa kemungkinan besar belum cukup), workflow scraping Python lengkap dengan strategi anti-blokir berlapis, serta alternatif no-code dua klik dengan Thunderbit buat Anda yang cuma ingin datanya, tanpa maraton debugging.
Coba Thunderbit untuk Scrape Yelp
Kenapa Scrape Yelp dengan Python (dan Siapa yang Paling Diuntungkan)
Sebelum menulis satu baris kode pun, sebenarnya apa sih nilai bisnis dari data Yelp? Platform ini bukan sekadar situs ulasan restoran — melainkan database bisnis lokal yang hidup, dengan info kontak terstruktur, rating, kategori, jam operasional, dan ratusan juta ulasan pelanggan.

Berikut siapa yang paling diuntungkan dan data apa yang mereka ambil:
| Kasus Penggunaan | Field Data Utama | Kenapa Penting |
|---|---|---|
| Sales & lead generation | Nama bisnis, telepon, website, alamat, kategori, rating | Membangun daftar prospek SMB lokal yang tertarget — 4 dari 5 pengguna Yelp siap membeli saat datang |
| Competitive intelligence | Ulasan, rating bintang, volume ulasan, sentimen | Memantau reputasi kompetitor, menemukan celah layanan, melacak tren |
| Riset pasar & NLP | Teks ulasan penuh, tanggal, metadata reviewer | Analisis sentimen, pemodelan topik — ulasan Yelp adalah salah satu korpus NLP paling sering dipakai dalam riset akademik |
| Properti & pemilihan lokasi | Kepadatan bisnis, campuran kategori, kualitas ulasan per area | Pemilihan lokasi franchise dan ritel — Yelp menjual Location Intelligence sebagai produk B2B berlisensi untuk kebutuhan ini |
| Ecommerce & operasional | Sinyal harga, keluhan pelanggan, jam layanan | Melacak bagaimana kompetitor dinilai, mengidentifikasi pola operasional |
Benang merahnya: tujuan utamanya adalah data terstruktur, dan Python cuma salah satu jalan ke sana. Ada yang butuh kontrol penuh lewat kode. Ada juga yang cuma ingin spreadsheet berisi kontak tukang ledeng di Austin. Dua-duanya dibahas di sini.
Yelp Fusion API vs. Web Scraping Python: Mana yang Sebaiknya Dipakai?
Banyak panduan melewatkan keputusan ini begitu saja dan langsung loncat ke kode, tanpa mengecek apakah Yelp Fusion API resmi (sekarang rebrand jadi "Yelp Places API") sebenarnya sudah cukup. Dari pengalaman saya, evaluasi ini bisa menghemat berjam-jam kerja sia-sia — karena API ini cocok untuk beberapa kebutuhan, tapi benar-benar tidak memadai untuk yang lain.
Apa yang Sebenarnya Diberikan Fusion API
Fusion API menyediakan pencarian bisnis terstruktur, detail bisnis, autocomplete, dan endpoint ulasan. Ini resmi, terdokumentasi dengan baik, dan tidak perlu trik anti-bot.
Tapi masalahnya ada di endpoint ulasan. Ini yang dikonfirmasi staf Yelp di GitHub:
"Yelp API tidak mengembalikan teks ulasan lengkap. Secara default, hanya disediakan tiga cuplikan ulasan sepanjang 160 karakter." — Balasan staf Yelp, GitHub Issue #163
Itu bukan bug — memang sengaja dibatasi begitu. API ini secara fisik hanya memberi 3 cuplikan ulasan (7 pada Premium), masing-masing dipotong sekitar 160 karakter. Tidak ada metadata ulasan (vote useful/funny/cool), tidak ada riwayat reviewer, tidak ada balasan pemilik. Dan batas rate limit harian untuk client baru turun ke 300–500 panggilan/hari setelah Mei 2023 — turun dari 5.000. Harga masuk dimulai dari $29/bulan.
Kerangka Keputusan
| Faktor | Yelp Fusion API | Web Scraping Python | Thunderbit (No-Code) |
|---|---|---|---|
| Ulasan lengkap | ❌ Hanya 3 cuplikan (~160 karakter masing-masing) | ✅ Semua ulasan via GraphQL | ✅ Semua ulasan yang terlihat |
| Rate limit | 300–500/hari (baru); 5.000 (lama) | Dikelola sendiri (budget proxy) | Berbasis kredit |
| Usaha setup | ~15 menit (API key + SDK) | Beberapa jam hingga beberapa hari | ~2 menit |
| Field bisnis | ~20 field terstruktur | Tak terbatas (parse HTML/JSON) | Field yang disarankan AI |
| Penanganan anti-bot | N/A (resmi) | Harus dibuat sendiri | Ditangani otomatis |
| Risiko legal | ✅ Resmi | ⚠️ Area abu-abu ToS | ⚠️ Sama seperti scraping |
| Biaya | Minimum $29/bulan | Gratis (+ biaya proxy $0,75–$4/GB) | Tersedia paket gratis |
| Maintenance | Rendah (API stabil) | Tinggi (selector rusak, anti-bot makin ketat) | Rendah (AI menyesuaikan ulang) |
Pakai Fusion API jika: Anda butuh info bisnis dasar, pencarian skala kecil, atau integrasi resmi — dan 3 cuplikan ulasan per bisnis sudah cukup.
Pakai scraping Python jika: Anda butuh teks ulasan lengkap, semua ulasan untuk satu bisnis, metadata ulasan, hasil lebih dari 240 per pencarian, atau anggaran Anda di bawah $29/bulan.
Pakai Thunderbit jika: Anda ingin data cepat tanpa menulis atau memelihara kode. Penjelasan lebih lanjut ada di bagian no-code di bawah.
Jalan Pintas No-Code: Scrape Yelp dengan Thunderbit (Tanpa Python)
Sebelum masuk ke pembahasan Python, ini jalur tercepat buat pembaca yang tujuan utamanya adalah data, bukan latihan coding. Hampir semua panduan kompetitor mengasumsikan Anda paham Python, padahal dari kerja saya di Thunderbit, saya lihat banyak orang yang mencari "scrape Yelp" sebenarnya adalah sales rep, manajer operasional, dan pemilik usaha kecil yang cuma butuh spreadsheet bisnis lokal — bukan kursus kilat fingerprinting TLS.
Thunderbit sudah menyediakan template Yelp siap pakai:
- Yelp Business Web Scraper — mengambil nama bisnis, rating, detail kontak, alamat, jam buka, kategori
- Yelp Review Scraper — mengambil username reviewer, isi ulasan, rating, tanggal, lokasi reviewer
Cara Kerjanya di Praktik
- Buka halaman hasil pencarian Yelp atau halaman bisnis di Chrome
- Klik AI Suggest Fields di ekstensi Thunderbit — AI membaca halaman dan mengusulkan kolom (nama bisnis, rating, jumlah ulasan, rentang harga, kategori, alamat, telepon, URL)
- Klik Scrape — selesai
Untuk template Yelp yang sudah jadi, lebih gampang lagi: buka template, klik Scrape.
Subpage scraping menangani enrichment secara otomatis — dari halaman hasil pencarian Yelp, aktifkan subpage scraping, lalu Thunderbit akan membuka tiap halaman bisnis untuk mengambil jam operasional, ulasan lengkap, website, foto, dan fasilitas. Tanpa setup tambahan.
Pagination otomatis — baik yang berbasis klik maupun scroll, sudah ditangani bawaan. (Kalau ingin tahu cara kerjanya, lihat panduan pagination kami.)
Ekspor gratis di semua paket — Excel, Google Sheets, Airtable, Notion, CSV, JSON. Tanpa pandas, tanpa kode untuk menulis file CSV.
Perbandingan Waktu
| Waktu | Python Scraper | Thunderbit |
|---|---|---|
| Run pertama | Beberapa jam hingga beberapa hari (buat selector, tangani pagination, proxy, retry logic) | ~30 detik dengan template Yelp siap pakai |
| Saat markup Yelp berubah | Tulis ulang selector secara manual | Klik AI Suggest Fields lagi — otomatis menyesuaikan |
| Saat IP diblokir | Debug, putar ulang pool proxy, uji lagi | Mode cloud menangani rotasi IP |
| Ekspor ke Google Sheets | Tulis OAuth + glue code pandas | Sekali klik, gratis |
Kalau Anda coba Thunderbit dulu dan ternyata sudah cukup, Anda bisa melewatkan sisa artikel ini. Kalau Anda butuh kontrol programatik penuh, field kustom, atau skala di atas beberapa ribu record per bulan — lanjut baca.
Library Python untuk Scrape Yelp: Mana yang Harus Dipilih
"Pakai Scrapy, BS4+requests, atau Selenium?" adalah salah satu pertanyaan paling umum di thread r/webscraping soal Yelp. Tapi hampir semua tutorial cuma memilih library favorit mereka lalu lanjut tanpa jelasin alasannya. Berikut penjelasan yang lebih jujur.
Realitas 2025: requests + BeautifulSoup Sudah Rusak untuk Yelp
Stack yang direkomendasikan hampir semua tutorial klasik Yelp — pip install requests beautifulsoup4 — akan diblokir pada request pertama di 2025. Bukan request ke-50. Yang pertama.
Alasannya: library requests milik Python mengirim fingerprint TLS/JA3 yang tidak cocok dengan browser nyata mana pun. Lapisan anti-bot Yelp menandainya di level TLS handshake, bahkan sebelum header User-Agent Anda dibaca. Saya mengujinya berulang kali — IP baru, header realistis, jeda acak — dan tetap langsung kena 403 Forbidden dengan requests biasa.
Matriks Keputusan Library
| Library | Cocok untuk | Dukung JS? | Anti-Bot? | Tingkat Belajar | Kecepatan |
|---|---|---|---|---|---|
requests + BeautifulSoup | ❌ | ❌ | Sangat rendah | Cepat (sampai diblokir) | |
httpx async + parsel | Scraping async skala besar | ❌ | ❌ | Rendah | Sangat cepat |
curl_cffi + parsel | Khusus Yelp: impersonasi TLS | ❌ | ✅ TLS/JA3/HTTP2 | Rendah | Sangat cepat |
Scrapy 2.14 | Pipeline crawl penuh dengan pagination | Parsial (via scrapy-playwright) | AutoThrottle, retry middleware | Menengah-Tinggi | Cepat |
Selenium 4.43 / Playwright 1.58 | Halaman banyak JS, workaround CAPTCHA | ✅ | Parsial | Menengah | Lambat (~10–30 halaman/menit) |
| Thunderbit | Non-coder, ekstraksi cepat | ✅ (browser) | Built-in (mode cloud) | Sangat rendah | Cepat |
Terobosan curl_cffi
Library yang mengubah workflow scraping Yelp saya adalah curl_cffi — binding Python untuk curl-impersonate. Library ini menghasilkan fingerprint TLS/JA3 + HTTP/2 yang sama persis seperti Chrome asli, dan API-nya bisa menggantikan requests secara langsung:
from curl_cffi import requests
r = requests.get(
"https://www.yelp.com/biz/some-restaurant",
impersonate="chrome131",
)
print(r.status_code, len(r.text))
Satu perubahan ini — from curl_cffi import requests plus impersonate="chrome131" — mampu melewati lapisan anti-bot terbesar Yelp tanpa harus menyalakan browser. Dalam pengujian saya, ini yang membedakan antara 403 instan dan respons 200 yang bersih.
Stack yang saya rekomendasikan untuk Yelp di 2025: curl_cffi + parsel + jmespath + residential proxy. Kalau Anda butuh pipeline crawl penuh dengan scheduling, bungkus saja di Scrapy 2.14 dengan downloader middleware berbasis curl_cffi.
Menyiapkan Lingkungan Python untuk Scrape Yelp
- Tingkat Kesulitan: Menengah
- Waktu yang Dibutuhkan: ~15 menit untuk setup, 1–2 jam untuk scraper yang berjalan
- Yang Dibutuhkan: Python 3.10+ (disarankan 3.12), terminal, dan opsional penyedia residential proxy
Langkah 1: Buat Virtual Environment dan Install Paket
python3.12 -m venv .venv
source .venv/bin/activate # Di Windows: .venv\Scripts\activate
pip install "curl_cffi>=0.11" "parsel>=1.9" "jmespath>=1.0" pandas
Fungsi tiap paket:
curl_cffi— mengirim HTTP request dengan fingerprint TLS Chrome (bypass anti-bot)parsel— selector CSS/XPath untuk parsing HTML (mesin yang sama seperti Scrapy, tapi lebih ringan)jmespath— query JSON deklaratif (lebih rapi daripada akses dict bertingkat untuk JSON tertanam Yelp)pandas— ekspor data ke CSV/Excel
Opsional tapi berguna:
pip install fake-useragent # Catatan: repositori diarsipkan April 2026, tapi masih bisa diinstal
Langkah Demi Langkah: Cara Scrape Yelp dengan Python
Ini inti tutorialnya. Insight utama yang bikin semuanya lebih tahan banting: lewati selector CSS, ambil JSON tersembunyi saja. Yelp mengacak nama class CSS saat build time (y-css-14xwok2 minggu ini, y-css-hcq7b9 minggu depan), jadi scraper yang bergantung pada class itu akan rusak dalam hitungan minggu. Payload JSON tertanam — schema application/ld+json dan react-root-props — jauh lebih stabil.
Langkah 2: Scrape Hasil Pencarian Yelp
URL pencarian Yelp mengikuti pola yang mudah ditebak: https://www.yelp.com/search?find_desc={term}&find_loc={location}. Data hasil pencarian tertanam di tag <script data-id="react-root-props"> sebagai JSON — bukan di tumpukan class CSS acak.
import re, json, jmespath
from curl_cffi import requests
from parsel import Selector
HEADERS = {
"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
"AppleWebKit/537.36 (KHTML, like Gecko) "
"Chrome/124.0.0.0 Safari/537.36",
"accept": "text/html,application/xhtml+xml,application/xml;q=0.9,"
"image/avif,image/webp,image/apng,*/*;q=0.8",
"accept-language": "en-US,en;q=0.9",
"accept-encoding": "gzip, deflate, br",
"cookie": "intl_splash=false",
}
def scrape_search(term: str, location: str, max_pages: int = 3):
results = []
for page in range(max_pages):
url = (f"https://www.yelp.com/search?"
f"find_desc={term}&find_loc={location}&start={page * 10}")
r = requests.get(url, headers=HEADERS, impersonate="chrome131")
if r.status_code != 200:
print(f"Diblokir di halaman {page}: {r.status_code}")
break
sel = Selector(text=r.text)
script = sel.xpath(
"//script[@data-id='react-root-props']/text()"
).get() or ""
m = re.search(r"react_root_props\s*=\s*(\{.*?\});", script, re.S)
if not m:
print(f"react-root-props tidak ditemukan di halaman {page} — kemungkinan soft block")
break
data = json.loads(m.group(1))
businesses = jmespath.search(
"legacyProps.searchAppProps.searchPageProps"
".mainContentComponentsListProps"
"[?searchResultBusiness].searchResultBusiness.{"
"name: name, url: businessUrl, rating: rating, "
"reviews: reviewCount, phone: phone, "
"neighborhoods: neighborhoods}",
data,
) or []
results.extend(businesses)
import time, random
time.sleep(random.uniform(3, 7))
return results
Anda seharusnya mendapatkan daftar dict berisi nama bisnis, URL, rating, dan jumlah ulasan. Kalau react-root-props hilang dari respons, berarti Anda sedang diberi shell blokir — ganti IP dan coba lagi.
Header Cookie: intl_splash=false adalah workaround umum untuk redirect splash negara Yelp. Tanpa ini, IP non-AS akan diarahkan ke splash page yang terlihat seperti soft block, padahal bukan.
Langkah 3: Scrape Halaman Bisnis Yelp
Setiap URL bisnis dari hasil pencarian mengarah ke halaman detail dengan data yang lebih kaya. Target ekstraksi yang paling stabil adalah blok <script type="application/ld+json"> — isinya data schema.org terstruktur yang dipertahankan Yelp untuk SEO dan tidak diacak.
def scrape_business(biz_url: str) -> dict:
url = f"https://www.yelp.com{biz_url}" if biz_url.startswith("/") else biz_url
r = requests.get(url, headers=HEADERS, impersonate="chrome131")
if r.status_code != 200:
return {"url": url, "error": r.status_code}
sel = Selector(text=r.text)
biz_id = sel.css('meta[name="yelp-biz-id"]::attr(content)').get()
for raw in sel.css('script[type="application/ld+json"]::text').getall():
try:
data = json.loads(raw)
except json.JSONDecodeError:
continue
for node in (data if isinstance(data, list) else [data]):
if node.get("@type") in (
"Restaurant", "LocalBusiness", "FoodEstablishment",
"HealthAndBeautyBusiness", "HomeAndConstructionBusiness",
):
return {
"biz_id": biz_id,
"name": node.get("name"),
"rating": (node.get("aggregateRating") or {}).get("ratingValue"),
"review_count": (node.get("aggregateRating") or {}).get("reviewCount"),
"address": node.get("address"),
"telephone": node.get("telephone"),
"price_range": node.get("priceRange"),
"hours": node.get("openingHours"),
"url": url,
}
return {"biz_id": biz_id, "url": url}
Nilai meta[name="yelp-biz-id"] adalah encoded business ID yang nanti dibutuhkan untuk endpoint ulasan. Ambil ini di sini — Anda akan memakainya pada langkah berikutnya.
Langkah 4: Scrape Ulasan Yelp dengan Pagination
Di sinilah Fusion API kalah, dan scraping unggul. Endpoint GraphQL internal Yelp mengembalikan teks ulasan lengkap, info reviewer, tanggal, rating, dan jumlah vote — semua yang disembunyikan API.
Endpoint-nya adalah https://www.yelp.com/gql/batch, dan memakai documentId statis untuk operasi GetBusinessReviewFeed. Pagination berjalan lewat cursor yang di-encode dengan base64.
import base64
GQL_URL = "https://www.yelp.com/gql/batch"
DOC_ID = "ef51f33d1b0eccc958dddbf6cde15739c48b34637a00ebe316441031d4bf7681"
def fetch_reviews(enc_biz_id: str, num_pages: int = 5):
all_reviews = []
for page in range(num_pages):
offset = page * 10
cursor = base64.b64encode(
json.dumps({"version": 1, "offset": offset}).encode()
).decode()
payload = [{
"operationName": "GetBusinessReviewFeed",
"variables": {
"encBizId": enc_biz_id,
"reviewsPerPage": 10,
"after": cursor,
"sortBy": "DATE_DESC",
"language": "en",
},
"extensions": {
"operationType": "query",
"documentId": DOC_ID,
},
}]
r = requests.post(
GQL_URL,
json=payload,
headers={
**HEADERS,
"content-type": "application/json",
"x-apollo-operation-name": "GetBusinessReviewFeed",
"apollographql-client-name": "yelp-main-frontend",
},
impersonate="chrome131",
)
if r.status_code != 200:
print(f"Pengambilan ulasan gagal di offset {offset}: {r.status_code}")
break
data = r.json()
# Telusuri struktur respons untuk mengambil ulasan
try:
reviews = data[0]["data"]["business"]["reviews"]["edges"]
for edge in reviews:
node = edge.get("node", {})
all_reviews.append({
"reviewer": node.get("author", {}).get("displayName"),
"rating": node.get("rating"),
"date": node.get("localizedDate"),
"text": node.get("text", {}).get("full"),
})
except (KeyError, IndexError, TypeError):
break
import time, random
time.sleep(random.uniform(3, 7))
return all_reviews
Setiap halaman mengembalikan 10 ulasan. Naikkan offset di cursor base64 untuk pagination. Parameter sortBy menerima DATE_DESC (terbaru dulu), RATING_ASC, RATING_DESC, dan lainnya.
Langkah 5: Ekspor Data Yelp yang Sudah di-Scrape
import pandas as pd
# Misalkan Anda sudah mengumpulkan businesses dan reviews
df_businesses = pd.DataFrame(businesses)
df_businesses.to_csv("yelp_businesses.csv", index=False)
df_reviews = pd.DataFrame(all_reviews)
df_reviews.to_csv("yelp_reviews.csv", index=False)
# Atau simpan sebagai JSON agar lebih fleksibel
import json
with open("yelp_data.json", "w") as f:
json.dump({"businesses": businesses, "reviews": all_reviews}, f, indent=2)
Buat pembaca yang memilih jalur no-code, Thunderbit mengekspor data yang sama langsung ke Excel, Google Sheets, Airtable, atau Notion — tanpa perlu pandas atau kode untuk menulis file CSV.
Playbook Anti-Blokir: Cara Scrape Yelp Tanpa Kena Blokir
Bagian ini adalah alasan utama artikel ini dibuat. Sejak akhir 2024, pertahanan anti-bot Yelp makin ketat — TLS fingerprinting, pemeriksaan reputasi IP, CAPTCHA, dan analisis perilaku semuanya dipakai. Banyak panduan lama sudah basi karena ditulis sebelum pengetatan ini.

Strateginya bertingkat. Setiap lapisan menurunkan risiko blokir; kalau digabung, scraping jangka panjang jadi jauh lebih realistis.
Lapisan 1: Header Request yang Realistis
Header default Python requests mengirim User-Agent: python-requests/2.x — langsung ketahuan. Tapi User-Agent yang realistis saja belum cukup. Yelp memeriksa keseluruhan set header Client Hints supaya konsisten.
FULL_HEADERS = {
"authority": "www.yelp.com",
"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
"AppleWebKit/537.36 (KHTML, like Gecko) "
"Chrome/124.0.0.0 Safari/537.36",
"accept": "text/html,application/xhtml+xml,application/xml;q=0.9,"
"image/avif,image/webp,image/apng,*/*;q=0.8",
"accept-language": "en-US,en;q=0.9",
"accept-encoding": "gzip, deflate, br",
"sec-ch-ua": '"Chromium";v="124", "Google Chrome";v="124", "Not-A.Brand";v="99"',
"sec-ch-ua-mobile": "?0",
"sec-ch-ua-platform": '"Windows"',
"sec-fetch-dest": "document",
"sec-fetch-mode": "navigate",
"sec-fetch-site": "same-origin",
"sec-fetch-user": "?1",
"upgrade-insecure-requests": "1",
"referer": "https://www.yelp.com/",
"cookie": "intl_splash=false",
}
Tiga kesalahan yang bikin Anda ditandai:
- UA ngaku Chrome tapi
sec-ch-uahilang atau bertentangan dengan versi UA sec-ch-ua-platformbilang "Windows" tapi string UA menunjukkan macOS- UA yang sama persis dipakai ribuan request dari satu IP — rotasi pool 10–20 string Chrome/Firefox/Safari terbaru
Lapisan 2: Rate Limiting dan Delay Acak
Pola timing yang mudah ditebak adalah sinyal bahaya. Tambahkan interval tidur acak dan implementasikan exponential backoff untuk response error.
import random, time
def polite_get(client_get, url, attempt=0):
r = client_get(url, headers=FULL_HEADERS, impersonate="chrome131")
if r.status_code in (403, 429, 503):
if attempt >= 4:
raise RuntimeError(f"Diblokir setelah {attempt + 1} percobaan pada {url}")
backoff = 2 ** (attempt + 1) + random.random()
print(f" Dapat {r.status_code}, backoff {backoff:.1f} detik (percobaan {attempt + 1})")
time.sleep(backoff)
return polite_get(client_get, url, attempt + 1)
time.sleep(random.uniform(3, 7))
return r
| Parameter | Nilai yang Disarankan |
|---|---|
| Jeda acak antar request | random.uniform(3, 7) detik |
| Backoff untuk 429/403/503 | 2 → 4 → 8 → 16 detik, maksimal 5 percobaan |
| Worker bersamaan per IP | 1 (serial per IP; gunakan proxy untuk paralelisme) |
| Laju maksimal per residential IP | ~1 request / 5 detik (~12 rpm) |
Lapisan 3: Rotasi User-Agent dan Session
Putar lewat pool string User-Agent browser nyata. Simpan session dan cookie agar perilaku browsing terlihat alami — Yelp memakai deteksi berbasis cookie, jadi membuat session baru setiap request justru mencurigakan.
UA_POOL = [
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 Chrome/124.0.0.0 Safari/537.36",
"Mozilla/5.0 (Macintosh; Intel Mac OS X 14_4_1) AppleWebKit/537.36 Chrome/124.0.0.0 Safari/537.36",
"Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:125.0) Gecko/20100101 Firefox/125.0",
"Mozilla/5.0 (Macintosh; Intel Mac OS X 14_4_1; rv:125.0) Gecko/20100101 Firefox/125.0",
"Mozilla/5.0 (Macintosh; Intel Mac OS X 14_4_1) AppleWebKit/605.1.15 Safari/17.4.1",
# Tambahkan 5-10 string terbaru lainnya
]
Lapisan 4: Rotasi Proxy
Pada volume nyata, Anda butuh residential proxy. Datacenter dan proxy gratis tidak bekerja di Yelp — lapisan reputasi IP Yelp akan lebih dulu memblokir rentang IP AWS, GCP, dan DigitalOcean.
| Provider | Harga awal $/GB | Catatan |
|---|---|---|
| IPRoyal | $1.75/GB | Paling murah; menjalankan tutorial Yelp yang paling sering dikutip |
| Decodo (ex-Smartproxy) | $3.20–$3.50 | Rasio GB/$ terbaik pada skala besar |
| Bright Data | $4.00 (PAYG) | Pool 150M+ IP; punya halaman khusus Yelp Proxies |
| Oxylabs | $6.00–$8.00 | Premium; 10M+ IP |
| Aluvia (mobile SIM) | $3.00 | IP mobile operator AS asli, diposisikan untuk Yelp |
Rotating residential (IP baru tiap request) paling cocok untuk crawl pencarian volume tinggi. Sticky session (menahan satu IP selama 10 menit) lebih baik saat perlu mempertahankan cookie di alur halaman bisnis → ulasan → pagination.
Lapisan 5: Mendeteksi dan Menangani Blokir
Tidak semua blokir tampil sama. Yelp sering menyajikan shell generik "page not available" alih-alih CAPTCHA, makanya scraper yang naif mengira mereka dapat data padahal sebenarnya cuma respons kosong.
BLOCK_MARKERS = (
"captcha", "px-captcha", "page not available",
"access denied", "unusual traffic",
)
def is_blocked(resp):
if resp.status_code in (401, 403, 429, 503):
return True
body = resp.text.lower()
if any(m in body for m in BLOCK_MARKERS):
return True
# Kalau ini halaman search/business tapi react-root-props hilang,
# berarti Yelp mengirim respons blokir yang sudah dipreteli
if "react-root-props" not in body and "/biz/" in str(resp.url):
return True
return False
| Sinyal | Arti |
|---|---|
| HTTP 403 | Blokir keras — IP/header/TLS sudah hangus |
| HTTP 429 | Rate limit — sering bisa pulih dengan backoff |
| HTTP 503 | Blokir generik atau load shedding |
Redirect ke /error atau body "page not available" | Soft block |
| kosong hanya dengan | Halaman challenge menunggu JS |
captcha / g-recaptcha / px-captcha di body | Eskalasi — CAPTCHA diperlukan |
react-root-props hilang di halaman listing | Respons blokir yang sudah dipreteli |
Lapisan 6: Trik Parsing yang Tahan Lama — JSON Tersembunyi, Bukan CSS Selector
Perlu diulang: Yelp mengacak nama class CSS saat build time. Scraper yang bergantung pada h3.y-css-14xwok2 akan rusak dalam hitungan minggu saat Yelp deploy ulang dengan h3.y-css-hcq7b9.
Payload yang tidak berubah:
<script type="application/ld+json">— data terstruktur schema.org (nama, alamat, telepon, rating, jam buka)<script data-id="react-root-props">— data hasil pencarian lengkap dalam bentuk JSONhttps://www.yelp.com/gql/batch— endpoint GraphQL ulasan dengandocumentIdyang stabil
Kalau Anda parsing class CSS, Anda sedang membangun di atas pasir. Parse JSON-nya saja.
Lapisan 7: Fallback Stealth Browser
Naikkan ke headless browser hanya ketika curl_cffi + residential proxy tidak tembus — biasanya saat Yelp menampilkan halaman challenge JavaScript atau CAPTCHA.
Untuk 95% kebutuhan scraping bisnis/pencarian/ulasan, curl_cffi + JSON tersembunyi + residential proxy lebih cepat, lebih murah, dan lebih andal daripada browser. Tapi kalau memang butuh browser:
| Tool | Status (2025) | Catatan |
|---|---|---|
| rebrowser-playwright | Titik awal yang direkomendasikan | Playwright yang dipatch, drop-in, untuk memperbaiki kebocoran CDP |
| nodriver | Terbaik di kelasnya untuk stealth Chrome | Penerus undetected-chromedriver; menghindari protokol WebDriver sepenuhnya |
| patchright | Fork Playwright yang aktif dipelihara | Lolos tes deteksi modern |
| playwright-stealth | Matang | Mem-patch navigator.webdriver, menghapus HeadlessChrome dari UA |
Lewati Selenium biasa untuk Yelp. Terlalu gampang terdeteksi fingerprint-nya.
Yelp Fusion API vs. Python Scraping vs. Thunderbit: Perbandingan Lengkap
| Dimensi | Yelp Fusion API | Python Scraping | Thunderbit |
|---|---|---|---|
| Teks ulasan lengkap | ❌ 3 cuplikan × ~160 karakter | ✅ Tak terbatas (GraphQL) | ✅ Template ulasan bawaan |
| Metadata ulasan (vote, balasan pemilik) | ❌ | ✅ | ✅ Via field yang disarankan AI |
| Foto | ❌ (0 pada Base) | ✅ Tak terbatas | ✅ |
| Maksimum hasil per pencarian | 240 (dulu 1.000 sebelum 2024) | Tak terbatas (dipaginasi) | Tak terbatas |
| Batas harian | 300–500 (baru) / 5.000 (lama) | Hanya budget proxy | Berbasis kredit (3.000/bulan di Pro) |
| Usaha setup | ~15 menit | Beberapa jam hingga beberapa hari | ~2 menit |
| Penanganan anti-bot | N/A | Masalah Anda sendiri | Ditangani (mode cloud) |
| Risiko legal | Rendah (resmi) | Menengah (area abu-abu ToS) | Menengah (sama seperti scraping) |
| Biaya awal | $29/bulan | ~$0,75–$4/GB proxy + waktu dev | Paket gratis |
| Biaya untuk penggunaan berat | $643+/bulan | $50–$500/bulan proxy + waktu dev | $38–$49/bulan |
| Ekspor data | JSON | CSV/JSON (harus Anda buat) | Excel / Sheets / Airtable / Notion — gratis |
| Maintenance | Rendah | Tinggi (selector rusak, anti-bot makin ketat) | Rendah (AI menyesuaikan ulang) |
Tips Legal dan Etika untuk Scraping Yelp
Saya bukan pengacara, dan ini bukan nasihat hukum. Tapi lanskap hukumnya sudah cukup berubah dalam dua tahun terakhir sehingga Anda sebaiknya tahu dasar-dasarnya sebelum menginvestasikan waktu ke proyek scraping Yelp.
Apa yang dikatakan Terms of Service Yelp: Pembaruan ToS Oktober 2025 secara eksplisit melarang penggunaan "robot, spider... atau perangkat otomatis lain" untuk "mengakses, mengambil, menyalin, melakukan scrape, atau mengindeks bagian mana pun dari Service." Di situ juga ditambahkan bahasa tentang "AI Technologies dan/atau alat otomatis lain."
Yelp Support menegaskan lagi: "Yelp tidak mengizinkan scraping apa pun dari situs ini."
Apa yang dikatakan robots.txt: robots.txt Yelp punya wildcard User-agent: * / Disallow: / dan secara khusus memblokir GPTBot, ClaudeBot, PerplexityBot, CCBot, dan Meta-ExternalAgent. Hanya Googlebot, Bingbot, dan beberapa crawler media sosial yang di-whitelist.
Preseden hukum yang relevan: Dalam Meta v. Bright Data (N.D. Cal. Jan 2024), pengadilan memutuskan bahwa scraping data publik yang bisa diakses tanpa login tidak melanggar Terms of Service Meta. Pembeda utamanya: data publik tanpa login vs. data yang memerlukan login. Kasus hiQ v. LinkedIn menetapkan bahwa scraping data publik kemungkinan tidak melanggar CFAA, tetapi hiQ tetap kalah pada klaim tort negara bagian (trespass to chattels, misappropriation) dan dikenai putusan $500.000.
Panduan praktis:
- Scrape hanya halaman publik yang bisa diakses tanpa login
- Batasi laju request Anda (jeda di panduan ini juga berfungsi sebagai batas etis)
- Jangan menjual ulang teks ulasan mentah yang dikaitkan ke pengguna bernama — hormati privasi reviewer
- Patuhi hukum perlindungan data lokal (CCPA, GDPR)
- Jangan login untuk melakukan scraping — itu melewati batas otorisasi
- Anggap info bisnis (nama/alamat/telepon/rating) sebagai data faktual publik; teks ulasan lebih sensitif
Konsultasikan dengan profesional hukum untuk situasi spesifik Anda.
Penutup
Tiga jalur, satu tujuan.
Yelp Fusion API adalah opsi resmi dan minim perawatan — tetapi dibatasi 3 cuplikan ulasan dan mulai dari $29/bulan. Scraping Python memberi Anda kontrol penuh atas setiap titik data di Yelp, tapi butuh investasi nyata: curl_cffi untuk impersonasi TLS, residential proxy, delay acak, parsing JSON tersembunyi, dan maintenance berkelanjutan seiring pertahanan Yelp berkembang. Thunderbit membawa Anda dari "saya butuh data Yelp" ke "ini spreadsheet saya" dalam sekitar 30 detik, tanpa kode dan tanpa konfigurasi proxy.
Inti anti-blokir yang benar-benar bekerja di 2025: header realistis dengan Client Hints lengkap, curl_cffi untuk impersonasi fingerprint TLS, delay acak dengan exponential backoff, rotasi residential proxy, dan — yang paling penting — parsing JSON tersembunyi (application/ld+json dan react-root-props) alih-alih selector CSS yang rapuh.
Masih ragu jalur mana yang cocok? Coba dulu paket gratis Thunderbit. Kalau sudah cukup, Anda menghemat berjam-jam. Kalau Anda butuh kontrol lebih besar — pipeline programatik penuh, field kustom, integrasi CRM yang rapat — panduan Python di atas sudah mencakup semuanya. Dan kalau ingin melihat lebih luas soal lanskap alat scraping, cek rangkuman kami tentang ekstensi Chrome web scraper terbaik atau panduan mengambil data dari website ke Excel.
Coba Thunderbit untuk Ekstraksi Data Yelp Get Started Free
FAQ
Bisakah saya scrape Yelp secara gratis dengan Python?
Bisa — pakai library gratis seperti curl_cffi, parsel, dan jmespath. Tapi pada volume nyata (lebih dari beberapa lusin halaman), Anda akan butuh residential proxy berbayar, yang harganya mulai sekitar $1.75/GB di IPRoyal. Thunderbit juga menawarkan paket gratis dengan 6 halaman/bulan untuk ekstraksi cepat tanpa kode.
Apakah Yelp memblokir scraper?
Ya, dan cukup agresif. Yelp memakai TLS/JA3 fingerprinting, penilaian reputasi IP, CAPTCHA, analisis perilaku, dan class CSS obfuscated yang berubah-ubah. requests biasa langsung diblokir pada hit pertama. Strategi anti-blokir berlapis di panduan ini — curl_cffi untuk impersonasi TLS, header realistis, delay acak, dan residential proxy — adalah yang bekerja di 2025.
Apakah Yelp Fusion API lebih baik daripada scraping?
Tergantung kebutuhan Anda. API ini resmi dan risikonya rendah, tetapi hanya mengembalikan 3 cuplikan ulasan masing-masing sekitar 160 karakter, membatasi hasil pencarian hingga 240, dan mulai dari $29/bulan. Kalau Anda butuh teks ulasan lengkap, metadata ulasan, atau lebih dari beberapa ratus record per hari, scraping adalah satu-satunya opsi.
Bagaimana cara scrape ulasan Yelp dengan Python?
Gunakan curl_cffi dengan impersonate="chrome131" untuk mengambil halaman bisnis, ambil encoded business ID dari <meta name="yelp-biz-id">, lalu kirim POST ke https://www.yelp.com/gql/batch dengan operasi GetBusinessReviewFeed dan lakukan pagination via cursor after yang di-encode base64. Kode langkah demi langkahnya ada di bagian tutorial di atas. Repo Scrapfly Yelp scraper juga bisa jadi referensi implementasi yang solid.
Bisakah saya scrape Yelp tanpa coding?
Bisa — AI Web Scraper Thunderbit menyediakan template siap pakai untuk bisnis Yelp dan ulasan. Buka halaman Yelp, klik AI Suggest Fields, lalu klik Scrape. Ekspor ke Google Sheets, Excel, Airtable, dan Notion gratis di semua paket, termasuk paket gratis.
Pelajari Lebih Lanjut


