Yelpissä on yli 330 miljoonaa arvostelua 8,4 miljoonalla aktiivisella yrityssivulla — ja tämän datan saaminen käyttökelpoiseen muotoon on nyt vaikeampaa kuin koskaan. Yelpin vuosien 2024–2025 tiukennettu torjunta bottien käyttöä vastaan on rikkonut hiljaisesti suurimman osan olemassa olevista Python-kaavojen mukaisista kaavintaoppaista.
Jos olet viime aikoina yrittänyt ajaa Yelp-kaavintaohjelmaa ja törmännyt 403-virheisiin, tyhjiin HTML-vastauksiin tai CAPTCHAsuojiin, joita ei ollut vielä puoli vuotta sitten, et kuvittele tätä. Yelp käyttää nyt TLS/JA3-fingerprintingia, kiertäviä obfuskoituja CSS-luokkanimiä ja aggressiivista IP-maineen pisteytystä — eli vanha requests + BeautifulSoup -lähestymistapa, jota jokainen opas yhä suosittelee, kaatuu jo ensimmäiseen pyyntöön. Olen käyttänyt viikkoja testaten eri tapoja Yelpin nykyistä pinottua suojausta vastaan, ja tämä opas kattaa kaiken, mikä oikeasti toimii vuonna 2025: virallisen Fusion API:n (ja miksi se ei todennäköisesti riitä), täyden Python-kaavintatyönkulun kerroksellisella estojen kiertostrategialla sekä kahden klikkauksen koodittoman vaihtoehdon Thunderbitillä niille, jotka haluavat vain datan ilman pitkää debuggausrumbaa.
Kokeile Thunderbitiä Yelp-kaavintaan
Miksi kaapia Yelp-dataa Pythonilla — ja kuka siitä oikeasti hyötyy?
Ennen kuin kirjoitat riviäkään koodia, mikä on Yelp-datan todellinen liiketoimintahyöty? Alusta ei ole vain ravintola-arvostelusivusto — se on käytännössä reaaliaikainen tietokanta paikallisista yrityksistä, jossa on jäsennellyt yhteystiedot, arvosanat, kategoriat, aukioloajat ja satoja miljoonia asiakasarvosteluja.

Näin eri käyttäjät hyötyvät ja mitä he yleensä poimivat:
| Käyttötapaus | Keskeiset kentät | Miksi sillä on väliä |
|---|---|---|
| Myynti ja liidien generointi | Yrityksen nimi, puhelin, verkkosivusto, osoite, kategoria, arvosana | Rakenna kohdennettuja potentiaalisten asiakkaiden listoja paikallisista pienyrityksistä — 4/5 Yelp-käyttäjää on ostopäätösvalmis heti palveluun tullessaan |
| Kilpailija-analyysi | Arvostelut, tähtiarvostelut, arvostelujen määrä, sävy | Seuraa kilpailijoiden mainetta, tunnista palveluaukot ja havaitse trendit |
| Markkinatutkimus ja NLP | Koko arvosteluteksti, päivämäärät, arvostelijan metatiedot | Sentimenttianalyysi, aiheiden mallinnus — Yelp-arvostelut ovat akateemisessa tutkimuksessa yksi käytetyimmistä NLP-aineistoista |
| Kiinteistöt ja sijaintivalinta | Yritystiheys, kategoriajakauma, alueen arvostelulaatu | Ketjujen ja vähittäiskaupan sijaintivalinta — Yelp myy Location Intelligence -ratkaisua lisensoituna B2B-tuotteena juuri tätä varten |
| Verkkokauppa ja operatiivinen toiminta | Hinnoittelusignaalit, asiakasvalitukset, palveluajat | Seuraa, miten kilpailijoita arvioidaan, ja tunnista toimintamalleja |
Yhteinen nimittäjä: todellinen tavoite on jäsennelty data, ja Python on vain yksi väline sen saamiseen. Osa lukijoista haluaa täyden ohjelmallisen hallinnan. Toiset tarvitsevat vain taulukon Austinin putkimieskontakteista. Molemmat polut käydään läpi tässä oppaassa.
Yelp Fusion API vai Python-kaavinta: kumpaa kannattaa käyttää?
Useimmat oppaat ohittavat tämän päätöksen täysin ja hyppäävät suoraan koodiin arvioimatta, olisiko virallinen Yelp Fusion API (nykyisin brändätty nimellä “Yelp Places API”) riittänyt. Oman kokemukseni mukaan tämän arvioinnin tekeminen säästää tuntikausia turhaa työtä — API on erinomainen joihinkin tarpeisiin, mutta täysin riittämätön toisiin.
Mitä Fusion API oikeasti tarjoaa
Fusion API tarjoaa jäsennellyn yrityshaun, yritystiedot, automaattitäydennyksen ja arvostelupisteen. Se on valtuutettu, hyvin dokumentoitu eikä vaadi anti-bot-kikkailua.
Mutta arvostelupäätepisteessä homma menee pieleen. Yelpin työntekijät ovat vahvistaneet GitHubissa seuraavaa:
“Yelp API ei palauta koko arvostelutekstiä. Oletuksena tarjotaan kolme 160 merkin mittaista arvostelukatkelmaa.” — Yelp staff -vastaus, GitHub Issue #163
Tämä ei ole bugi — se on tarkoituksellista. API rajoittaa fyysisesti 3 arvostelukatkelmaan (Premiumissa 7), ja jokainen on typistetty noin 160 merkkiin. Ei arvostelun metatietoja (hyödyllinen/hauska/cool), ei arvostelijan historiaa, ei omistajan vastauksia. Ja uusien asiakkaiden päivittäinen rajoitus putosi toukokuun 2023 jälkeen 300–500 kutsuun päivässä — aiemmasta 5 000:sta. Aloitushinta on $29/kk.
Päätöspuikko
| Tekijä | Yelp Fusion API | Python-kaavinta | Thunderbit (kooditon) |
|---|---|---|---|
| Koko arvosteluhistoria | ❌ Vain 3 katkelmaa (~160 merkkiä/kpl) | ✅ Kaikki arvostelut GraphQL:n kautta | ✅ Kaikki näkyvät arvostelut |
| Rajoitukset | 300–500/pv (uudet); 5 000 (vanhat) | Itse hallittu (proxy-budjetti) | Kreditipohjainen |
| Käyttöönotto | ~15 min (API-avain + SDK) | Tunteja tai päiviä | ~2 min |
| Yrityskentät | ~20 jäsenneltyä kenttää | Rajoittamaton (HTML/JSON-parsinta) | AI:n ehdottamat kentät |
| Anti-bot-käsittely | Ei sovellu (valtuutettu) | Rakennettava itse | Hoituu automaattisesti |
| Juridinen riski | ✅ Valtuutettu | ⚠️ ToS-harmaa alue | ⚠️ Sama kuin kaavinnassa |
| Hinta | Alkaen $29/kk | Ilmainen (+ proxy-kulut $0,75–$4/GB) | Ilmainen taso saatavilla |
| Ylläpito | Matala (API vakaa) | Korkea (valitsimet vanhenevat, suojaus kiristyy) | Matala (AI mukautuu uudelleen) |
Käytä Fusion API:a, jos: tarvitset perustiedot yrityksistä, pieniä hakuja tai valtuutetun integraation — ja 3 arvostelukatkelmaa per yritys riittää.
Käytä Python-kaavintaa, jos: tarvitset täyden arvostelutekstin, kaikki arvostelut yhdestä yrityksestä, arvostelujen metatiedot, yli 240 tulosta haussa tai budjettisi on alle $29/kk.
Käytä Thunderbitiä, jos: haluat datan nopeasti ilman koodin kirjoittamista tai ylläpitoa. Tästä lisää alla koodittomassa osiossa.
Kooditon oikotie: kaavi Yelp Thunderbitillä (ei Pythonia)
Ennen kuin syvennymme Pythoniin, tässä nopein reitti niille, joiden oikea tavoite on data — ei ohjelmointi. Jokainen kilpailijan opas olettaa Python-osaamista, mutta Thunderbitillä tehdyn työni aikana olen huomannut, että valtava osa “scrape Yelp” -hakijoista on myyjiä, operatiivisia johtajia ja pienyrittäjiä, jotka haluavat vain taulukon paikallisista yrityksistä — eivät tiivistä kurssia TLS-fingerprintingiin.
Thunderbitillä on valmiina Yelp-pohjia:
- Yelp Business Web Scraper — poimii yrityksen nimen, arvosanan, yhteystiedot, osoitteen, aukioloajat ja kategorian
- Yelp Review Scraper — poimii arvostelijan käyttäjänimen, arvostelun sisällön, arvosanan, päivämäärän ja sijainnin
Miten se toimii käytännössä
- Avaa Yelp-hakutulossivu tai yrityssivu Chromessa
- Klikkaa AI Suggest Fields Thunderbit-laajennuksessa — AI lukee sivun ja ehdottaa sarakkeet (yrityksen nimi, arvosana, arvostelujen määrä, hintataso, kategoria, osoite, puhelin, URL)
- Klikkaa Scrape — valmis
Valmiilla Yelp-pohjilla se on vielä helpompaa: avaa malli ja klikkaa Scrape.
Alasivujen kaavinta hoitaa rikastuksen automaattisesti — aloita Yelp-hakutulossivulta, ota käyttöön alasivukaavinta, ja Thunderbit käy jokaisella yrityssivulla poimimassa aukioloajat, koko arvostelut, verkkosivun, kuvat ja palvelut. Ei lisäasetuksia.
Sivutus on automaattinen — sekä klikkaus- että vierityspohjainen sivutus toimii suoraan valmiina. (Jos haluat tietää enemmän, katso sivutusoppaamme.)
Vienti on ilmainen kaikilla tasoilla — Excel, Google Sheets, Airtable, Notion, CSV, JSON. Ei pandasia, ei CSV-kirjoituskoodia.
Aikavertailu
| Aika | Python-kaavin | Thunderbit |
|---|---|---|
| Ensimmäinen ajo | Tunteja tai päiviä (valitsimet, sivutus, proxyt, retry-logiikka) | ~30 sekuntia valmiilla Yelp-pohjalla |
| Kun Yelp muuttaa merkkausta | Kirjoita valitsimet uusiksi käsin | Klikkaa AI Suggest Fields uudelleen — mukautuu automaattisesti |
| Kun IP estetään | Debuggaa, kierrätä proxy-poolit, testaa uudelleen | Cloud-tila hoitaa IP-kierron |
| Vie Google Sheetiin | Kirjoita OAuth- ja pandas-liima | Yksi klikkaus, ilmainen |
Jos kokeilet ensin Thunderbitiä ja huomaat sen riittävän tarpeisiisi, voit ohittaa loppuartikkelin. Jos tarvitset täyden ohjelmallisen hallinnan, omat kentät tai skaalaa yli muutaman tuhannen tietueen kuukaudessa — jatka lukemista.
Python-kirjastot Yelp-kaavintaan: minkä valitsen?
“Pitäisikö käyttää Scrapyä, BS4+requestsia vai Seleniumia?” on yksi yleisimmistä kysymyksistä r/webscraping-keskusteluissa Yelpistä. Silti jokainen opas valitsee vain oman suosikkikirjastonsa eikä selitä miksi. Tässä rehellinen yhteenveto.
Vuoden 2025 todellisuus: requests + BeautifulSoup on rikki Yelpissä
Se pino, jota jokainen klassinen Yelp-opas suosittelee — pip install requests beautifulsoup4 — jää kiinni jo ensimmäisessä pyynnössä vuonna 2025. Ei 50. pyynnössä. Ensimmäisessä.
Syy: Pythonin requests-kirjasto lähettää TLS/JA3-fingerprintin, joka ei vastaa mitään oikeaa selainta. Yelpin anti-bot-kerros tunnistaa sen TLS-kättelytasolla, ennen kuin User-Agent-otsikkoa edes luetaan. Testasin tätä toistuvasti — uusi IP, uskottavat otsikot, satunnaiset viiveet — ja silti sain välittömästi 403 Forbiddenin puhtaalla requestsillä.
Kirjastopäätösmatriisi
| Kirjasto | Paras käyttötarkoitus | Käsittelee JS:n? | Anti-Bot? | Oppimiskäyrä | Nopeus |
|---|---|---|---|---|---|
requests + BeautifulSoup | ❌ | ❌ | Erittäin matala | Nopea (kunnes estetään) | |
httpx async + parsel | Suuren mittakaavan async-kaavinta | ❌ | ❌ | Matala | Erittäin nopea |
curl_cffi + parsel | Yelp-kohtainen: TLS-imitointi | ❌ | ✅ TLS/JA3/HTTP2 | Matala | Erittäin nopea |
Scrapy 2.14 | Täydet crawl-putket sivutuksineen | Osittain (scrapy-playwrightin kautta) | AutoThrottle, retry-middleware | Keskitaso–korkea | Nopea |
Selenium 4.43 / Playwright 1.58 | JS-raskaat sivut, CAPTCHA-kiertotavat | ✅ | Osittain | Keskitaso | Hidas (~10–30 sivua/min) |
| Thunderbit | Ei-ohjelmoijille, nopeaan poimintaan | ✅ (selaimessa) | Sisäänrakennettu (Cloud-tila) | Erittäin matala | Nopea |
curl_cffi-läpimurto
Kirjasto, joka muutti Yelp-kaavintatyöni, on curl_cffi — Python-sidonta curl-impersonatelle. Se lähettää täsmälleen saman TLS/JA3- ja HTTP/2-fingerprintin kuin oikea Chrome, ja sen API on suora korvaaja requestsille:
from curl_cffi import requests
r = requests.get(
"https://www.yelp.com/biz/some-restaurant",
impersonate="chrome131",
)
print(r.status_code, len(r.text))
Tämä yksi muutos — from curl_cffi import requests sekä impersonate="chrome131" — ohittaa Yelpin suurimman anti-bot-kerroksen ilman selaimen käynnistämistä. Omat testini osoittavat, että ero on välittömien 403-virheiden ja siistien 200-vastausten välillä.
Suositeltu pino Yelpille vuonna 2025: curl_cffi + parsel + jmespath + residential-proxyt. Jos tarvitset täyden crawl-putken ajastuksella, kääri se Scrapy 2.14:ään ja curl_cffi-pohjaiseen downloader-middlewareen.
Python-ympäristön pystyttäminen Yelpin kaavintaa varten
- Vaikeustaso: Keskitaso
- Tarvittava aika: ~15 min asennukseen, 1–2 h toimivaan kaavintaohjelmaan
- Mitä tarvitset: Python 3.10+ (3.12 suositeltu), terminaali ja halutessasi residential-proxy-palvelu
Vaihe 1: Luo virtuaaliympäristö ja asenna paketit
python3.12 -m venv .venv
source .venv/bin/activate # Windowsissa: .venv\Scripts\activate
pip install "curl_cffi>=0.11" "parsel>=1.9" "jmespath>=1.0" pandas
Mitä kukin paketti tekee:
curl_cffi— tekee HTTP-pyynnöt Chromen TLS-fingerprintillä (anti-bot-kierto)parsel— CSS/XPath-valitsimet HTML:n parsimiseen (sama moottori kuin Scrapyssa, kevyempi)jmespath— deklaratiivinen JSON-kysely (siistimpi kuin sisäkkäinen dict-työskentely Yelpin upotetun JSONin kanssa)pandas— datan vienti CSV/Excel-muotoon
Valinnainen mutta hyödyllinen:
pip install fake-useragent # Huom: repo arkistoitiin huhtikuussa 2026, mutta on yhä asennettavissa
Vaihe vaiheelta: miten kaapia Yelp-dataa Pythonilla
Tämä on varsinainen opetusosa. Keskeinen oivallus, joka tekee kaikesta paljon kestävämpää: ohita CSS-valitsimet ja poimi piilotettu JSON. Yelp satunnaistaa CSS-luokkanimet build-vaiheessa (y-css-14xwok2 yhtenä viikkona, y-css-hcq7b9 seuraavana), joten niihin sidottu kaavin hajoaa viikkojen sisällä. Upotetut JSON-payloadit — application/ld+json-schema ja react-root-props — ovat vakaita.
Vaihe 2: kaavi Yelp-hakutulokset
Yelp-haku-URL:t noudattavat ennustettavaa muotoa: https://www.yelp.com/search?find_desc={term}&find_loc={location}. Hakutulosten data on upotettu <script data-id="react-root-props"> -tagiin JSONina — ei CSS-luokkien sekaan renderöitynä.
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"Estetty sivulla {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 ei löytynyt sivulta {page} — mahdollinen pehmeä esto")
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
Saat takaisin listan sanakirjoja, joissa on yrityksen nimi, URL, arvosana ja arvostelumäärä. Jos react-root-props puuttuu vastauksesta, sinulle on tarjoiltu estokuori — vaihda IP ja yritä uudelleen.
Cookie: intl_splash=false on vakiokierto Yelpin maa-splash-uudelleenohjaukseen. Ilman sitä ei-yhdysvaltalaiset IP:t päätyvät splash-sivulle, joka näyttää pehmeältä estolta, mutta ei ole sitä.
Vaihe 3: kaavi Yelp-yrityssivut
Jokainen hakutulosten yritys-URL johtaa tarkempaan sivuun, jossa on rikkaampi data. Vakain poimintakohde on <script type="application/ld+json"> -lohko — se sisältää schema.org-rakennetta, jota Yelp ylläpitää SEO:ta varten eikä obfuskoi sitä.
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}
meta[name="yelp-biz-id"] -arvo on koodattu yritystunniste, jota tarvitset arvostelupäätepisteeseen. Ota se talteen tästä — käytät sitä seuraavassa vaiheessa.
Vaihe 4: kaavi Yelp-arvostelut sivutuksella
Tässä kohtaa Fusion API jää jälkeen ja kaavinta loistaa. Yelpin sisäinen GraphQL-eräpäätepiste palauttaa koko arvostelutekstin, arvostelijan tiedot, päivämäärät, arvosanat ja äänimäärät — kaiken sen, minkä API piilottaa.
Päätepiste on https://www.yelp.com/gql/batch, ja se käyttää staattista documentId-tunnusta GetBusinessReviewFeed-operaatiolle. Sivutus toimii base64-koodatun cursorin kautta.
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"Arvostelun haku epäonnistui offsetissa {offset}: {r.status_code}")
break
data = r.json()
# Navigoi vastauksen rakenteessa ja poimi arvostelut
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
Jokainen sivu palauttaa 10 arvostelua. Kasvata offset-arvoa base64-cursorissa sivuttaaksesi. sortBy-parametri hyväksyy DATE_DESC (uusimmat ensin), RATING_ASC, RATING_DESC ja muita.
Vaihe 5: vie kaavittu Yelp-data
import pandas as pd
# Oletetaan, että olet kerännyt yritykset ja arvostelut
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)
# Tai tallenna JSON-muodossa joustavuuden vuoksi
import json
with open("yelp_data.json", "w") as f:
json.dump({"businesses": businesses, "reviews": all_reviews}, f, indent=2)
Koodittomalla polulla Thunderbit vie saman datan suoraan Exceliin, Google Sheetiin, Airtableen tai Notioniin — ilman pandasia tai tiedostonkirjoituskoodia.
Estojen kiertämisen pelikirja: miten kaapia Yelp ilman että jää kiinni
Tämä osio on koko artikkelin ydin. Yelpin anti-bot-keinot ovat selvästi koventuneet loppuvuodesta 2024 — TLS-fingerprinting, IP-maineen tarkistus, CAPTCHA:t ja käyttäytymisanalyysi ovat kaikki käytössä. Useimmat olemassa olevat oppaat ovat vanhentuneita, koska ne kirjoitettiin ennen tätä tiukennusta.

Strategia on kerroksittainen. Jokainen kerros pienentää estojen osuutta; yhdessä ne tekevät jatkuvasta kaavinnasta mahdollisen.
Kerros 1: uskottavat request-otsikot
Python requests lähettää oletuksena otsikon User-Agent: python-requests/2.x — se estetään välittömästi. Mutta edes uskottava User-Agent ei riitä. Yelp tarkistaa koko Client Hints -otsikkosarjan johdonmukaisuuden.
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",
}
Kolme virhettä, jotka laukaisevat hälytyksen:
- UA väittää olevansa Chrome, mutta
sec-ch-uapuuttuu tai on ristiriidassa version kanssa sec-ch-ua-platformsanoo “Windows”, mutta UA-merkkijono viittaa macOS:ään- Sama täsmälleen identtinen UA tuhansissa pyynnöissä yhdestä IP:stä — kierrätä 10–20 tuoreen Chrome/Firefox/Safari-merkkijonon poolia
Kerros 2: nopeusrajoitus ja satunnaiset viiveet
Ennustettavat aikamallit ovat punainen lippu. Lisää satunnaisia sleep-välejä ja toteuta eksponentiaalinen backoff virhevastausten kohdalla.
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"Estetty {attempt + 1} yrityksen jälkeen osoitteessa {url}")
backoff = 2 ** (attempt + 1) + random.random()
print(f" Sait {r.status_code}-vastauksen, odotetaan {backoff:.1f}s (yritys {attempt + 1})")
time.sleep(backoff)
return polite_get(client_get, url, attempt + 1)
time.sleep(random.uniform(3, 7))
return r
| Parametri | Suositeltu arvo |
|---|---|
| Satunnainen tauko pyyntöjen välillä | random.uniform(3, 7) sekuntia |
| Backoff 429/403/503-virheissä | 2 → 4 → 8 → 16 s, enintään 5 yritystä |
| Samanaikaiset työntekijät per IP | 1 (serialisoi per IP; käytä proxya rinnakkaisuuteen) |
| Suurin kestävä tahti residential-IP:llä | noin 1 pyyntö / 5 s (~12 rpm) |
Kerros 3: User-Agentin ja session kierto
Kierrätä oikeiden selain-User-Agentien poolia. Säilytä sessiot ja evästeet, jotta käyttäytyminen näyttää aidolta — Yelp käyttää evästepohjaista tunnistusta, joten jokaisen pyynnön aloittaminen täysin uutena sessiona on itsessään epäilyttävää.
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; 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",
# Lisää 5–10 muuta tuoretta merkkijonoa
]
Kerros 4: proxy-kierto
Todellisessa volyymissa tarvitset residential-proxyt. Datacenter- ja ilmaisproxyt eivät toimi Yelpissä — Yelpin IP-mainekerros hylkää ennakoivasti AWS-, GCP- ja DigitalOcean-IP-alueet.
| Palveluntarjoaja | Alkuhinta $/GB | Huomioita |
|---|---|---|
| IPRoyal | $1.75/GB | Halvin; ylläpitää usein siteerattua Yelp-opasta |
| Decodo (ent. Smartproxy) | $3.20–$3.50 | Paras GB/$-suhde volyymissa |
| Bright Data | $4.00 (PAYG) | 150M+ IP-pooli; oma Yelp Proxies -sivu |
| Oxylabs | $6.00–$8.00 | Premium; 10M+ IP:tä |
| Aluvia (mobiili-SIM) | $3.00 | Aidot US-carrier-mobiili-IP:t, asemoi itsensä Yelp-kaavintaan |
Kierrättävät residential-proxyt (uusi IP jokaiselle pyynnölle) toimivat parhaiten suuren volyymin hakukroolauksessa. Sticky-sessionit (pidä sama IP 10 minuuttia) sopivat paremmin, kun evästeitä halutaan säilyttää yrityssivu → arvostelut → sivutus -polussa.
Kerros 5: estojen tunnistus ja käsittely
Kaikki estot eivät näytä samoilta. Yelp näyttää usein geneerisen “page not available” -kuoren CAPTCHAn sijaan, minkä vuoksi sinisilmäiset kaavimet luulevat saavansa dataa, vaikka oikeasti vastauksena on tyhjää.
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
# Jos kyseessä on haku- tai yrityssivu, mutta react-root-props puuttuu,
# Yelp on tarjonnut riisuttua estovastausta
if "react-root-props" not in body and "/biz/" in str(resp.url):
return True
return False
| Signaali | Merkitys |
|---|---|
| HTTP 403 | Kova esto — IP/otsikot/TLS poltettu |
| HTTP 429 | Nopeusrajoitus — usein palautettavissa backoffilla |
| HTTP 503 | Geneerinen esto tai kuormanhallinta |
Uudelleenohjaus /error-polkuun tai “page not available” -sisältö | Pehmeä esto |
| Tyhjä , jossa vain | Haastesivu odottaa JS:ää |
captcha / g-recaptcha / px-captcha sisällössä | Tilanne eskaloitui — CAPTCHA vaaditaan |
react-root-props puuttuu listaussivulta | Riisuttu estovastaus |
Kerros 6: kestävä parsintakikka — piilotettu JSON CSS-valitsimien sijaan
Toistetaan vielä: Yelp satunnaistaa CSS-luokkanimet build-vaiheessa. Kaavin, joka on sidottu h3.y-css-14xwok2:een, hajoaa viikkojen sisällä, kun Yelp julkaisee uudelleen h3.y-css-hcq7b9:n.
Payloadit, jotka eivät vaihdu:
<script type="application/ld+json">— schema.org-jäsennelty data (nimi, osoite, puhelin, arvosana, aukioloajat)<script data-id="react-root-props">— koko hakutulosten JSON-datahttps://www.yelp.com/gql/batch— GraphQL-arvostelupäätepiste vakaalladocumentId:llä
Jos parsit CSS-luokkia, rakennat hiekalle. Parsii sen sijaan JSON.
Kerros 7: huomaamaton selainvararatkaisu
Siirry headless-selaimeen vain silloin, kun curl_cffi + residential-proxyt eivät pääse läpi — yleensä silloin, kun Yelp näyttää JavaScript-haastesivun tai CAPTCHAn.
95 prosentissa yritys-, haku- ja arvostelukaavinnasta curl_cffi + piilotettu JSON + residential-proxyt on nopeampi, halvempi ja luotettavampi kuin selain. Mutta jos selainta tarvitaan:
| Työkalu | Tila (2025) | Huomioita |
|---|---|---|
| rebrowser-playwright | Suositeltu aloituspiste | Drop-in Playwright, jossa CDP-vuotot on paikattu |
| nodriver | Luokkansa paras Chrome-huomaamattomuudessa | undetected-chromedriverin seuraaja; välttää WebDriver-protokollan kokonaan |
| patchright | Aktiivisesti ylläpidetty Playwright-haara | Läpäisee modernit tunnistustestit |
| playwright-stealth | Kypsä | Paikkaa navigator.webdriver-arvon ja poistaa HeadlessChrome:n UA:sta |
Ohita tavallinen Selenium Yelpissä. Se on liian helposti sormenjälkitunnistettava.
Yelp Fusion API vs. Python-kaavinta vs. Thunderbit: täydellinen vertailu
| Ominaisuus | Yelp Fusion API | Python-kaavinta | Thunderbit |
|---|---|---|---|
| Koko arvosteluteksti | ❌ 3 katkelmaa × ~160 merkkiä | ✅ Rajoittamaton (GraphQL) | ✅ Sisäänrakennettu arvostelupohja |
| Arvostelujen metatiedot (äänet, omistajan vastaukset) | ❌ | ✅ | ✅ AI:n ehdottamien kenttien kautta |
| Kuvat | ❌ (0 Base-tasolla) | ✅ Rajoittamaton | ✅ |
| Maksimi tulokset haussa | 240 (ennen 2024:ää 1 000) | Rajoittamaton (sivutettuna) | Rajoittamaton |
| Päivittäinen rajoitus | 300–500 (uudet) / 5 000 (vanhat) | Vain proxy-budjetti | Kreditipohjainen (3 000/kk Prossa) |
| Käyttöönotto | ~15 min | Tunteja tai päiviä | ~2 min |
| Anti-bot-käsittely | Ei sovellu | Ongelmasi | Hoidettu (Cloud-tila) |
| Juridinen riski | Matala (valtuutettu) | Keskitaso (ToS-harmaa alue) | Keskitaso (sama kuin kaavinnassa) |
| Hinta (aloitus) | $29/kk | ~$0.75–$4/GB proxyt + kehitysaika | Ilmainen taso |
| Hinta (raskaassa käytössä) | $643+/kk | $50–$500/kk proxyt + kehitysaika | $38–$49/kk |
| Datan vienti | JSON | CSV/JSON (sinun täytyy kirjoittaa se) | Excel / Sheets / Airtable / Notion — ilmainen |
| Ylläpito | Matala | Korkea (valitsimet vanhenevat, suojaus kiristyy) | Matala (AI mukautuu uudelleen) |
Lailliset ja eettiset vinkit Yelp-kaavintaan
En ole juristi, eikä tämä ole oikeudellista neuvontaa. Mutta oikeudellinen maisema on muuttunut sen verran kahden viime vuoden aikana, että perusteet kannattaa ymmärtää ennen kuin sijoitat aikaa Yelp-kaavintaprojektiin.
Mitä Yelpin käyttöehdot sanovat: Lokakuun 2025 käyttöehtopäivitys kieltää nimenomaisesti käyttämästä “mitään robottia, hämähäkkiä... tai muuta automatisoitua välinettä” palvelun minkä tahansa osan “käyttämiseen, hakemiseen, kopiointiin, kaapimiseen tai indeksointiin”. Mukaan tuli myös maininta “AI-teknologioista ja/tai muista automatisoiduista työkaluista”.
Yelp Support toistaa: “Yelp ei salli sivuston kaavintaa.”
Mitä robots.txt sanoo: Yelpin robots.txt sisältää wildcardin User-agent: * / Disallow: / ja estää erikseen GPTBotin, ClaudeBotin, PerplexityBotin, CCBotin ja Meta-ExternalAgentin. Vain Googlebot, Bingbot ja muutamat some-crawlerit on valkolistattu.
Merkittävä oikeustapaus: Meta v. Bright Data -tapauksessa (N.D. Cal. tammi 2024) oikeus katsoi, että julkisesti saatavilla olevan, uloskirjautuneen datan kaavinta ei rikkonut Metan käyttöehtoja. Keskeinen ero: uloskirjautunut julkinen data vs. kirjautunut data. hiQ v. LinkedIn -tapaus osoitti, että julkisen datan kaavinta ei todennäköisesti riko CFAA-lakia, mutta hiQ hävisi silti osavaltiotason vahingonkorvausväitteissä (trespass to chattels, misappropriation) ja sai 500 000 dollarin tuomion.
Käytännön ohjeet:
- Kaavi vain julkisesti saatavilla olevia, uloskirjautuneita sivuja
- Rajoita pyyntömääriäsi (tämän oppaan viiveet toimivat samalla eettisinä rate limitteinä)
- Älä jälleenmyy raakaa arvostelutekstiä nimettyihin käyttäjiin liitettynä — kunnioita arvostelijoiden yksityisyyttä
- Noudata paikallisia tietosuojalakeja (CCPA, GDPR)
- Älä kirjaudu sisään kaaviaksesi — se ylittää valtuutusrajan
- Käsittele yritystiedot (nimi/osoite/puhelin/arvosana) julkisena faktatietona; käsittele arvostelutekstiä arkaluonteisempana
Kysy tarvittaessa neuvoa lakiasiantuntijalta omaan tilanteeseesi.
Loppusanat
Kolme polkua, yksi tavoite.
Yelp Fusion API on valtuutettu ja vähän ylläpitoa vaativa vaihtoehto — mutta se rajoittuu kolmeen arvostelukatkelmaan ja alkaa $29/kk-hinnasta. Python-kaavinta antaa täyden hallinnan kaikkiin Yelp-datan kohtiin, mutta se vaatii oikeaa panostusta: curl_cffi TLS-imitointiin, residential-proxyt, satunnaiset viiveet, piilotetun JSONin parsinnan ja jatkuvan ylläpidon, kun Yelpin puolustukset kehittyvät. Thunderbit vie sinut “tarvitsen Yelp-dataa” -tilasta “tässä on taulukko” -tilaan noin 30 sekunnissa ilman koodia tai proxy-asetuksia.
Käytännössä vuonna 2025 toimivat estojen kierron peruspalikat: uskottavat otsikot täydellä Client Hints -sarjalla, curl_cffi TLS-fingerprintin jäljittelyyn, satunnaiset viiveet eksponentiaalisella backoffilla, residential-proxyjen kierto ja ennen kaikkea piilotetun JSONin (application/ld+json ja react-root-props) parsinta hauraiden CSS-valitsimien sijaan.
Etkö ole varma, mikä polku sopii? Kokeile ensin Thunderbitin ilmaista tasoa. Jos se riittää, säästät itseltäsi tunteja. Jos tarvitset enemmän hallintaa — täyden ohjelmallisen putken, omat kentät, tiukan CRM-integraation — yllä oleva Python-opas kattaa sen. Ja jos haluat syvemmän katsauksen kaavintatyökalujen kenttään, tutustu koontiimme parhaista Chrome-laajennuksista web-kaavintaan tai oppaaseemme datan kaapimisesta verkkosivuilta Exceliin.
Kokeile Thunderbitiä Yelp-datan poimintaan Get Started Free
Usein kysytyt kysymykset
Voinko kaapia Yelp-dataa Pythonilla ilmaiseksi?
Kyllä — käyttämällä ilmaisia kirjastoja kuten curl_cffi, parsel ja jmespath. Mutta oikeassa volyymissa (yli muutama kymmenen sivua) tarvitset maksulliset residential-proxyt, joiden hinnat alkavat noin $1.75/GB IPRoyalilla. Thunderbit tarjoaa myös ilmaisen tason, jossa saa 6 sivua kuukaudessa nopeaan koodittomaan poimintaan.
Estääkö Yelp kaavimet?
Kyllä, aggressiivisesti. Yelp käyttää TLS/JA3-fingerprintingia, IP-maineen pisteytystä, CAPTCHA:ita, käyttäytymisanalyysiä ja kiertäviä obfuskoituja CSS-luokkia. Tavallinen requests jää kiinni ensimmäisellä osumalla. Tämän oppaan kerroksellinen estojen kiertostrategia — curl_cffi TLS-imitointiin, uskottavat otsikot, satunnaiset viiveet ja residential-proxyt — on se, mikä toimii vuonna 2025.
Onko Yelp Fusion API parempi kuin kaavinta?
Riippuu tarpeesta. API on valtuutettu ja matalan riskin vaihtoehto, mutta se palauttaa vain 3 noin 160 merkin mittaista arvostelukatkelmaa, rajoittaa hakutulokset 240:een ja alkaa $29/kk-hinnasta. Jos tarvitset koko arvostelutekstin, arvostelun metatiedot tai enemmän kuin muutaman sadan tietueen päivässä, kaavinta on ainoa vaihtoehto.
Miten kaavin Yelp-arvostelut Pythonilla?
Käytä curl_cffi:ä impersonate="chrome131" -asetuksella hakeaksesi yrityssivun, poimi koodattu yritystunniste <meta name="yelp-biz-id">-tagista ja tee sitten POST-pyyntö osoitteeseen https://www.yelp.com/gql/batch käyttäen GetBusinessReviewFeed-operaatiota sekä sivuta base64-koodatun after-cursorin avulla. Vaiheittainen koodi on ylempänä oppaan opetusosiossa. Myös Scrapfly Yelp scraper repo on hyvä viiteimplementaatio.
Voinko kaapia Yelp-dataa ilman koodausta?
Kyllä — Thunderbitin AI Web Scraper sisältää valmiit Yelp-yritys ja arvostelu -pohjat. Avaa Yelp-sivu, klikkaa AI Suggest Fields ja sitten Scrape. Vienti Google Sheetiin, Exceliin, Airtableen ja Notioniin on ilmainen kaikilla tasoilla, myös ilmaisella suunnitelmalla.
Lue lisää


