Το Yelp διαθέτει 330 εκατομμύρια συνολικές κριτικές σε 8,4 εκατομμύρια ενεργές σελίδες επιχειρήσεων — και το να μετατρέψεις αυτά τα δεδομένα σε κάτι πραγματικά αξιοποιήσιμο δεν ήταν ποτέ πιο δύσκολο. Η αντεπίθεση του Yelp στα bots για το 2024–2025 έχει ουσιαστικά διαλύσει σιωπηλά τα περισσότερα υπάρχοντα Python tutorials για scraping.
Αν πρόσφατα δοκίμασες να τρέξεις ένα Yelp scraper και έπεσες πάνω σε 403 errors, κενές HTML responses ή CAPTCHAs που δεν υπήρχαν πριν από έξι μήνες, δεν το φαντάζεσαι. Το Yelp πλέον χρησιμοποιεί TLS/JA3 fingerprinting, εναλλασσόμενα obfuscated CSS class names και επιθετικό IP reputation scoring — πράγμα που σημαίνει ότι η παλιά προσέγγιση requests + BeautifulSoup, που συνεχίζει να προτείνει κάθε tutorial, αποτυγχάνει από το πρώτο κιόλας request. Έχω περάσει εβδομάδες δοκιμάζοντας διαφορετικές προσεγγίσεις στο σημερινό stack του Yelp, και αυτός ο οδηγός καλύπτει ό,τι δουλεύει πραγματικά το 2025: το επίσημο Fusion API (και γιατί μάλλον δεν θα σου φτάσει), ένα πλήρες Python workflow scraping με πολυεπίπεδη στρατηγική αποφυγής μπλοκαρίσματος, και μια no-code εναλλακτική με 2 κλικ μέσω του Thunderbit για όσους θέλουν απλώς τα δεδομένα χωρίς μαραθώνιο debugging.
Δοκίμασε το Thunderbit για Scraping Yelp
Γιατί να κάνεις Scrape το Yelp με Python (και ποιοι πραγματικά ωφελούνται)
Πριν γράψεις ούτε μία γραμμή κώδικα, ποιο είναι το πραγματικό business case για τα δεδομένα του Yelp; Η πλατφόρμα δεν είναι απλώς ένας ιστότοπος με κριτικές εστιατορίων — είναι στην πράξη μια ζωντανή βάση δεδομένων τοπικών επιχειρήσεων με δομημένα στοιχεία επικοινωνίας, αξιολογήσεις, κατηγορίες, ώρες λειτουργίας και εκατοντάδες εκατομμύρια κριτικές πελατών.

Να ποιοι ωφελούνται περισσότερο και τι εξάγουν:
| Χρήση | Κύρια πεδία δεδομένων | Γιατί έχει σημασία |
|---|---|---|
| Πωλήσεις & lead generation | Όνομα επιχείρησης, τηλέφωνο, website, διεύθυνση, κατηγορία, αξιολόγηση | Φτιάχνεις στοχευμένες λίστες υποψήφιων πελατών από τοπικές μικρομεσαίες επιχειρήσεις — 4 στους 5 χρήστες του Yelp είναι έτοιμοι για αγορά μόλις μπουν στην πλατφόρμα |
| Ανταγωνιστική ανάλυση | Κριτικές, αστέρια, όγκος κριτικών, συναίσθημα | Παρακολουθείς τη φήμη των ανταγωνιστών, εντοπίζεις κενά στην εξυπηρέτηση, βλέπεις τάσεις |
| Έρευνα αγοράς & NLP | Πλήρες κείμενο κριτικών, ημερομηνίες, μεταδεδομένα συντακτών | Ανάλυση συναισθήματος, topic modeling — οι κριτικές του Yelp είναι ένα από τα πιο χρησιμοποιούμενα NLP corpora στην ακαδημαϊκή έρευνα |
| Real estate & επιλογή τοποθεσίας | Πυκνότητα επιχειρήσεων, μείγμα κατηγοριών, ποιότητα κριτικών ανά περιοχή | Επιλογή σημείων για franchise και λιανεμπόριο — το Yelp πουλάει Location Intelligence ως αδειοδοτημένο B2B προϊόν ακριβώς γι’ αυτό |
| Ecommerce & operations | Ενδείξεις τιμολόγησης, παράπονα πελατών, ώρες εξυπηρέτησης | Παρακολουθείς πώς αξιολογούνται οι ανταγωνιστές και εντοπίζεις λειτουργικά μοτίβα |
Το κοινό νήμα είναι απλό: ο πραγματικός στόχος είναι τα δομημένα δεδομένα, και η Python είναι απλώς το μέσο για να τα πάρεις. Κάποιοι θέλουν πλήρη προγραμματιστικό έλεγχο. Άλλοι θέλουν απλώς ένα spreadsheet με στοιχεία επικοινωνίας υδραυλικών στο Austin. Και οι δύο διαδρομές καλύπτονται εδώ.
Yelp Fusion API vs. Python Web Scraping: Τι να διαλέξεις;
Οι περισσότεροι οδηγοί προσπερνούν τελείως αυτή την απόφαση και πάνε κατευθείαν στον κώδικα, χωρίς να αξιολογήσουν αν το επίσημο Yelp Fusion API (που πλέον έχει μετονομαστεί σε "Yelp Places API") θα αρκούσε. Από την εμπειρία μου, αυτή η αξιολόγηση μπορεί να σου γλιτώσει ώρες χαμένου κόπου — γιατί το API είναι εξαιρετικό για ορισμένα πράγματα και εντελώς ανεπαρκές για άλλα.
Τι σου δίνει πραγματικά το Fusion API
Το Fusion API προσφέρει δομημένη αναζήτηση επιχειρήσεων, λεπτομέρειες επιχείρησης, autocomplete και ένα reviews endpoint. Είναι εξουσιοδοτημένο, καλά τεκμηριωμένο και δεν χρειάζεται κόλπα anti-bot.
Αλλά το πρόβλημα ξεκινά στο endpoint των reviews. Να τι έχουν επιβεβαιώσει στελέχη του Yelp στο GitHub:
"Το Yelp API δεν επιστρέφει πλήρες κείμενο κριτικών. Παρέχονται από προεπιλογή τρία αποσπάσματα κριτικών των 160 χαρακτήρων." — Απάντηση στελέχους του Yelp, GitHub Issue #163
Αυτό δεν είναι bug — έτσι είναι σχεδιασμένο. Το API περιορίζεται φυσικά σε 3 αποσπάσματα κριτικών (7 στο Premium), και το καθένα κόβεται περίπου στους 160 χαρακτήρες. Δεν υπάρχουν μεταδεδομένα κριτικών (useful/funny/cool ψήφοι), ούτε ιστορικό συντάκτη, ούτε απαντήσεις ιδιοκτήτη. Και το ημερήσιο rate limit για νέους πελάτες έπεσε σε 300–500 calls/ημέρα μετά τον Μάιο του 2023 — από 5.000. Η βασική τιμολόγηση ξεκινά από $29/μήνα.
Το πλαίσιο απόφασης
| Παράγοντας | Yelp Fusion API | Python Web Scraping | Thunderbit (No-Code) |
|---|---|---|---|
| Πλήρεις κριτικές | ❌ Μόνο 3 αποσπάσματα (~160 χαρακτήρες το καθένα) | ✅ Όλες οι κριτικές μέσω GraphQL | ✅ Όλες οι ορατές κριτικές |
| Rate limits | 300–500/ημέρα (νέοι)· 5.000 (παλιοί λογαριασμοί) | Το διαχειρίζεσαι μόνος σου (budget σε proxies) | Με βάση credits |
| Χρόνος ρύθμισης | ~15 λεπτά (API key + SDK) | Από ώρες έως μέρες | ~2 λεπτά |
| Πεδία επιχειρήσεων | ~20 δομημένα πεδία | Απεριόριστα (parse HTML/JSON) | Πεδία που προτείνει το AI |
| Anti-bot χειρισμός | N/A (εξουσιοδοτημένο) | Πρέπει να τον φτιάξεις εσύ | Χειρίζεται αυτόματα |
| Νομικός κίνδυνος | ✅ Εξουσιοδοτημένο | ⚠️ Γκρίζα ζώνη στους όρους χρήσης | ⚠️ Ίδιο με το scraping |
| Κόστος | Ελάχιστο $29/μήνα | Δωρεάν (+ κόστος proxy $0.75–$4/GB) | Διαθέσιμο δωρεάν πλάνο |
| Συντήρηση | Χαμηλή (σταθερό API) | Υψηλή (selectors χαλάνε, το anti-bot σκληραίνει) | Χαμηλή (το AI προσαρμόζεται ξανά) |
Χρησιμοποίησε το Fusion API αν: χρειάζεσαι βασικές πληροφορίες επιχείρησης, μικρής κλίμακας αναζητήσεις ή μια εξουσιοδοτημένη ενσωμάτωση — και αρκούν 3 αποσπάσματα κριτικών ανά επιχείρηση.
Χρησιμοποίησε Python scraping αν: χρειάζεσαι πλήρες κείμενο κριτικών, όλες τις κριτικές μιας επιχείρησης, μεταδεδομένα κριτικών, πάνω από 240 αποτελέσματα ανά αναζήτηση ή το budget σου είναι κάτω από $29/μήνα.
Χρησιμοποίησε το Thunderbit αν: θέλεις τα δεδομένα γρήγορα, χωρίς να γράψεις ή να συντηρείς κώδικα. Περισσότερα γι’ αυτό στην ενότητα για το no-code παρακάτω.
Η no-code συντόμευση: Scrape το Yelp με το Thunderbit (χωρίς Python)
Πριν μπούμε βαθιά στην Python, να η πιο γρήγορη διαδρομή για όσους θέλουν το αποτέλεσμα — τα δεδομένα — όχι την άσκηση προγραμματισμού. Όλοι οι ανταγωνιστικοί οδηγοί υποθέτουν ότι ξέρεις Python, αλλά στη δουλειά μου στο Thunderbit έχω δει ότι ένα τεράστιο ποσοστό όσων ψάχνουν "scrape Yelp" είναι πωλητές, operations managers και ιδιοκτήτες μικρών επιχειρήσεων που θέλουν απλώς ένα spreadsheet με τοπικές επιχειρήσεις — όχι μάθημα πάνω σε TLS fingerprinting.
Το Thunderbit διαθέτει ήδη έτοιμα templates για το Yelp:
- Yelp Business Web Scraper — εξάγει όνομα επιχείρησης, αξιολόγηση, στοιχεία επικοινωνίας, διεύθυνση, ώρες λειτουργίας, κατηγορία
- Yelp Review Scraper — εξάγει username συντάκτη, περιεχόμενο κριτικής, αξιολόγηση, ημερομηνία, τοποθεσία συντάκτη
Πώς δουλεύει στην πράξη
- Άνοιξε σελίδα αποτελεσμάτων αναζήτησης ή σελίδα επιχείρησης στο Yelp μέσα στο Chrome
- Πάτησε AI Suggest Fields στο Thunderbit extension — το AI διαβάζει τη σελίδα και προτείνει στήλες (όνομα επιχείρησης, αξιολόγηση, αριθμός κριτικών, εύρος τιμών, κατηγορία, διεύθυνση, τηλέφωνο, URL)
- Πάτησε Scrape — και τέλος
Με τα έτοιμα templates του Yelp, είναι ακόμα πιο απλό: άνοιξε το template και πάτησε Scrape.
Το subpage scraping χειρίζεται αυτόματα τον κύκλο εμπλουτισμού — ξεκινάς από τη σελίδα αποτελεσμάτων του Yelp, ενεργοποιείς το subpage scraping και το Thunderbit επισκέπτεται κάθε σελίδα επιχείρησης για να τραβήξει ώρες λειτουργίας, πλήρεις κριτικές, website, φωτογραφίες και παροχές. Χωρίς επιπλέον ρύθμιση.
Η σελιδοποίηση είναι αυτόματη — είτε με click είτε με scrolling, όλα έτοιμα out of the box. (Για περισσότερα σχετικά με το πώς δουλεύει αυτό, δες τον οδηγό μας για pagination.)
Οι εξαγωγές είναι δωρεάν σε όλα τα πλάνα — Excel, Google Sheets, Airtable, Notion, CSV, JSON. Χωρίς pandas, χωρίς κώδικα για εγγραφή CSV.
Σύγκριση χρόνου
| Χρόνος | Python Scraper | Thunderbit |
|---|---|---|
| Πρώτη εκτέλεση | Από ώρες έως μέρες (selectors, pagination, proxies, retry logic) | ~30 δευτερόλεπτα με το έτοιμο Yelp template |
| Όταν αλλάξει το markup του Yelp | Επαναγράφεις χειροκίνητα τους selectors | Ξαναπατάς AI Suggest Fields — προσαρμόζεται μόνο του |
| Όταν μπλοκαριστεί το IP | Debug, αλλαγή proxy pools, ξαναδοκιμές | Το cloud mode αναλαμβάνει την εναλλαγή IP |
| Export στο Google Sheets | Γράφεις OAuth + pandas glue | Ένα κλικ, δωρεάν |
Αν δοκιμάσεις πρώτα το Thunderbit και δεις ότι καλύπτει τις ανάγκες σου, μπορείς να προσπεράσεις το υπόλοιπο άρθρο. Αν χρειάζεσαι πλήρη προγραμματιστικό έλεγχο, custom πεδία ή κλίμακα πέρα από μερικές χιλιάδες εγγραφές τον μήνα — συνέχισε να διαβάζεις.
Python libraries για scraping στο Yelp: ποια να διαλέξεις
Το "να χρησιμοποιήσω Scrapy, BS4+requests ή Selenium;" είναι μία από τις πιο συχνές ερωτήσεις σε threads του r/webscraping για το Yelp. Κι όμως, κάθε tutorial απλώς διαλέγει τη δική του αγαπημένη βιβλιοθήκη και προχωρά, χωρίς να εξηγεί το γιατί. Ορίστε η ειλικρινής ανάλυση.
Η πραγματικότητα του 2025: το requests + BeautifulSoup είναι σπασμένο για το Yelp
Το stack που προτείνει κάθε κλασικό Yelp tutorial — pip install requests beautifulsoup4 — σε μπλοκάρει από το πρώτο request το 2025. Όχι στο 50ό. Στο πρώτο.
Ο λόγος: η Python βιβλιοθήκη requests στέλνει TLS/JA3 fingerprint που δεν ταιριάζει με κανέναν πραγματικό browser. Το anti-bot layer του Yelp το σημαδεύει στο επίπεδο του TLS handshake, πριν καν διαβαστεί το User-Agent header. Το δοκίμασα επανειλημμένα — φρέσκο IP, ρεαλιστικά headers, τυχαίες καθυστερήσεις — και πάλι έπαιρνα αμέσως 403 Forbidden με το γυμνό requests.
Ο πίνακας απόφασης για libraries
| Library | Καλύτερη χρήση | Υποστηρίζει JS; | Anti-Bot; | Καμπύλη εκμάθησης | Ταχύτητα |
|---|---|---|---|---|---|
requests + BeautifulSoup | ❌ | ❌ | Πολύ χαμηλή | Γρήγορο (μέχρι να μπλοκάρει) | |
httpx async + parsel | Async scraping μεγάλης κλίμακας | ❌ | ❌ | Χαμηλή | Πολύ γρήγορο |
curl_cffi + parsel | Ειδικά για Yelp: TLS impersonation | ❌ | ✅ TLS/JA3/HTTP2 | Χαμηλή | Πολύ γρήγορο |
Scrapy 2.14 | Πλήρεις crawl pipelines με pagination | Μερική (μέσω scrapy-playwright) | AutoThrottle, retry middleware | Μέτρια-Υψηλή | Γρήγορο |
Selenium 4.43 / Playwright 1.58 | Σελίδες με έντονο JS, workarounds για CAPTCHA | ✅ | Μερική | Μέτρια | Αργό (~10–30 σελίδες/λεπτό) |
| Thunderbit | Μη προγραμματιστές, γρήγορη εξαγωγή | ✅ (browser) | Ενσωματωμένο (Cloud mode) | Πολύ χαμηλή | Γρήγορο |
Η αποκάλυψη του curl_cffi
Η βιβλιοθήκη που άλλαξε τη ροή μου στο Yelp scraping είναι το curl_cffi — ένα Python binding για το curl-impersonate. Παράγει ακριβώς το ίδιο TLS/JA3 + HTTP/2 fingerprint με το πραγματικό Chrome, και το API του αντικαθιστά το requests χωρίς αλλαγές στη λογική:
from curl_cffi import requests
r = requests.get(
"https://www.yelp.com/biz/some-restaurant",
impersonate="chrome131",
)
print(r.status_code, len(r.text))
Αυτή η μία αλλαγή — from curl_cffi import requests μαζί με impersonate="chrome131" — παρακάμπτει το μεγαλύτερο anti-bot layer του Yelp χωρίς να ανοίξεις browser. Στα δικά μου tests, είναι η διαφορά ανάμεσα σε άμεσο 403 και καθαρά 200 responses.
Το stack που προτείνω για Yelp το 2025: curl_cffi + parsel + jmespath + residential proxies. Αν χρειάζεσαι πλήρες crawl pipeline με scheduling, τύλιξέ το σε Scrapy 2.14 με downloader middleware βασισμένο στο curl_cffi.
Ρύθμιση του Python περιβάλλοντος για scraping στο Yelp
- Δυσκολία: Ενδιάμεση
- Χρόνος που χρειάζεται: ~15 λεπτά για setup, 1–2 ώρες για λειτουργικό scraper
- Τι θα χρειαστείς: Python 3.10+ (προτείνεται 3.12), ένα terminal και προαιρετικά έναν πάροχο residential proxy
Βήμα 1: Δημιούργησε virtual environment και εγκατέστησε πακέτα
python3.12 -m venv .venv
source .venv/bin/activate # Σε Windows: .venv\Scripts\activate
pip install "curl_cffi>=0.11" "parsel>=1.9" "jmespath>=1.0" pandas
Τι κάνει το κάθε πακέτο:
curl_cffi— κάνει HTTP requests με το TLS fingerprint του Chrome (το bypass του anti-bot)parsel— CSS/XPath selectors για parsing HTML (ίδια μηχανή με το Scrapy, πιο ελαφριά)jmespath— δηλωτικό querying JSON (πιο καθαρό από το να ανοίγεις βαθιά nested dicts στα embedded JSON του Yelp)pandas— εξαγωγή δεδομένων σε CSV/Excel
Προαιρετικό αλλά χρήσιμο:
pip install fake-useragent # Σημείωση: το repo αρχειοθετήθηκε τον Απρίλιο του 2026 αλλά εγκαθίσταται ακόμα
Βήμα προς βήμα: Πώς να κάνεις Scrape το Yelp με Python
Αυτό είναι το βασικό tutorial. Το κλειδί που κάνει όλη τη διαδικασία πιο ανθεκτική: παράκαμψε τα CSS selectors και πάρε τα κρυμμένα JSON αντί γι’ αυτά. Το Yelp αλλάζει τυχαία τα CSS class names στο build time (y-css-14xwok2 μια εβδομάδα, y-css-hcq7b9 την επόμενη), οπότε όποιος scraper βασίζεται σε αυτά χαλάει μέσα σε λίγες εβδομάδες. Τα embedded JSON payloads — application/ld+json schema και react-root-props — είναι σταθερά.
Βήμα 2: Scrape τα αποτελέσματα αναζήτησης του Yelp
Τα URLs αναζήτησης του Yelp ακολουθούν προβλέψιμο μοτίβο: https://www.yelp.com/search?find_desc={term}&find_loc={location}. Τα δεδομένα των αποτελεσμάτων είναι ενσωματωμένα σε ένα <script data-id="react-root-props"> ως JSON — όχι μέσα στο χάος των CSS classes.
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"Μπλοκαρίστηκε στη σελίδα {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 στη σελίδα {page} — πιθανό 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
Θα πρέπει να πάρεις πίσω μια λίστα από dicts με ονόματα επιχειρήσεων, URLs, αξιολογήσεις και αριθμό κριτικών. Αν το react-root-props λείπει από την απάντηση, σημαίνει ότι σου έχει δοθεί block shell — άλλαξε IP και ξαναδοκίμασε.
Το header Cookie: intl_splash=false είναι ένα συνηθισμένο workaround για το country-splash redirect του Yelp. Χωρίς αυτό, IP εκτός ΗΠΑ πέφτουν σε splash page που μοιάζει με soft block αλλά δεν είναι.
Βήμα 3: Scrape τις σελίδες επιχειρήσεων του Yelp
Κάθε URL επιχείρησης από τα αποτελέσματα αναζήτησης οδηγεί σε σελίδα λεπτομερειών με πλουσιότερα δεδομένα. Το πιο σταθερό σημείο εξαγωγής είναι το block <script type="application/ld+json"> — περιέχει δομημένα schema.org δεδομένα που το Yelp συντηρεί για SEO και δεν τα θολώνει.
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"] είναι το encoded business ID που θα χρειαστείς για το reviews endpoint. Πάρε το από εδώ — θα το χρησιμοποιήσεις στο επόμενο βήμα.
Βήμα 4: Scrape τις κριτικές του Yelp με pagination
Εδώ είναι που το Fusion API υπολείπεται και το scraping υπερέχει. Το εσωτερικό GraphQL batch endpoint του Yelp επιστρέφει πλήρες κείμενο κριτικών, στοιχεία συντάκτη, ημερομηνίες, αξιολογήσεις και vote counts — ό,τι ακριβώς αποκρύπτει το API.
Το endpoint είναι το https://www.yelp.com/gql/batch, και χρησιμοποιεί ένα στατικό documentId για το operation GetBusinessReviewFeed. Η σελιδοποίηση γίνεται μέσω ενός cursor με base64 encoding.
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"Η λήψη κριτικών απέτυχε στο offset {offset}: {r.status_code}")
break
data = r.json()
# Πλοήγηση στη δομή της απάντησης για εξαγωγή κριτικών
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
Κάθε σελίδα επιστρέφει 10 κριτικές. Αύξησε το offset στον base64 cursor για pagination. Η παράμετρος sortBy δέχεται DATE_DESC (νεότερες πρώτα), RATING_ASC, RATING_DESC και άλλες.
Βήμα 5: Εξαγωγή των δεδομένων Yelp που έκανες scrape
import pandas as pd
# Υποθέτοντας ότι έχεις συλλέξει businesses και 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)
# Ή αποθήκευση ως JSON για μεγαλύτερη ευελιξία
import json
with open("yelp_data.json", "w") as f:
json.dump({"businesses": businesses, "reviews": all_reviews}, f, indent=2)
Για όσους ακολουθούν τη no-code διαδρομή, το Thunderbit εξάγει τα ίδια δεδομένα απευθείας σε Excel, Google Sheets, Airtable ή Notion — χωρίς pandas ή κώδικα για εγγραφή αρχείων.
Το playbook κατά του μπλοκαρίσματος: πώς να κάνεις Scrape το Yelp χωρίς να σε μπλοκάρουν
Αυτή η ενότητα είναι ουσιαστικά ο λόγος που υπάρχει το άρθρο. Τα anti-bot μέτρα του Yelp έχουν γίνει αισθητά πιο αυστηρά από τα τέλη του 2024 — TLS fingerprinting, έλεγχοι αξιοπιστίας IP, CAPTCHAs και behavioral analysis είναι όλα ενεργά. Οι περισσότεροι υπάρχοντες οδηγοί είναι ξεπερασμένοι, γιατί γράφτηκαν πριν από αυτή την καταστολή.

Η στρατηγική είναι πολυεπίπεδη. Κάθε επίπεδο μειώνει το block rate σου· μαζί, κάνουν το sustained scraping εφικτό.
Επίπεδο 1: Ρεαλιστικά request headers
Τα default headers του Python requests στέλνουν User-Agent: python-requests/2.x — μπλοκάρεται αμέσως. Αλλά ακόμη και ένα ρεαλιστικό User-Agent δεν αρκεί. Το Yelp ελέγχει όλο το σύνολο headers των Client Hints για συνέπεια.
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",
}
Τρία λάθη που σε βάζουν στο στόχαστρο:
- Το UA λέει Chrome αλλά το
sec-ch-uaλείπει ή έρχεται σε αντίθεση με την έκδοση του UA - Το
sec-ch-ua-platformλέει "Windows" αλλά το UA string λέει macOS - Το ίδιο ακριβώς UA σε χιλιάδες requests από ένα IP — κάνε rotate ένα pool από 10–20 πρόσφατα Chrome/Firefox/Safari strings
Επίπεδο 2: Rate limiting και τυχαίες καθυστερήσεις
Τα προβλέψιμα χρονικά μοτίβα είναι κόκκινη σημαία. Πρόσθεσε τυχαία διαστήματα αναμονής και υλοποίησε exponential backoff στα error responses.
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"Μπλοκαρίστηκε μετά από {attempt + 1} προσπάθειες στο {url}")
backoff = 2 ** (attempt + 1) + random.random()
print(f" Έλαβε {r.status_code}, κάνει backoff {backoff:.1f}s (προσπάθεια {attempt + 1})")
time.sleep(backoff)
return polite_get(client_get, url, attempt + 1)
time.sleep(random.uniform(3, 7))
return r
| Παράμετρος | Προτεινόμενη τιμή |
|---|---|
| Τυχαίο sleep ανάμεσα στα requests | random.uniform(3, 7) δευτερόλεπτα |
| Backoff σε 429/403/503 | 2 → 4 → 8 → 16s, έως 5 προσπάθειες |
| Concurrent workers ανά IP | 1 (serialize ανά IP· χρησιμοποίησε proxies για parallelism) |
| Μέγιστος sustained ρυθμός ανά residential IP | ~1 request / 5s (~12 rpm) |
Επίπεδο 3: Εναλλαγή User-Agent και session
Κάνε rotate μια δεξαμενή από πραγματικά browser User-Agent strings. Διατήρησε sessions και cookies για να μιμείσαι πραγματική συμπεριφορά πλοήγησης — το Yelp χρησιμοποιεί cookie-based detection, οπότε το να δημιουργείς νέο session σε κάθε request είναι από μόνο του ύποπτο.
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",
# Πρόσθεσε 5-10 ακόμη πρόσφατα strings
]
Επίπεδο 4: Proxy rotation
Σε πραγματική κλίμακα, χρειάζεσαι residential proxies. Datacenter και δωρεάν proxies δεν δουλεύουν στο Yelp — το IP-reputation layer του Yelp ρίχνει προληπτικά 403 σε IP ranges από AWS, GCP και DigitalOcean.
| Πάροχος | Είσοδος $/GB | Σημειώσεις |
|---|---|---|
| IPRoyal | $1.75/GB | Ο πιο οικονομικός· φιλοξενεί το πιο συχνά αναφερόμενο Yelp tutorial |
| Decodo (πρώην Smartproxy) | $3.20–$3.50 | Καλύτερη σχέση GB/$ σε όγκο |
| Bright Data | $4.00 (PAYG) | Pool 150M+ IPs· ειδική σελίδα Yelp Proxies |
| Oxylabs | $6.00–$8.00 | Premium· 10M+ IPs |
| Aluvia (mobile SIM) | $3.00 | Πραγματικά mobile IPs αμερικανικών carriers, τοποθετημένα για Yelp |
Τα rotating residential (νέο IP ανά request) δουλεύουν καλύτερα για μαζικά search crawls. Τα sticky sessions (κρατάς ένα IP για 10 λεπτά) είναι καλύτερα όταν διατηρείς cookies σε ροή σελίδα επιχείρησης → κριτικές → pagination.
Επίπεδο 5: Εντοπισμός και διαχείριση blocks
Δεν μοιάζουν όλα τα blocks ίδια. Το Yelp συχνά σερβίρει ένα γενικό shell "page not available" αντί για CAPTCHA, γι’ αυτό οι αφελείς scrapers νομίζουν ότι παίρνουν δεδομένα ενώ στην πραγματικότητα παίρνουν άδειες απαντήσεις.
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
# Αν πρόκειται για search/business page αλλά λείπει το react-root-props,
# το Yelp έστειλε stripped block response
if "react-root-props" not in body and "/biz/" in str(resp.url):
return True
return False
| Σήμα | Σημασία |
|---|---|
| HTTP 403 | Σκληρό μπλοκάρισμα — IP/header/TLS έχει καεί |
| HTTP 429 | Rate limited — συχνά αναστρέψιμο με backoff |
| HTTP 503 | Γενικό block ή φόρτος |
Redirect σε /error ή σώμα με "page not available" | Soft block |
| Άδειο με μόνο | Σελίδα challenge που περιμένει JS |
captcha / g-recaptcha / px-captcha στο body | Κλιμάκωση — απαιτείται CAPTCHA |
Λείπει το react-root-props σε σελίδα καταχώρισης | Stripped block response |
Επίπεδο 6: Το trick του ανθεκτικού parsing — κρυμμένο JSON αντί για CSS selectors
Αξίζει να το επαναλάβω: το Yelp αλλάζει τυχαία τα CSS class names στο build time. Ένας scraper δεμένος στο h3.y-css-14xwok2 θα σπάσει μέσα σε λίγες εβδομάδες όταν το Yelp κάνει redeploy με h3.y-css-hcq7b9.
Τα payloads που δεν αλλάζουν:
<script type="application/ld+json">— schema.org δομημένα δεδομένα (όνομα, διεύθυνση, τηλέφωνο, αξιολόγηση, ώρες)<script data-id="react-root-props">— πλήρη δεδομένα αποτελεσμάτων αναζήτησης ως JSONhttps://www.yelp.com/gql/batch— GraphQL endpoint για κριτικές με σταθερόdocumentId
Αν κάνεις parsing CSS classes, χτίζεις πάνω στην άμμο. Κάνε parsing το JSON.
Επίπεδο 7: Το stealth browser fallback
Πέρασε σε headless browser μόνο όταν το curl_cffi + residential proxies δεν αρκούν — συνήθως όταν το Yelp σερβίρει JavaScript challenge page ή CAPTCHA.
Για το 95% του scraping σε επιχειρήσεις/αναζητήσεις/κριτικές, το curl_cffi + hidden JSON + residential proxies είναι πιο γρήγορο, πιο φθηνό και πιο αξιόπιστο από έναν browser. Αλλά όταν χρειάζεσαι browser:
| Εργαλείο | Κατάσταση (2025) | Σημειώσεις |
|---|---|---|---|
| rebrowser-playwright | Προτεινόμενο σημείο εκκίνησης | Drop-in Playwright patched για να διορθώνει CDP leaks |
| nodriver | Καλύτερο στην κατηγορία για Chrome stealth | Διάδοχος του undetected-chromedriver· αποφεύγει εντελώς το WebDriver protocol |
| patchright | Ενεργά συντηρούμενο Playwright fork | Περνάει σύγχρονα detection tests |
| playwright-stealth | Ώριμο | Κάνει patch το navigator.webdriver, αφαιρεί το HeadlessChrome από το UA |
Απόφυγε το vanilla Selenium για το Yelp. Εντοπίζεται πολύ εύκολα.
Yelp Fusion API vs. Python Scraping vs. Thunderbit: Πλήρης σύγκριση
| Διάσταση | Yelp Fusion API | Python Scraping | Thunderbit |
|---|---|---|---|
| Πλήρες κείμενο κριτικών | ❌ 3 αποσπάσματα × ~160 χαρακτήρες | ✅ Απεριόριστο (GraphQL) | ✅ Έτοιμο review template |
| Μεταδεδομένα κριτικών (ψήφοι, απαντήσεις ιδιοκτήτη) | ❌ | ✅ | ✅ Μέσω AI-suggested fields |
| Φωτογραφίες | ❌ (0 στο Base) | ✅ Απεριόριστες | ✅ |
| Μέγιστα αποτελέσματα ανά αναζήτηση | 240 (ήταν 1.000 πριν το 2024) | Απεριόριστα (με pagination) | Απεριόριστα |
| Ημερήσιο rate limit | 300–500 (νέοι) / 5.000 (παλιοί) | Μόνο το budget σε proxies | Με βάση credits (3.000/μήνα στο Pro) |
| Χρόνος ρύθμισης | ~15 λεπτά | Ώρες έως μέρες | ~2 λεπτά |
| Anti-bot χειρισμός | N/A | Δικό σου πρόβλημα | Χειρισμένο (Cloud mode) |
| Νομικός κίνδυνος | Χαμηλός (εξουσιοδοτημένο) | Μέτριος (γκρίζα ζώνη στους όρους) | Μέτριος (ίδιο με scraping) |
| Κόστος εκκίνησης | $29/μήνα | ~$0.75–$4/GB proxies + χρόνος ανάπτυξης | Δωρεάν πλάνο |
| Κόστος σε βαριά χρήση | $643+/μήνα | $50–$500/μήνα σε proxies + χρόνος ανάπτυξης | $38–$49/μήνα |
| Εξαγωγή δεδομένων | JSON | CSV/JSON (το γράφεις εσύ) | Excel / Sheets / Airtable / Notion — δωρεάν |
| Συντήρηση | Χαμηλή | Υψηλή (selectors χαλάνε, anti-bot κλιμακώνεται) | Χαμηλή (το AI προσαρμόζεται ξανά) |
Νομικές και ηθικές συμβουλές για scraping στο Yelp
Δεν είμαι δικηγόρος, και αυτό δεν αποτελεί νομική συμβουλή. Αλλά το νομικό τοπίο έχει αλλάξει αρκετά τα τελευταία δύο χρόνια ώστε να πρέπει να ξέρεις τα βασικά πριν επενδύσεις χρόνο σε project scraping του Yelp.
Τι λένε οι Όροι Χρήσης του Yelp: Η ενημέρωση των ToS του Οκτωβρίου 2025 απαγορεύει ρητά τη χρήση "οποιουδήποτε robot, spider... ή άλλης αυτοματοποιημένης συσκευής" για να "αποκτά, ανακτά, αντιγράφει, κάνει scrape ή index οποιοδήποτε τμήμα της Υπηρεσίας." Προστέθηκε επίσης γλώσσα για "AI Technologies and/or other automated tools."
Το Yelp Support επαναλαμβάνει: "Το Yelp δεν επιτρέπει κανενός είδους scraping του site."
Τι λέει το robots.txt: Το robots.txt του Yelp έχει wildcard User-agent: * / Disallow: / και μπλοκάρει συγκεκριμένα τα GPTBot, ClaudeBot, PerplexityBot, CCBot και Meta-ExternalAgent. Μόνο το Googlebot, το Bingbot και λίγα social-media crawlers είναι whitelisted.
Το νομικό προηγούμενο που έχει σημασία: Στην υπόθεση Meta v. Bright Data (N.D. Cal. Ιαν. 2024), το δικαστήριο έκρινε ότι το scraping δημοσίως διαθέσιμων, logged-out δεδομένων δεν παραβίαζε τους Όρους Χρήσης της Meta. Η κρίσιμη διάκριση είναι: δημόσια δεδομένα σε logged-out κατάσταση vs. logged-in δεδομένα. Η υπόθεση hiQ v. LinkedIn έδειξε ότι το scraping δημόσιων δεδομένων πιθανότατα δεν παραβιάζει το CFAA, αλλά η hiQ έχασε παρ’ όλα αυτά σε πολιτειακές αξιώσεις αδικοπραξίας (trespass to chattels, misappropriation) και της επιβλήθηκε απόφαση $500.000.
Πρακτικές οδηγίες:
- Κάνε scrape μόνο δημόσια διαθέσιμες σελίδες χωρίς login
- Περιόρισε τον ρυθμό των requests σου (οι καθυστερήσεις σε αυτόν τον οδηγό λειτουργούν διπλά ως ηθικό rate limiting)
- Μην μεταπωλείς ακατέργαστο κείμενο κριτικών με αναφορά σε ονομαστικούς χρήστες — σεβάσου την ιδιωτικότητα των συντακτών
- Συμμορφώσου με τους τοπικούς νόμους προστασίας δεδομένων (CCPA, GDPR)
- Μην κάνεις login για να κάνεις scrape — αυτό ξεπερνά το όριο της εξουσιοδότησης
- Αντιμετώπισε τα στοιχεία επιχείρησης (όνομα/διεύθυνση/τηλέφωνο/αξιολόγηση) ως δημόσια πραγματικά δεδομένα· το κείμενο των κριτικών είναι πιο ευαίσθητο
Συμβουλέψου νομικό επαγγελματία για τη δική σου περίπτωση.
Κλείνοντας
Τρεις δρόμοι, ένας στόχος.
Το Yelp Fusion API είναι η εξουσιοδοτημένη, χαμηλής συντήρησης επιλογή — αλλά περιορίζεται σε 3 αποσπάσματα κριτικών και ξεκινά από $29/μήνα. Το Python scraping σου δίνει πλήρη έλεγχο σε κάθε σημείο δεδομένων στο Yelp, αλλά απαιτεί σοβαρή επένδυση: curl_cffi για TLS impersonation, residential proxies, τυχαίες καθυστερήσεις, parsing κρυμμένων JSON και συνεχή συντήρηση καθώς εξελίσσονται οι άμυνες του Yelp. Το Thunderbit σε πάει από το «χρειάζομαι δεδομένα Yelp» στο «ορίστε το spreadsheet μου» σε περίπου 30 δευτερόλεπτα, χωρίς κώδικα και χωρίς ρύθμιση proxies.
Τα anti-blocking βασικά που πραγματικά δουλεύουν το 2025: ρεαλιστικά headers με πλήρη Client Hints, curl_cffi για TLS fingerprint impersonation, τυχαίες καθυστερήσεις με exponential backoff, rotation residential proxies και — πάνω απ’ όλα — parsing κρυμμένων JSON (application/ld+json και react-root-props) αντί για εύθραυστα CSS selectors.
Δεν είσαι σίγουρος ποιος δρόμος σου ταιριάζει; Δοκίμασε πρώτα το δωρεάν πλάνο του Thunderbit. Αν καλύπτει τις ανάγκες σου, γλίτωσες ώρες. Αν χρειάζεσαι περισσότερο έλεγχο — πλήρη προγραμματιστικά pipelines, custom πεδία, στενή ενσωμάτωση με CRM — ο παραπάνω οδηγός για Python σε καλύπτει. Και για μια πιο βαθιά ματιά στο τοπίο των scraping tools, δες το roundup μας με τα καλύτερα Chrome extensions για web scraper ή τον οδηγό μας για εξαγωγή δεδομένων από websites σε Excel.
Δοκίμασε το Thunderbit για εξαγωγή δεδομένων Yelp Get Started Free
Συχνές ερωτήσεις
Μπορώ να κάνω scrape το Yelp δωρεάν με Python;
Ναι — χρησιμοποιώντας δωρεάν βιβλιοθήκες όπως curl_cffi, parsel και jmespath. Αλλά σε πραγματική κλίμακα (πάνω από λίγες δεκάδες σελίδες), θα χρειαστείς πληρωμένους residential proxies, που ξεκινούν περίπου από $1.75/GB με την IPRoyal. Το Thunderbit προσφέρει επίσης δωρεάν πλάνο με 6 σελίδες/μήνα για γρήγορη, no-code εξαγωγή.
Το Yelp μπλοκάρει scrapers;
Ναι, και μάλιστα επιθετικά. Το Yelp χρησιμοποιεί TLS/JA3 fingerprinting, scoring αξιοπιστίας IP, CAPTCHAs, behavioral analysis και εναλλασσόμενα obfuscated CSS classes. Το vanilla requests μπλοκάρεται από το πρώτο κιόλας hit. Η πολυεπίπεδη στρατηγική anti-blocking σε αυτόν τον οδηγό — curl_cffi για TLS impersonation, ρεαλιστικά headers, τυχαίες καθυστερήσεις και residential proxies — είναι αυτή που δουλεύει το 2025.
Είναι το Yelp Fusion API καλύτερο από το scraping;
Εξαρτάται από τις ανάγκες σου. Το API είναι εξουσιοδοτημένο και χαμηλού ρίσκου, αλλά επιστρέφει μόνο 3 αποσπάσματα κριτικών περίπου 160 χαρακτήρων το καθένα, περιορίζει τα αποτελέσματα αναζήτησης στα 240 και ξεκινά από $29/μήνα. Αν χρειάζεσαι πλήρες κείμενο κριτικών, μεταδεδομένα κριτικών ή πάνω από μερικές εκατοντάδες εγγραφές την ημέρα, το scraping είναι η μόνη επιλογή.
Πώς κάνω scrape τις κριτικές του Yelp με Python;
Χρησιμοποίησε curl_cffi με impersonate="chrome131" για να τραβήξεις τη σελίδα της επιχείρησης, πάρε το encoded business ID από το <meta name="yelp-biz-id">, και μετά κάνε POST στο https://www.yelp.com/gql/batch με το operation GetBusinessReviewFeed και pagination μέσω ενός base64-encoded after cursor. Ο κώδικας βήμα-βήμα βρίσκεται στην ενότητα του tutorial πιο πάνω. Το Scrapfly Yelp scraper repo είναι επίσης μια πολύ καλή υλοποίηση αναφοράς.
Μπορώ να κάνω scrape το Yelp χωρίς κώδικα;
Ναι — το AI Web Scraper του Thunderbit διαθέτει έτοιμα templates για Yelp business και reviews. Άνοιξε μια σελίδα Yelp, πάτησε AI Suggest Fields, πάτησε Scrape. Οι εξαγωγές σε Google Sheets, Excel, Airtable και Notion είναι δωρεάν σε όλα τα πλάνα, συμπεριλαμβανομένου του free plan.
Μάθε περισσότερα
- Πώς να κάνεις Web Scraping χωρίς να μπλοκαριστείς σε Python
- Python Web Scraping: Απόφυγε τα μπλοκαρίσματα με έξυπνη χρήση proxies
- Κατάκτησε το Python Web Scraper: Οδηγός βήμα προς βήμα με παράδειγμα
- Python Web Scraping Tutorial: Πάρε δεδομένα από έναν ιστότοπο
- Python Web Scraping Tutorial: Πώς να κάνεις Scrape έναν ιστότοπο


