איך אני מגרד מידע מ‑Yelp עם Python בלי להיחסם

עודכן לאחרונה ב- April 15, 2026
איך אני מגרד מידע מ‑Yelp עם Python בלי להיחסם

Yelp מחזיקה 330 מיליון ביקורות מצטברות על פני 8.4 מיליון דפי עסקים פעילים — והפיכת המידע הזה לפורמט שימושי מעולם לא הייתה מאתגרת יותר. המאבק של Yelp נגד בוטים ב‑2024–2025 שבר בשקט את רוב מדריכי ה‑Python הקיימים לגרידת מידע.

אם ניסיתם לאחרונה להריץ Yelp scraper ונתקלתם בגל של שגיאות 403, תגובות HTML ריקות או CAPTCHA שלא הופיעו לפני חצי שנה — זה לא בדמיון שלכם. כיום Yelp מפעילה fingerprinting של TLS/JA3, שמות מחלקות CSS מוסווים שמתחלפים כל הזמן, ודירוג אגרסיבי של מוניטין IP — כלומר הגישה הישנה של requests + BeautifulSoup, שעדיין כמעט כל מדריך ממליץ עליה, נופלת כבר בבקשה הראשונה. השקענו שבועות בבדיקת גישות שונות מול המערכת הנוכחית של Yelp, והמדריך הזה מכסה את מה שבאמת עובד ב‑2025: ה‑Fusion API הרשמי (ולמה כנראה הוא לא יספיק), תהליך גרידת Python מלא עם אסטרטגיה שכבתית נגד חסימות, ואלטרנטיבה ללא קוד בשני קליקים עם Thunderbit למי שרוצה פשוט את הנתונים בלי מרתון של דיבוג.

נסו את Thunderbit לגרידת Yelp

למה לגרד מידע מ‑Yelp עם Python, ומי באמת מרוויח מזה?

לפני שכותבים אפילו שורת קוד אחת, מהו בעצם המקרה העסקי של נתוני Yelp? הפלטפורמה היא לא רק אתר של ביקורות למסעדות — היא בפועל מסד נתונים חי של עסקים מקומיים עם פרטי קשר מובנים, דירוגים, קטגוריות, שעות פעילות ומאות מיליוני ביקורות של לקוחות.

yelp_stats_bd6a43108e.png

הנה מי מרוויח הכי הרבה ומה הוא שולף:

מקרה שימוששדות נתונים מרכזייםלמה זה חשוב
מכירות וליד ג'נריישןשם העסק, טלפון, אתר, כתובת, קטגוריה, דירוגבניית רשימות לידים ממוקדות של עסקים קטנים מקומיים — 4 מתוך 5 משתמשי Yelp מוכנים לרכישה כבר עם הכניסה
מודיעין תחרותיביקורות, כוכבים, נפח ביקורות, סנטימנטמעקב אחרי מוניטין מתחרים, זיהוי פערי שירות, ניטור מגמות
מחקר שוק ו‑NLPטקסט מלא של ביקורות, תאריכים, מטא־דאטה של כותביםניתוח סנטימנט, מודליזציה של נושאים — ביקורות Yelp הן אחד מקורפוסי ה‑NLP הנפוצים ביותר במחקר אקדמי
נדל״ן ובחירת מיקומיםצפיפות עסקים, תמהיל קטגוריות, איכות ביקורות לפי אזורבחירת מיקומים לזכיינות ולקמעונאות — Yelp מוכרת Location Intelligence כמוצר B2B מורשה בדיוק לצורך הזה
איקומרס ותפעולאותות תמחור, תלונות לקוחות, שעות שירותמעקב אחר אופן הדירוג של מתחרים וזיהוי דפוסי תפעול

החוט המקשר: המטרה האמיתית היא נתונים מובנים, ו‑Python הוא רק אחד הכלים להגיע אליהם. יש קוראים שירצו שליטה תכנותית מלאה. אחרים רק צריכים גיליון עם פרטי אינסטלטורים באוסטין. כאן מכוסים שני המסלולים.

Yelp Fusion API מול גרידת מידע ב‑Python: מה כדאי לבחור?

רוב המדריכים מדלגים על ההחלטה הזו וקופצים ישר לקוד, בלי לבדוק האם Yelp Fusion API הרשמי (שממותג כעת כ‑"Yelp Places API") היה יכול להספיק. מניסיוני, הבדיקה הזו חוסכת שעות של עבודה מיותרת — כי ה‑API מצוין לחלק מהצרכים, אבל לגמרי לא מספיק לאחרים.

מה ה‑Fusion API באמת נותן

ה‑Fusion API מספק חיפוש עסקים מובנה, פרטי עסק, השלמה אוטומטית ו‑endpoint של ביקורות. הוא מורשה, מתועד היטב, ולא דורש תרגילי התחמקות מבוטים.

אבל ב‑endpoint של הביקורות הכל מתפרק. הנה מה שעובדי Yelp אישרו ב‑GitHub:

"The Yelp API does not return full review text. Three review excerpts of 160 characters are provided by default." — תשובת צוות Yelp, GitHub Issue #163

זה לא באג — זה מכוון. ה‑API מוגבל פיזית ל‑3 קטעי ביקורת (7 ב‑Premium), וכל קטע מקוצר לכ‑160 תווים. אין מטא־דאטה של הביקורת (votes של useful/funny/cool), אין היסטוריית כותב, אין תגובות של בעל העסק. ומגבלת הקריאות היומית ללקוחות חדשים ירדה ל‑300–500 ביום אחרי מאי 2023 — ירידה מ‑5,000. המחיר ההתחלתי עומד על $29 לחודש.

מסגרת ההחלטה

גורםYelp Fusion APIגרידת מידע ב‑PythonThunderbit (ללא קוד)
ביקורות מלאות❌ רק 3 קטעים (~160 תווים כל אחד)✅ כל הביקורות דרך GraphQL✅ כל הביקורות הגלויות
מגבלות קצב300–500/יום (חדש); 5,000 (ותיק)מנוהל על ידכם (תקציב פרוקסי)מבוסס קרדיטים
מאמץ התקנה~15 דק׳ (מפתח API + SDK)שעות עד ימים~2 דקות
שדות עסקיים~20 שדות מובניםללא הגבלה (ניתוח HTML/JSON)שדות מוצעים על ידי AI
טיפול נגד בוטיםלא רלוונטי (מורשה)צריך לבנות לבדמטופל אוטומטית
סיכון משפטי✅ מורשה⚠️ אזור אפור מול תנאי השימוש⚠️ אותו מצב כמו scraping
עלותמינימום $29/חודשחינם (+ עלות פרוקסי $0.75–$4/GB)יש חינם
תחזוקהנמוכה (API יציב)גבוהה (selectors נשברים, ההגנות מתהדקות)נמוכה (ה‑AI מתכוונן מחדש)

בחרו ב‑Fusion API אם: אתם צריכים מידע עסקי בסיסי, בדיקות בקנה מידה קטן, או אינטגרציה מורשית — ו‑3 קטעי ביקורת לעסק מספיקים לכם.

בחרו בגרידת Python אם: אתם צריכים טקסט מלא של ביקורות, את כל הביקורות לעסק, מטא־דאטה של ביקורות, יותר מ‑240 תוצאות לחיפוש, או שהתקציב שלכם נמוך מ‑$29 לחודש.

בחרו ב‑Thunderbit אם: אתם רוצים את הנתונים מהר, בלי לכתוב או לתחזק קוד. על כך יותר בסעיף ללא קוד בהמשך.

קיצור הדרך ללא קוד: לגרד Yelp עם Thunderbit (בלי Python)

לפני הצלילה ל‑Python, הנה הדרך המהירה ביותר למי שהמטרה האמיתית שלו היא הנתונים — לא תרגיל קידוד. כל מדריך מתחרה מניח שאתם כבר שולטים ב‑Python, אבל בעבודה שלי ב‑Thunderbit ראיתי שחלק גדול מהאנשים שמחפשים "scrape Yelp" הם אנשי מכירות, מנהלי תפעול ובעלי עסקים קטנים שרוצים פשוט גיליון עם עסקים מקומיים — לא קורס מזורז ב‑TLS fingerprinting.

Thunderbit כבר מגיע עם תבניות Yelp מובנות:

  • Yelp Business Web Scraper — מחלץ שם עסק, דירוג, פרטי קשר, כתובת, שעות, קטגוריה
  • Yelp Review Scraper — מחלץ שם משתמש של הכותב, תוכן הביקורת, דירוג, תאריך, מיקום הכותב

איך זה עובד בפועל

  1. פותחים בדפדפן Chrome עמוד תוצאות חיפוש של Yelp או עמוד עסק
  2. לוחצים AI Suggest Fields בתוסף Thunderbit — ה‑AI קורא את העמוד ומציע עמודות (שם עסק, דירוג, מספר ביקורות, טווח מחירים, קטגוריה, כתובת, טלפון, URL)
  3. לוחצים Scrape — וזהו

עם התבניות המובנות של Yelp, זה אפילו פשוט יותר: פותחים את התבנית ולוחצים Scrape.

גרידת תתי־עמודים מטפלת אוטומטית בלולאת ההעשרה — מתחילים מדף תוצאות חיפוש של Yelp, מפעילים subpage scraping, ו‑Thunderbit נכנס לכל עמוד עסק כדי לשלוף שעות פעילות, ביקורות מלאות, אתר, תמונות ומתקנים. בלי התקנה נוספת.

הדפדוף בעמודים אוטומטי — גם בלחיצה וגם בגלילה, מובנה כברירת מחדל. (למידע נוסף על איך זה עובד, ראו את מדריך הפגינציה שלנו.)

הייצוא חינם בכל מסלול — Excel, Google Sheets, Airtable, Notion, CSV, JSON. בלי pandas, בלי קוד כתיבה ל‑CSV.

השוואת זמן

זמןPython ScraperThunderbit
הרצה ראשונהשעות עד ימים (כתיבת selectors, טיפול בפגינציה, פרוקסים, לוגיקת retry)כ‑30 שניות עם תבנית Yelp המובנית
כש‑Yelp משנה markupכותבים selectors מחדש ידניתלוחצים שוב על AI Suggest Fields — המערכת מתאימה את עצמה מחדש
כש‑IP נחסםדיבוג, החלפת מאגרי פרוקסי, בדיקות חוזרותמצב Cloud מטפל ברוטציה של IP
ייצוא ל‑Google Sheetsכתיבת OAuth ו‑pandas glueקליק אחד, חינם

אם תנסו קודם את Thunderbit ותגלו שהוא עונה על הצרכים שלכם, תוכלו לדלג על שאר המאמר. אם אתם צריכים שליטה תכנותית מלאה, שדות מותאמים, או קנה מידה של אלפי רשומות בחודש — המשיכו לקרוא.

ספריות Python לגרידת Yelp: איזו לבחור

"האם להשתמש ב‑Scrapy, ב‑BS4+requests, או ב‑Selenium?" זו אחת השאלות הנפוצות ביותר בשרשורי r/webscraping על Yelp. ובכל זאת, כל מדריך פשוט בוחר את הספרייה המועדפת עליו וממשיך הלאה בלי להסביר למה. הנה ההסבר הישר.

המציאות של 2025: requests + BeautifulSoup שבור עבור Yelp

הסטאק שכמעט כל מדריך קלאסי ל‑Yelp ממליץ עליו — pip install requests beautifulsoup4נחסם כבר בבקשה הראשונה ב‑2025. לא ב‑50. בראשונה.

הסיבה: ספריית requests של Python שולחת fingerprint של TLS/JA3 שלא תואם אף דפדפן אמיתי. שכבת ההגנה של Yelp נגד בוטים מזהה זאת ברמת ה‑TLS handshake, עוד לפני שהיא בכלל קוראת את כותרת ה‑User-Agent. בדקתי זאת שוב ושוב — IP חדש, כותרות מציאותיות, השהיות אקראיות — ועדיין קיבלתי מיד 403 Forbidden עם requests רגיל.

מטריצת החלטה בין הספריות

ספרייהמתאימה במיוחד למטפלת ב‑JS?נגד בוטים?עקומת למידהמהירות
requests + BeautifulSoupגרידה פשוטה של עמוד יחיד (שבור עבור Yelp)נמוכה מאודמהירה (עד החסימה)
httpx async + parselגרידה אסינכרונית בהיקף גדולנמוכהמהירה מאוד
curl_cffi + parselספציפית ל‑Yelp: התחזות ל‑TLS✅ TLS/JA3/HTTP2נמוכהמהירה מאוד
Scrapy 2.14צינורות crawl מלאים עם פגינציהחלקית (דרך scrapy-playwright)AutoThrottle, retry middlewareבינונית-גבוההמהירה
Selenium 4.43 / Playwright 1.58עמודים עתירי JS, מעקפים ל‑CAPTCHAחלקיתבינוניתאיטית (~10–30 עמודים לדקה)
Thunderbitלא טכניים, שליפה מהירה✅ (בדפדפן)מובנה (Cloud mode)נמוכה מאודמהירה

הגילוי על curl_cffi

הספרייה ששינתה לי את תהליך העבודה עם Yelp היא curl_cffi — binding של Python ל‑curl-impersonate. היא מפיקה בדיוק את אותו fingerprint של TLS/JA3 + HTTP/2 כמו 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" — עוקף את שכבת ההגנה הגדולה ביותר של Yelp נגד בוטים בלי להפעיל דפדפן. בבדיקות שלי זה ההבדל בין חסימות 403 מיידיות לבין תשובות 200 נקיות.

הסטאק שאני ממליץ עליו ל‑Yelp ב‑2025: curl_cffi + parsel + jmespath + פרוקסי residential. אם אתם צריכים צינור crawl מלא עם תזמון, עטפו זאת ב‑Scrapy 2.14 עם middleware להורדה שמבוסס על curl_cffi.

איך להגדיר סביבת Python לגרידת Yelp

  • רמת קושי: בינונית
  • זמן נדרש: כ‑15 דקות להגדרה, 1–2 שעות לסקרייפר עובד
  • מה תצטרכו: Python 3.10+ (מומלץ 3.12), טרמינל, ואופציונלית ספק פרוקסי residential

שלב 1: יצירת סביבה וירטואלית והתקנת חבילות

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 עם fingerprint של TLS של Chrome (מעקף ההגנות נגד בוטים)
  • parsel — סלקטורים של CSS/XPath לפענוח HTML (אותו מנוע של Scrapy, רק קל יותר)
  • jmespath — שאילתות JSON דקלרטיביות (נקי יותר מגישה מקוננת למילונים ב‑JSON המוטמע של Yelp)
  • pandas — ייצוא נתונים ל‑CSV/Excel

אופציונלי, אבל שימושי:

pip install fake-useragent  # שימו לב: המאגר הועבר לארכיון באפריל 2026 אך עדיין ניתן להתקנה

שלב אחר שלב: איך לגרד Yelp עם Python

זהו המדריך המרכזי. התובנה החשובה שהופכת הכול לעמיד יותר: לדלג על CSS selectors ולשלוף JSON מוסתר במקום זאת. Yelp מערבת את שמות מחלקות ה‑CSS בזמן הבנייה (y-css-14xwok2 שבוע אחד, y-css-hcq7b9 בשבוע הבא), ולכן כל scraper שנעול עליהם נשבר תוך שבועות. מטעני ה‑JSON המוטמעים — application/ld+json ו‑react-root-props — יציבים.

שלב 2: גרידת תוצאות חיפוש של Yelp

כתובות החיפוש של 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"Blocked on page {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"No react-root-props found on page {page} — possible 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 חסר בתגובה, קיבלתם מעטפת חסימה — החליפו IP ונסו שוב.

הכותרת Cookie: intl_splash=false היא עקיפה סטנדרטית של ה־country-splash redirect של Yelp. בלעדיה, IP‑ים לא אמריקאיים נתקלים בעמוד splash שנראה כמו חסימה רכה, אבל בפועל לא.

שלב 3: גרידת דפי עסקים ב‑Yelp

כל URL של עסק שמגיע מתוצאות החיפוש מוביל לעמוד פרטים עם נתונים עשירים יותר. יעד השליפה היציב ביותר הוא בלוק <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"] הוא מזהה העסק המוצפן שתצטרכו עבור endpoint הביקורות. תאספו אותו כאן — תשתמשו בו בשלב הבא.

שלב 4: גרידת ביקורות Yelp עם פגינציה

כאן ה‑Fusion API נופל והגרידה מנצחת. ה‑GraphQL הפנימי של Yelp מחזיר טקסט מלא של ביקורות, מידע על הכותב, תאריכים, דירוגים ומספרי הצבעות — כל מה שה‑API מסתיר.

ה‑endpoint הוא https://www.yelp.com/gql/batch, והוא משתמש ב‑documentId סטטי עבור הפעולה GetBusinessReviewFeed. הפגינציה פועלת באמצעות cursor שמקודד ב‑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"Review fetch failed at offset {offset}: {r.status_code}")
            break
        data = r.json()
        # Navigate the response structure to extract reviews
        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 ב‑cursor המקודד ב‑base64 כדי לדפדף. הפרמטר sortBy מקבל DATE_DESC (החדשות ביותר קודם), RATING_ASC, RATING_DESC, ועוד.

שלב 5: ייצוא נתוני Yelp שגרדתם

import pandas as pd

# Assuming you've collected businesses and 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)

# Or save as JSON for flexibility
import json
with open("yelp_data.json", "w") as f:
    json.dump({"businesses": businesses, "reviews": all_reviews}, f, indent=2)

למי שבוחר במסלול ללא קוד, Thunderbit מייצא את אותם נתונים ישירות ל‑Excel, Google Sheets, Airtable או Notion — בלי pandas ובלי קוד לכתיבת קבצים.

ספר המשחק נגד חסימות: איך לגרד Yelp בלי להיחסם

זהו כל הסיפור של המאמר. ההגנות של Yelp נגד בוטים הפכו משמעותית קשוחות מאז סוף 2024 — TLS fingerprinting, בדיקות מוניטין IP, CAPTCHA, וניתוח התנהגותי כולם נמצאים במשחק. רוב המדריכים הקיימים מיושנים כי נכתבו לפני המהלך הזה.

yelp_antiblock_518f0447bb.png

האסטרטגיה היא שכבתית. כל שכבה מורידה את שיעור החסימה; יחד הן הופכות גרידה מתמשכת לאפשרית.

שכבה 1: כותרות בקשה מציאותיות

כותרות ברירת המחדל של requests ב‑Python שולחות User-Agent: python-requests/2.x — נחסם מיד. אבל גם User-Agent מציאותי לא מספיק. Yelp בודקת את כל סט ה‑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",
}

שלוש טעויות שמסמנות אתכם:

  1. ה‑UA טוען ל‑Chrome אבל sec-ch-ua חסר או סותר את גרסת ה‑UA
  2. sec-ch-ua-platform אומר "Windows" אבל מחרוזת ה‑UA אומרת macOS
  3. אותו UA בדיוק לאורך אלפי בקשות מאותו IP — צריך לרוטט מאגר של 10–20 מחרוזות Chrome/Firefox/Safari עדכניות

שכבה 2: הגבלת קצב והשהיות אקראיות

דפוסי תזמון צפויים הם נורה אדומה. הוסיפו מרווחי שינה אקראיים ויישמו backoff אקספוננציאלי על שגיאות.

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"Blocked after {attempt + 1} attempts on {url}")
        backoff = 2 ** (attempt + 1) + random.random()
        print(f"  Got {r.status_code}, backing off {backoff:.1f}s (attempt {attempt + 1})")
        time.sleep(backoff)
        return polite_get(client_get, url, attempt + 1)
    time.sleep(random.uniform(3, 7))
    return r
פרמטרערך מומלץ
שינה אקראית בין בקשותrandom.uniform(3, 7) שניות
backoff על 429/403/5032 → 4 → 8 → 16 שנ׳, עד 5 ניסיונות
עובדים מקבילים לכל IP1 (סדרו לפי IP; השתמשו בפרוקסי בשביל מקביליות)
קצב מקסימלי בר־קיימא ל‑residential IPבערך בקשה אחת כל 5 שניות (~12 לדקה)

שכבה 3: רוטציה של User-Agent ושל סשנים

רוטו בין מאגר של מחרוזות User-Agent אמיתיות של דפדפנים. שמרו סשנים ו‑cookies כדי לדמות גלישה אמיתית — Yelp משתמשת בזיהוי מבוסס cookie, ולכן יצירת סשן חדש לכל בקשה חשודה בפני עצמה.

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",
    # Add 5-10 more recent strings
]

שכבה 4: רוטציית פרוקסי

בכל נפח משמעותי באמת, צריך פרוקסי residential. פרוקסי data center ופרוקסי חינמיים לא עובדים על Yelp — שכבת מוניטין ה‑IP של Yelp חוסמת מראש כתובות AWS, GCP ו‑DigitalOcean.

ספקמחיר כניסה ל‑GBהערות
IPRoyal$1.75/GBהזול ביותר; מריץ את המדריך הנפוץ ביותר ל‑Yelp
Decodo (לשעבר Smartproxy)$3.20–$3.50יחס GB/$ טוב במיוחד בנפחים
Bright Data$4.00 (PAYG)מאגר של 150M+ IP; דף ייעודי לפרוקסי Yelp
Oxylabs$6.00–$8.00פרימיום; 10M+ IPs
Aluvia (mobile SIM)$3.00כתובות IP סלולריות אמיתיות של ספקי US, ממותגות עבור Yelp

Rotating residential (IP חדש לכל בקשה) עובד הכי טוב לסריקות חיפוש בנפח גבוה. Sticky sessions (שמירת IP אחד ל‑10 דקות) עדיפות כששומרים cookies לאורך זרימה של עמוד עסק → ביקורות → פגינציה.

שכבה 5: זיהוי וטיפול בחסימות

לא כל חסימה נראית אותו דבר. Yelp מציגה לעיתים מעטפת כללית של "page not available" במקום CAPTCHA, ולכן scraper נאיבי חושב שהוא קיבל נתונים בזמן שבפועל הוא מקבל תשובה ריקה.

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
    # If this is a search/business page but react-root-props is missing,
    # Yelp served a stripped block response
    if "react-root-props" not in body and "/biz/" in str(resp.url):
        return True
    return False
סימןמשמעות
HTTP 403חסימה קשה — IP/headers/TLS נשרפו
HTTP 429הגבלת קצב — לעיתים ניתן לשחזור עם backoff
HTTP 503חסימה כללית או עומס
Redirect ל‑/error או גוף "page not available"חסימה רכה
ריק עם רק עמוד challenge שמחכה ל‑JS
captcha / g-recaptcha / px-captcha בגוףהסלמה — נדרש CAPTCHA
react-root-props חסר בעמוד רישוםתשובת חסימה מופשטת

שכבה 6: טריק הפענוח העמיד — JSON מוסתר במקום CSS selectors

כדאי לחזור על זה: Yelp מערבת את שמות מחלקות ה‑CSS בזמן הבנייה. scraper שנשען על h3.y-css-14xwok2 יישבר תוך שבועות כש‑Yelp תפרוס גרסה עם h3.y-css-hcq7b9.

הנתונים שלא זזים:

  • <script type="application/ld+json"> — structured data של schema.org (שם, כתובת, טלפון, דירוג, שעות)
  • <script data-id="react-root-props"> — כל נתוני תוצאות החיפוש כ‑JSON
  • https://www.yelp.com/gql/batch — endpoint הביקורות של GraphQL עם documentId יציב

אם אתם מנתחים CSS classes, אתם בונים על חול. עדיף לנתח JSON.

שכבה 7: fallback של דפדפן stealth

עוברים לדפדפן headless רק כאשר curl_cffi + פרוקסי residential לא מצליחים — בדרך כלל כש‑Yelp מציגה עמוד JS challenge או CAPTCHA.

ב‑95% ממקרי הגרידה של עסקים/חיפוש/ביקורות, curl_cffi + JSON מוסתר + פרוקסי residential מהירים, זולים ואמינים יותר מדפדפן. אבל כשבאמת צריך דפדפן:

כליסטטוס (2025)הערות
rebrowser-playwrightנקודת התחלה מומלצתPlaywright עם תיקונים מובנים ל‑CDP leaks
nodriverהטוב ביותר בקטגוריה ל‑Chrome stealthיורש של undetected-chromedriver; עוקף לחלוטין את פרוטוקול WebDriver
patchrightFork של Playwright שמתוחזק באופן פעילעובר בדיקות זיהוי מודרניות
playwright-stealthבוגרמתקן navigator.webdriver, מסיר HeadlessChrome מ‑UA

עדיף לוותר על Selenium רגיל עבור Yelp. קל מדי לזהות אותו.

Yelp Fusion API מול Python Scraping מול Thunderbit: השוואה מלאה

ממדYelp Fusion APIPython ScrapingThunderbit
טקסט מלא של ביקורות❌ 3 קטעים × ~160 תווים✅ ללא הגבלה (GraphQL)✅ תבנית ביקורות מובנית
מטא־דאטה של ביקורות (votes, תגובות בעלים)✅ דרך שדות מוצעים על ידי AI
תמונות❌ (0 ב‑Base)✅ ללא הגבלה
מקסימום תוצאות לחיפוש240 (היה 1,000 לפני 2024)ללא הגבלה (עם פגינציה)ללא הגבלה
מגבלת קצב יומית300–500 (חדש) / 5,000 (ותיק)רק תקציב פרוקסימבוסס קרדיטים (3,000/חודש ב‑Pro)
מאמץ התקנה~15 דק׳שעות עד ימים~2 דקות
טיפול נגד בוטיםלא רלוונטיהבעיה שלכםמטופל (Cloud mode)
סיכון משפטינמוך (מורשה)בינוני (אזור אפור מול תנאי השימוש)בינוני (אותו מצב כמו scraping)
עלות התחלתית$29 לחודשבערך $0.75–$4/GB לפרוקסי + זמן פיתוחיש חינם
עלות בשימוש כבד$643+ לחודש$50–$500 לחודש בפרוקסי + זמן פיתוח$38–$49 לחודש
ייצוא נתוניםJSONCSV/JSON (אתם כותבים)Excel / Sheets / Airtable / Notion — חינם
תחזוקהנמוכהגבוהה (selectors נשברים, ההגנות מתהדקות)נמוכה (ה‑AI מתכוונן מחדש)

טיפים משפטיים ואתיים לגרידת Yelp

אני לא עורך דין, וזה לא ייעוץ משפטי. אבל הנוף המשפטי השתנה מספיק בשנתיים האחרונות, ולכן כדאי להכיר את הבסיס לפני שמשקיעים זמן בפרויקט גרידת Yelp.

מה תנאי השימוש של Yelp אומרים: עדכון תנאי השימוש מאוקטובר 2025 אוסר במפורש להשתמש ב"any robot, spider... or other automated device" כדי "access, retrieve, copy, scrape, or index any portion of the Service." נוסף גם ניסוח על "AI Technologies and/or other automated tools."

התמיכה של Yelp חוזרת על כך: "Yelp does not allow any scraping of the site."

מה robots.txt אומר: ב‑robots.txt של Yelp יש wildcard User-agent: * / Disallow: /, והוא חוסם במפורש גם GPTBot, ClaudeBot, PerplexityBot, CCBot ו‑Meta-ExternalAgent. רק Googlebot, Bingbot וכמה סורקי רשתות חברתיות נמצאים ברשימת ההיתר.

התקדים המשפטי החשוב: ב‑Meta v. Bright Data (N.D. Cal. Jan 2024) בית המשפט קבע שגרידת נתונים ציבוריים שאינם מאחורי התחברות לא הפרה את תנאי Meta. ההבחנה המרכזית: נתונים ציבוריים ללא התחברות מול נתונים מאחורי התחברות. תיק hiQ v. LinkedIn קבע שגרידה של נתונים ציבוריים כנראה אינה מפרה את ה‑CFAA, אבל hiQ עדיין הפסידה בתביעות נזיקין של המדינה (trespass to chattels, misappropriation) וחויבה בפסק דין של $500,000.

הנחיות מעשיות:

  • גרדו רק עמודים ציבוריים שנגישים ללא התחברות
  • הגבילו קצב בקשות (ההשהיות במדריך הזה משמשות גם כהגבלת קצב אתית)
  • אל תמכרו מחדש טקסט גולמי של ביקורות עם שיוך למשתמשים מזוהים — כבדו את פרטיות הכותבים
  • צייתו לחוקי הגנת המידע המקומיים (CCPA, GDPR)
  • אל תתחברו כדי לגרד — זה חוצה את קו ההרשאה
  • התייחסו למידע עסקי (שם/כתובת/טלפון/דירוג) כנתון עובדתי ציבורי; לטקסט ביקורות התייחסו כרגיש יותר

התייעצו עם גורם משפטי מוסמך לגבי המקרה הספציפי שלכם.

לסיכום

שלושה מסלולים, מטרה אחת.

Yelp Fusion API הוא האופציה המורשית והפחות תחזוקתית — אבל הוא מוגבל ל‑3 קטעי ביקורות ומתחיל ב‑$29 לחודש. גרידת Python נותנת לכם שליטה מלאה על כל נקודת נתון ב‑Yelp, אבל דורשת השקעה אמיתית: curl_cffi ל‑TLS impersonation, פרוקסי residential, השהיות אקראיות, ניתוח JSON מוסתר, ותחזוקה שוטפת ככל שההגנות של Yelp מתפתחות. Thunderbit מביא אתכם מ"אני צריך נתונים מ‑Yelp" ל"הנה הגיליון שלי" בכ‑30 שניות, בלי קוד ובלי הגדרת פרוקסי.

המרכיבים נגד חסימה שבאמת עובדים ב‑2025: כותרות מציאותיות עם Client Hints מלאים, curl_cffi להתחזות לפינגרפרינט של TLS, השהיות אקראיות עם backoff אקספוננציאלי, רוטציית פרוקסי residential, ומעל הכול — ניתוח JSON מוסתר (application/ld+json ו‑react-root-props) במקום CSS selectors שבירים.

לא בטוחים איזה מסלול מתאים? נסו קודם את התוכנית החינמית של Thunderbit. אם היא עונה על הצרכים שלכם, חסכתם לעצמכם שעות. אם אתם צריכים יותר שליטה — צינורות תכנותיים מלאים, שדות מותאמים, אינטגרציה הדוקה עם CRM — המדריך ל‑Python למעלה מכסה אתכם. ולמבט עמוק יותר על נוף כלי הגרידה, בדקו את הסקירה שלנו על ההרחבות הטובות ביותר ל‑Chrome לגרידת מידע או את המדריך שלנו ל‑גרידת נתונים מאתרים לתוך Excel.

נסו את Thunderbit לחילוץ נתונים מ‑Yelp Get Started Free

שאלות נפוצות

האם אפשר לגרד Yelp בחינם עם Python?

כן — באמצעות ספריות חינמיות כמו curl_cffi, parsel ו‑jmespath. אבל בכל נפח אמיתי (יותר מכמה עשרות עמודים), תצטרכו פרוקסי residential בתשלום, שמתחילים סביב $1.75/GB ב‑IPRoyal. Thunderbit מציע גם שכבת חינם עם 6 עמודים בחודש לחילוץ מהיר ללא קוד.

האם Yelp חוסמת scrapers?

כן, ובאופן אגרסיבי. Yelp משתמשת ב‑TLS/JA3 fingerprinting, דירוג מוניטין IP, CAPTCHA, ניתוח התנהגותי, ומחלקות CSS מוסוות שמתחלפות. requests רגיל נחסם כבר במגע הראשון. האסטרטגיה השכבתית נגד חסימות במדריך הזה — curl_cffi להתחזות TLS, כותרות מציאותיות, השהיות אקראיות ופרוקסי residential — היא מה שעובד ב‑2025.

האם Yelp Fusion API עדיף על גרידה?

תלוי בצרכים שלכם. ה‑API מורשה ובעל סיכון נמוך, אבל הוא מחזיר רק 3 קטעי ביקורות של כ‑160 תווים כל אחד, מגביל תוצאות חיפוש ל‑240, ומתחיל ב‑$29 לחודש. אם אתם צריכים טקסט מלא של ביקורות, מטא־דאטה של ביקורות, או יותר מכמה מאות רשומות ביום — גרידה היא האופציה היחידה.

איך מגרדים ביקורות Yelp עם Python?

משתמשים ב‑curl_cffi עם impersonate="chrome131" כדי לשלוף את עמוד העסק, לוקחים את מזהה העסק המוצפן מתוך <meta name="yelp-biz-id">, ואז מבצעים POST ל‑https://www.yelp.com/gql/batch עם הפעולה GetBusinessReviewFeed ומבצעים פגינציה באמצעות cursor מקודד ב‑base64 בשם after. הקוד שלב־אחר־שלב נמצא בסעיף המדריך למעלה. גם מאגר Yelp scraper של Scrapfly הוא מימוש ייחוס טוב.

אפשר לגרד Yelp בלי לקודד?

כן — Thunderbit AI Web Scraper מגיע עם תבניות מוכנות לעסקים ב‑Yelp ולביקורות. פותחים עמוד Yelp, לוחצים AI Suggest Fields, ואז Scrape. הייצוא ל‑Google Sheets, Excel, Airtable ו‑Notion חינמי בכל המסלולים, כולל התוכנית החינמית.

למידע נוסף

Shuai Guan
Shuai Guan
מנכ"ל Thunderbit | מומחה לאוטומציה של נתונים באמצעות AI Shuai Guan הוא המנכ"ל של Thunderbit ובוגר הפקולטה להנדסה של אוניברסיטת מישיגן. עם כמעט עשור של ניסיון בטכנולוגיה ובארכיטקטורת SaaS, הוא מתמחה בהפיכת מודלים מורכבים של AI לכלי חילוץ נתונים פרקטיים, ללא קוד. בבלוג הזה הוא משתף תובנות ישירות מהשטח, שנבחנו בפועל, על Web Scraping ואסטרטגיות אוטומציה שיעזרו לכם לבנות תהליכי עבודה חכמים יותר, מבוססי נתונים. כשאינו משפר תהליכי נתונים, הוא מביא את אותה תשומת לב לפרטים גם לתשוקה שלו לצילום.
תוכן עניינים

גרדו דף אינטרנט פשוט על ידי בקשה

תגידו מה צריך באנגלית פשוטה. או אפילו לא צריך להגיד כלום.

נסו את Thunderbit חינם
חילוץ נתונים באמצעות AI
העבירו נתונים בקלות ל-Google Sheets, Airtable או Notion
Chrome Store Rating
PRODUCT HUNT#1 Product of the Week