Cara Saya Scrape Yelp dengan Python Tanpa Kena Blokir

Terakhir diperbarui pada April 15, 2026
Cara Saya Scrape Yelp dengan Python Tanpa Kena Blokir

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.

yelp_stats_bd6a43108e.png

Berikut siapa yang paling diuntungkan dan data apa yang mereka ambil:

Kasus PenggunaanField Data UtamaKenapa Penting
Sales & lead generationNama bisnis, telepon, website, alamat, kategori, ratingMembangun daftar prospek SMB lokal yang tertarget — 4 dari 5 pengguna Yelp siap membeli saat datang
Competitive intelligenceUlasan, rating bintang, volume ulasan, sentimenMemantau reputasi kompetitor, menemukan celah layanan, melacak tren
Riset pasar & NLPTeks ulasan penuh, tanggal, metadata reviewerAnalisis sentimen, pemodelan topik — ulasan Yelp adalah salah satu korpus NLP paling sering dipakai dalam riset akademik
Properti & pemilihan lokasiKepadatan bisnis, campuran kategori, kualitas ulasan per areaPemilihan lokasi franchise dan ritel — Yelp menjual Location Intelligence sebagai produk B2B berlisensi untuk kebutuhan ini
Ecommerce & operasionalSinyal harga, keluhan pelanggan, jam layananMelacak 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

FaktorYelp Fusion APIWeb Scraping PythonThunderbit (No-Code)
Ulasan lengkap❌ Hanya 3 cuplikan (~160 karakter masing-masing)✅ Semua ulasan via GraphQL✅ Semua ulasan yang terlihat
Rate limit300–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 terstrukturTak terbatas (parse HTML/JSON)Field yang disarankan AI
Penanganan anti-botN/A (resmi)Harus dibuat sendiriDitangani otomatis
Risiko legal✅ Resmi⚠️ Area abu-abu ToS⚠️ Sama seperti scraping
BiayaMinimum $29/bulanGratis (+ biaya proxy $0,75–$4/GB)Tersedia paket gratis
MaintenanceRendah (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:

Cara Kerjanya di Praktik

  1. Buka halaman hasil pencarian Yelp atau halaman bisnis di Chrome
  2. Klik AI Suggest Fields di ekstensi Thunderbit — AI membaca halaman dan mengusulkan kolom (nama bisnis, rating, jumlah ulasan, rentang harga, kategori, alamat, telepon, URL)
  3. 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

WaktuPython ScraperThunderbit
Run pertamaBeberapa jam hingga beberapa hari (buat selector, tangani pagination, proxy, retry logic)~30 detik dengan template Yelp siap pakai
Saat markup Yelp berubahTulis ulang selector secara manualKlik AI Suggest Fields lagi — otomatis menyesuaikan
Saat IP diblokirDebug, putar ulang pool proxy, uji lagiMode cloud menangani rotasi IP
Ekspor ke Google SheetsTulis OAuth + glue code pandasSekali 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 beautifulsoup4akan 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

LibraryCocok untukDukung JS?Anti-Bot?Tingkat BelajarKecepatan
requests + BeautifulSoupScraping satu halaman sederhana (rusak untuk Yelp)Sangat rendahCepat (sampai diblokir)
httpx async + parselScraping async skala besarRendahSangat cepat
curl_cffi + parselKhusus Yelp: impersonasi TLS✅ TLS/JA3/HTTP2RendahSangat cepat
Scrapy 2.14Pipeline crawl penuh dengan paginationParsial (via scrapy-playwright)AutoThrottle, retry middlewareMenengah-TinggiCepat
Selenium 4.43 / Playwright 1.58Halaman banyak JS, workaround CAPTCHAParsialMenengahLambat (~10–30 halaman/menit)
ThunderbitNon-coder, ekstraksi cepat✅ (browser)Built-in (mode cloud)Sangat rendahCepat

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.

yelp_antiblock_518f0447bb.png

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:

  1. UA ngaku Chrome tapi sec-ch-ua hilang atau bertentangan dengan versi UA
  2. sec-ch-ua-platform bilang "Windows" tapi string UA menunjukkan macOS
  3. 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
ParameterNilai yang Disarankan
Jeda acak antar requestrandom.uniform(3, 7) detik
Backoff untuk 429/403/5032 → 4 → 8 → 16 detik, maksimal 5 percobaan
Worker bersamaan per IP1 (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.

ProviderHarga awal $/GBCatatan
IPRoyal$1.75/GBPaling murah; menjalankan tutorial Yelp yang paling sering dikutip
Decodo (ex-Smartproxy)$3.20–$3.50Rasio GB/$ terbaik pada skala besar
Bright Data$4.00 (PAYG)Pool 150M+ IP; punya halaman khusus Yelp Proxies
Oxylabs$6.00–$8.00Premium; 10M+ IP
Aluvia (mobile SIM)$3.00IP 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
SinyalArti
HTTP 403Blokir keras — IP/header/TLS sudah hangus
HTTP 429Rate limit — sering bisa pulih dengan backoff
HTTP 503Blokir 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 bodyEskalasi — CAPTCHA diperlukan
react-root-props hilang di halaman listingRespons 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 JSON
  • https://www.yelp.com/gql/batch — endpoint GraphQL ulasan dengan documentId yang 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:

ToolStatus (2025)Catatan
rebrowser-playwrightTitik awal yang direkomendasikanPlaywright yang dipatch, drop-in, untuk memperbaiki kebocoran CDP
nodriverTerbaik di kelasnya untuk stealth ChromePenerus undetected-chromedriver; menghindari protokol WebDriver sepenuhnya
patchrightFork Playwright yang aktif dipeliharaLolos tes deteksi modern
playwright-stealthMatangMem-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

DimensiYelp Fusion APIPython ScrapingThunderbit
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 pencarian240 (dulu 1.000 sebelum 2024)Tak terbatas (dipaginasi)Tak terbatas
Batas harian300–500 (baru) / 5.000 (lama)Hanya budget proxyBerbasis kredit (3.000/bulan di Pro)
Usaha setup~15 menitBeberapa jam hingga beberapa hari~2 menit
Penanganan anti-botN/AMasalah Anda sendiriDitangani (mode cloud)
Risiko legalRendah (resmi)Menengah (area abu-abu ToS)Menengah (sama seperti scraping)
Biaya awal$29/bulan~$0,75–$4/GB proxy + waktu devPaket gratis
Biaya untuk penggunaan berat$643+/bulan$50–$500/bulan proxy + waktu dev$38–$49/bulan
Ekspor dataJSONCSV/JSON (harus Anda buat)Excel / Sheets / Airtable / Notion — gratis
MaintenanceRendahTinggi (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

Shuai Guan
Shuai Guan
CEO di Thunderbit | Ahli Otomasi Data AI Shuai Guan adalah CEO Thunderbit dan lulusan Teknik dari University of Michigan. Dengan pengalaman hampir satu dekade di bidang teknologi dan arsitektur SaaS, ia berfokus mengubah model AI yang kompleks menjadi alat ekstraksi data praktis tanpa coding. Di blog ini, ia membagikan wawasan apa adanya yang sudah teruji di lapangan tentang web scraping dan strategi otomasi untuk membantu Anda membangun alur kerja yang lebih cerdas dan berbasis data. Saat tidak sedang mengoptimalkan alur kerja data, ia menyalurkan ketelitian yang sama pada kecintaannya terhadap fotografi.
Daftar Isi

Ambil data halaman web cukup dengan bertanya

Cukup bilang apa yang kamu butuhkan dalam bahasa Inggris sederhana. Atau lebih baik lagi, tak perlu bilang apa-apa.

Coba Thunderbit gratis
Ekstrak Data menggunakan AI
Dengan mudah transfer data ke Google Sheets, Airtable, atau Notion
Chrome Store Rating
PRODUCT HUNT#1 Product of the Week