Как скрапить Yelp: бизнес-листинги и отзывы в 2026 году (публичные данные, PerimeterX и прокси)

Практическое руководство для разработчиков: как скрапить Yelp бизнес-данные и отзывы из публичных страниц, обходить PerimeterX/HUMAN и использовать ротационные резидентные прокси ProxyHat с гео-таргетингом по США.

How to Scrape Yelp Business Listings and Reviews in 2026: Public Data, PerimeterX, and Proxies
В этой статье

Важно: этот гайд посвящён только публично доступным данным Yelp — тем, что видны анонимному посетителю без авторизации. Скрапинг может нарушать Terms of Service Yelp; в США чрезмерное автоматизированное обращение к защищённым системам может подпадать под Computer Fraud and Abuse Act (CFAA), а в ЕС персональные данные из отзывов регулируются GDPR. Перед запуском продакшен-сбора проконсультируйтесь с юристом и рассмотрите официальный Yelp Fusion API.

Если вы строите локальный бизнес-датасет — каталоги ресторанов, салонов, автосервисов вместе с рейтингами и отзывами — Yelp остаётся одним из самых ценных источников. Но в 2026 году «как скрапить Yelp» — это не вопрос парсинга HTML, а вопрос обхода антибот-системы PerimeterX/HUMAN, управления TLS-фингерпринтами и правильного выбора прокси. В этом гайде разберём, что именно доступно публично, как Yelp защищается, и как собрать бизнес-листинги и отзывы, не получая бан на первых 10 запросах.

Как скрапить Yelp в 2026: что доступно без авторизации

Yelp публикует значительный объём бизнес-данных на публичных страницах без логина. Каждое заведение имеет профиль по адресу https://www.yelp.com/biz/<slug>, где slug — это URL-идентификатор вида blue-bottle-coffee-austin. Без аккаунта и без cookies вы видите:

  • Название, рейтинг (1–5 звёзд), количество отзывов и категорию бизнеса.
  • Адрес, телефон, часы работы, включая сезонные исключения.
  • Тексты отзывов — обычно первые ~100 отзывов доступны анонимно, остальные скрываются за кнопкой «see more» и подгрузкой.
  • Фотографии от пользователей и владельца бизнеса.
  • Атрибуты — «takes reservations», «outdoor seating», «wheelchair accessible» и т. п.

Официальный Yelp Fusion API даёт доступ к бизнес-поиску и деталям, но возвращает максимум 3 отзыва на бизнес через endpoint /businesses/{id}/reviews. Если вам нужен полный корпус отзывов для анализа тональности, обучения моделей или мониторинга репутации — Fusion API не покроет потребность, и единственный легальный путь — сбор публично видимых страниц.

Важно: данные за логином (личные сообщения, расширенная история отзывов конкретного пользователя, некоторые фотоальбомы) не входят в этот гайд. Их скрапинг нарушает ToS и в США может подпадать под CFAA.

Антибот-защита Yelp: PerimeterX/HUMAN, _px3 и TLS-фингерпринтинг

Yelp использует PerimeterX (ныне HUMAN Security) — одну из самых агрессивных антибот-платформ на рынке. PerimeterX работает на нескольких уровнях:

При первом запросе PerimeterX выполняет JavaScript-«sensor challenge» — собирает данные о браузере (Canvas fingerprint, WebGL, шрифты, тайминги, mouse movements) и выпускает cookie _px3. Без валидного _px3 сервер Yelp либо отдаёт пустую страницу, либо редиректит на /px-captcha. Обычный requests.get() без headless-браузера этот challenge не пройдёт.

2. TLS-фингерпринтинг (JA3/JA4)

PerimeterX анализирует TLS ClientHello — наборы шифров, расширения, порядок curves — и сравнивает с сигнатурой заявленного User-Agent. Если вы шлёте UA Chrome 120, но JA3 соответствует Python requests (на базе urllib3/OpenSSL), запрос помечается как бот. По данным исследований BrowserLeaks TLS, JA3-хеш Python requests стабильно отличается от Chrome на 100%.

3. IP-репутация и скоринг

PerimeterX ведёт репутационную базу IP. Datacenter-диапазоны (AWS, DigitalOcean, OVH, Hetzner) имеют низкий «trust score» — после 5–20 запросов с одного datacenter IP вы получаете CAPTCHA или 403. Резидентные IP от крупных ISP (Comcast, AT&T, Verizon) имеют высокий trust score и проходят значительно дольше.

4. CAPTCHA после нескольких datacenter-запросов

На практике: с datacenter-прокси без ротации первые 5–15 запросов могут пройти, затем — CAPTCHA. С резидентными IP и разумным темпом (1–2 запроса/сек на сессию) можно собирать тысячи страниц до первого блока, а ротация между запросами снижает риск ещё сильнее.

Почему нужны ротационные резидентные прокси с гео-таргетингом по США

Две причины делают резидентные прокси с US-гео стандартом для скрапинга Yelp:

  1. IP-репутация. PerimeterX скорит по IP-классу. Резидентные IP от американских ISP имеют trust score в 3–5 раз выше datacenter-IP по оценкам антифрод-вендоров. Это напрямую влияет на количество запросов до CAPTCHA.
  2. Локализация результатов. Yelp отдаёт разные бизнес-листинги в зависимости от гео IP-посетителя. Запрос /search?find_desc=coffee&find_loc=Austin,+TX с IP из Германии может вернуть искажённые результаты или триггерить дополнительную проверку. IP из Остин, TX (-country-US-city-austin) даёт корректные локальные результаты.

Mobile-прокси (4G/5G) тоже имеют высокую репутацию, но обычно стоят дороже и дают большую задержку (300–800ms против 80–200ms у резидентных). Для Yelp оптимальны именно резидентные.

Сравнение типов прокси для скрапинга Yelp:

Тип проксиРепутация у PerimeterXЗадержкаЦенаГео-таргетинг по городуПодходит для Yelp
DatacenterНизкая20–50msНизкаяОграниченныйНет — быстрые блоки
ResidentialВысокая80–200msСредняяДа (страна/город)Да — оптимально
Mobile (4G/5G)Очень высокая300–800msВысокаяДа (страна)Да, но дороже

Подобрать гео и оценить стоимость можно на странице локаций ProxyHat и на странице тарифов.

Архитектура скрапера: review_feed JSON и __INITIAL_STATE__

Вместо парсинга HTML регулярками или BeautifulSoup, эффективнее извлекать данные из встроенных JSON-блобов, которые Yelp рендерит в страницу для гидратации React-приложения. Два ключевых источника:

  • window.__INITIAL_STATE__ — большой JSON-объект в теге <script>, содержит бизнес-профиль, первые отзывы, категории, фото.
  • review_feed — JSON-эндпоинт вида /biz/<slug>?q=&rl=en&sort_by=relevance_desc или AJAX-эндпоинт /async/<slug>/review_feed, отдаёт пагинированные отзывы.

Извлечение __INITIAL_STATE__ одним regex-матчем над HTML быстрее и надёжнее, чем 50 CSS-селекторов. Для пагинации отзывов используется review_feed с параметром start (offset) и limit.

Пример 1: Python requests + ProxyHat HTTP-шлюз

Ниже — рабочий скелет на Python, использующий ротационные резидентные прокси ProxyHat через HTTP-шлюз gate.proxyhat.com:8080 с гео-таргетингом по Остину, TX. Скрипт извлекает __INITIAL_STATE__ и парсит один truncated-объект отзыва.

import re, json, time, random
import requests
from urllib.parse import quote

PROXY = "http://user-country-US-city-austin:PASSWORD@gate.proxyhat.com:8080"
PROXIES = {"http": PROXY, "https": PROXY}

UA_POOL = [
    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 "
    "(KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 "
    "(KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
]

def fetch_biz(slug: str, session_id: str | None = None) -> dict:
    user = f"user-country-US-city-austin"
    if session_id:
        user += f"-session-{session_id}"
    proxy = f"http://{user}:PASSWORD@gate.proxyhat.com:8080"
    proxies = {"http": proxy, "https": proxy}

    url = f"https://www.yelp.com/biz/{slug}"
    headers = {
        "User-Agent": random.choice(UA_POOL),
        "Accept-Language": "en-US,en;q=0.9",
        "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
    }
    r = requests.get(url, proxies=proxies, headers=headers, timeout=30)
    if r.status_code != 200 or "px-captcha" in r.text.lower():
        raise RuntimeError(f"Blocked or captcha: status={r.status_code}")

    # Извлекаем __INITIAL_STATE__
    m = re.search(r"window\.__INITIAL_STATE__\s*=\s*({.*?});?</script>",
                  r.text, re.DOTALL)
    if not m:
        raise RuntimeError("__INITIAL_STATE__ not found")
    state = json.loads(m.group(1))

    # Бизнес-профиль
    biz = state.get("bizDetailsPageProps", {}).get("businessContent", {})
    name = biz.get("name", "")
    rating = biz.get("rating", 0)
    review_count = biz.get("reviewCount", 0)

    # Первый truncated-объект отзыва
    reviews = state.get("bizDetailsPageProps", {}) \
                  .get("reviewFeedQuery", {}).get("reviews", [])
    first_review = {
        "id": reviews[0].get("id", "") if reviews else "",
        "author": reviews[0].get("author", {}).get("displayName", "") if reviews else "",
        "rating": reviews[0].get("rating", 0) if reviews else 0,
        "text": (reviews[0].get("comment", {}).get("text", "")[:200] + "…") if reviews else "",
        "date": reviews[0].get("localizedDate", "") if reviews else "",
    }

    return {
        "name": name,
        "rating": rating,
        "review_count": review_count,
        "first_review": first_review,
    }

if __name__ == "__main__":
    result = fetch_biz("blue-bottle-coffee-austin", session_id="biz1-abc123")
    print(json.dumps(result, indent=2, ensure_ascii=False))
    time.sleep(random.uniform(1.0, 2.5))  # pacing

Что делает этот код:

  • Использует -country-US-city-austin для локализованных результатов из Остина.
  • Опциональный -session-{id} включает sticky-сессию — один IP на всё время пагинации отзывов.
  • Ротирует User-Agent между двумя реальными Chrome-строками.
  • Извлекает __INITIAL_STATE__ одним regex, парсит первый truncated-объект отзыва (текст обрезан до 200 символов).
  • Спит 1.0–2.5 секунды между запросами для pacing.

Пример 2: Node.js + SOCKS5 на порту 1080

Для Node.js используем SOCKS5-шлюз ProxyHat на порту 1080 и библиотеку socks-proxy-agent:

const { SocksProxyAgent } = require('socks-proxy-agent');
const fetch = require('node-fetch');

const PROXY_URL = 'socks5://user-country-US-city-austin:PASSWORD@gate.proxyhat.com:1080';
const agent = new SocksProxyAgent(PROXY_URL);

const UA_POOL = [
  'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 ' +
  '(KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
  'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 ' +
  '(KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
];

async function fetchBiz(slug, sessionId) {
  let user = 'user-country-US-city-austin';
  if (sessionId) user += `-session-${sessionId}`;
  const agent = new SocksProxyAgent(
    `socks5://${user}:PASSWORD@gate.proxyhat.com:1080`
  );

  const url = `https://www.yelp.com/biz/${slug}`;
  const headers = {
    'User-Agent': UA_POOL[Math.floor(Math.random() * UA_POOL.length)],
    'Accept-Language': 'en-US,en;q=0.9',
  };

  const res = await fetch(url, { agent, headers, timeout: 30000 });
  const html = await res.text();
  if (html.toLowerCase().includes('px-captcha')) {
    throw new Error('Blocked by PerimeterX');
  }

  const m = html.match(/window\.__INITIAL_STATE__\s*=\s*({.*?});?<\/script>/s);
  if (!m) throw new Error('__INITIAL_STATE__ not found');
  const state = JSON.parse(m[1]);

  const reviews = state.bizDetailsPageProps?.reviewFeedQuery?.reviews ?? [];
  const first = reviews[0] ?? {};
  console.log(JSON.stringify({
    name: state.bizDetailsPageProps?.businessContent?.name,
    rating: state.bizDetailsPageProps?.businessContent?.rating,
    review_count: state.bizDetailsPageProps?.businessContent?.reviewCount,
    first_review: {
      id: first.id,
      author: first.author?.displayName,
      rating: first.rating,
      text: (first.comment?.text ?? '').slice(0, 200) + '…',
    },
  }, null, 2));
}

fetchBiz('blue-bottle-coffee-austin', 'biz1-abc123')
  .then(() => new Promise(r => setTimeout(r, 1500)));

SOCKS5 полезен, когда нужно туннелирование на транспортном уровне или когда HTTP-CONNECT блокируется промежуточным файрволом. Для большинства задач Yelp HTTP-шлюз на 8080 проще и достаточно быстр.

Пагинация отзывов и rate-limit pacing

Полный корпус отзывов требует пагинации. Yelp отдаёт отзывы порциями через review_feed с offset-параметром. Стратегия:

  1. Sticky-сессия на весь пагинационный цикл. Используйте -session-{biz_id} в username, чтобы все запросы для одного бизнеса шли с одного IP. Смена IP посреди пагинации выглядит подозрительно для PerimeterX.
  2. Параметр start с шагом 10. Yelp обычно отдаёт по 10 отзывов на страницу. Превышение offset ~990 часто возвращает пустой список — это мягкий лимит для анонимных пользователей.
  3. Pacing 1–2 запроса/сек на сессию. Случайный jitter 1.0–2.5 секунды между запросами снижает обнаружение. Не делайте 10 запросов/сек — даже резидентный IP получит CAPTCHA.
  4. Пауза между бизнесами. После завершения одного бизнеса — пауза 5–15 секунд и смена session-ID (новый IP).
def scrape_all_reviews(slug, max_pages=100):
    all_reviews = []
    session_id = f"{slug}-{int(time.time())}"
    for page in range(max_pages):
        start = page * 10
        data = fetch_review_feed(slug, start=start, session_id=session_id)
        reviews = data.get("reviews", [])
        if not reviews:
            break
        all_reviews.extend(reviews)
        time.sleep(random.uniform(1.2, 2.5))
    return all_reviews

Ротация User-Agent и снижение fingerprint-риска

User-Agent — не единственный фингерпринт, но самый очевидный. Правила:

  • Используйте реальные, актуальные UA. Chrome 120, Safari 17, Firefox 121. Устаревшие UA (Chrome 83) сразу подозрительны.
  • Согласованный набор заголовков. Если UA — Chrome на Windows, заголовки Sec-CH-UA, Sec-CH-UA-Platform должны совпадать. Несогласованность = флаг.
  • Ротируйте UA вместе с IP. Новый IP + новый UA на каждый бизнес — естественнее, чем один UA на 1000 IP.
  • Accept-Language соответствует гео. Для US-IP используйте en-US,en;q=0.9, не ru-RU.

Более продвинутый подход — headless-браузер (Playwright/Puppeteer) с stealth-плагинами для прохождения sensor challenge. Это медленнее (3–8 сек на страницу), но надёжнее для сайтов с агрессивным PerimeterX. Базовый requests + резидентные прокси работает для большинства публичных страниц Yelp, если темп разумный.

Типичные ошибки и edge-кейсы

  • Игнорирование _px3 cookie. Если вы не сохраняете cookies между запросами в рамках сессии, PerimeterX видит «нового» посетителя каждый раз и чаще триггерит challenge. Используйте requests.Session().
  • Слишком высокий темп. 10 запросов/сек с datacenter IP = бан за 30 секунд. Даже 5 запросов/сек с резидентного IP повышает риск. Цель — 1–2/сек.
  • Один IP на весь датасет. 10 000 страниц с одного IP = гарантированный бан. Ротация между бизнесами обязательна.
  • Парсинг HTML вместо JSON-блобов. CSS-селекторы ломаются при каждом редизайне Yelp. __INITIAL_STATE__ стабилен месяцами.
  • Игнорирование robots.txt. robots.txt Yelp запрещает часть путей. Проверяйте перед сбором.
  • Сохранение персональных данных без анонимизации. Имя автора отзыва + дата + город = персональные данные под GDPR. Храните хеш или псевдонимизируйте.

Этический скрапинг и когда предпочесть официальный API

Скрапинг публичных данных — серая зона. Юридический ландшафт: в США прецедент hiQ Labs v. LinkedIn (9th Circuit, 2022) поддержал скрапинг публично доступных данных как законный, но CFAA всё ещё применяется к «exceeding authorized access». В ЕС GDPR регулирует любые персональные данные, включая имена авторов отзывов.

Практические принципы этичного скрапинга Yelp:

  1. Собирайте только публичные страницы без логина. Данные за авторизацией — вне границ.
  2. Уважайте robots.txt. Если путь запрещён — не скрапьте.
  3. Ограничьте темп. 1–2 запроса/сек — это вежливо. 50 запросов/сек — это DoS.
  4. Анонимизируйте персональные данные. Для аналитики тональности имя автора обычно не нужно — достаточно текста и рейтинга.
  5. Предпочитайте Fusion API, где он покрывает потребность. Если вам нужны только бизнес-профили и 3 отзыва — используйте официальный API. Это легально, стабильно и не требует прокси.
  6. Не перепродавайте данные как есть. ToS Yelp запрещает редистрибуцию. Агрегированные метрики, производные инсайты — серая зона, сырая перепродажа — нарушение.

Когда Fusion API достаточно: бизнес-поиск по гео, базовые детали, 3 отзыва на бизнес, категории, часы. Когда нужен скрапинг: полный корпус отзывов (>3), фотографии в высоком разрешении, исторические изменения рейтингов, атрибуты не из API.

Подробнее о паттернах скрапинга и пагинации — в нашем гайде по веб-скрапингу и SERP-трекингу. Документация ProxyHat — на docs.proxyhat.com.

Key Takeaways

  • Публичные страницы Yelp (/biz/<slug>) отдают бизнес-профиль, рейтинг, категории, часы и ~100 отзывов без логина. Fusion API ограничен 3 отзывами.
  • PerimeterX/HUMAN — основная защита: _px3 cookie, TLS-фингерпринтинг (JA3/JA4), IP-скоринг. Datacenter-IP получают CAPTCHA после 5–20 запросов.
  • Ротационные резидентные прокси с US-гео (-country-US-city-austin) — оптимальный выбор: высокая IP-репутация и локализованные результаты.
  • Извлекайте __INITIAL_STATE__ одним regex вместо парсинга HTML — стабильнее и быстрее.
  • Pacing 1–2 запроса/сек, sticky-сессии для пагинации, ротация UA вместе с IP — снижают fingerprint-риск.
  • Этика: только публичные данные, уважение robots.txt, анонимизация персональных данных, предпочтение Fusion API где возможно.

FAQ

Можно ли скрапить Yelp без прокси?

Технически — да, первые 5–15 запросов с вашего IP пройдут. Но без ротации вы получите CAPTCHA или 403 в течение минуты, а ваш IP попадёт в репутационную базу PerimeterX. Для любого объёма выше 50 страниц прокси обязательны.

Чем отличается скрапинг от Fusion API?

Fusion API — официальный, легальный, с ключом доступа, но ограничен: 3 отзыва на бизнес, лимиты по запросам, нет фото в высоком разрешении. Скрапинг публичных страниц даёт полный корпус отзывов, но нарушает ToS и требует обхода PerimeterX.

Сколько отзывов доступно без логина?

Обычно ~100 отзывов на бизнес видны анонимно. После offset ~990 review_feed часто возвращает пустой список. Для большего объёма нужен логин — но это уже нарушает ToS и не покрывается этим гайдом.

Какой темп запросов безопасен?

1–2 запроса в секунду на сессию с jitter 1.0–2.5 сек. Между разными бизнесами — пауза 5–15 секунд и смена session-ID (новый IP). 10 запросов/сек = гарантированный бан даже с резидентных прокси.

Нужно ли использовать headless-браузер?

Для большинства публичных страниц Yelp достаточно requests + резидентные прокси + извлечение __INITIAL_STATE__. Headless (Playwright/Puppeteer со stealth-плагинами) нужен, если PerimeterX начинает требовать полноценный sensor challenge — это происходит при высоком темпе или подозрительных паттернах.

Часто задаваемые вопросы

Что такое скрапинг Yelp бизнес-листингов и отзывов?

Это программный сбор публично доступных данных со страниц Yelp — профилей бизнеса по URL вида /biz/, рейтингов, категорий, часов работы и текстов отзывов — без авторизации. В отличие от официального Fusion API, который возвращает не более 3 отзывов на бизнес, скрапинг публичных страниц позволяет собирать полный список отзывов, видимых анонимному посетителю.

Почему скрапинг Yelp важен для пользователей прокси?

Yelp использует PerimeterX/HUMAN, TLS-фингерпринтинг и IP-репутацию для блокировки автоматизированных запросов. Datacenter-IP часто получают CAPTCHA уже после нескольких запросов. Ротационные резидентные прокси с гео-таргетингом по США позволяют получать локализованные результаты и снижать риск блокировок, распределяя запросы по реальным пользовательским IP.

Какой тип прокси лучше всего подходит для скрапинга Yelp?

Лучший выбор — ротационные резидентные прокси с гео-таргетингом по США (например, user-country-US-city-austin). Резидентные IP имеют высокую репутацию у PerimeterX, а гео-таргетинг по городу даёт локализованные бизнес-результаты. Datacenter-прокси быстро блокируются. Mobile-прокси тоже работают, но обычно дороже и медленнее.

Как избежать блокировок при скрапинге Yelp?

Используйте ротационные резидентные прокси, ограничьте скорость до 1–2 запросов в секунду на сессию, ротируйте User-Agent, используйте sticky-сессии для пагинации, избегайте паттернов автоматизации и уважайте robots.txt. При появлении CAPTCHA снижайте темп и меняйте IP. Не запрашивайте данные за логином — это нарушает ToS и может подпадать под CFAA.

Легально ли скрапить публичные данные Yelp?

Сбор публично доступных данных без авторизации в США часто считается законным (прецедент hiQ v. LinkedIn), но нарушает Terms of Service Yelp. В ЕС персональные данные отзывов подпадают под GDPR. Рекомендуется предпочитать официальный Fusion API, где он покрывает ваши потребности, и консультироваться с юристом перед запуском продакшен-сбора.

Готовы начать?

Резидентные, ISP и мобильные прокси в 148+ странах. Создайте бесплатный аккаунт.

Создать бесплатный аккаунт
← Вернуться в Блог