2026년 Yelp 비즈니스 목록 및 리뷰 스크래핑 완전 가이드

Yelp의 공개 비즈니스 데이터와 리뷰를 수집하는 개발자 중심 가이드입니다. PerimeterX/HUMAN 봇 방어 우회, 미국 지역 residential proxy 설정, Python 및 Node.js 코드 예제를 제공합니다.

How to Scrape Yelp Business Listings and Reviews in 2026: Public Data, PerimeterX, and Production Patterns

Yelp 비즈니스 목록 및 리뷰 스크래핑: 공개 데이터의 범위와 한계

Yelp 비즈니스 목록 및 리뷰 스크래핑은 로컬 비즈니스 정보, 평점, 카테고리, 영업시간, 그리고 리뷰 텍스트를 수집하는 작업입니다. 경쟁 분석, 감성 분석, 로컬 SEO 연구, AI 학습 데이터 구축 등 다양한 목적으로 활용되지만, Yelp는 PerimeterX(현재 HUMAN Security) 기반의 강력한 봇 방어 시스템을 운영하여 무분별한 수집을 차단합니다.

⚠️ 법적 고지: 이 가이드는 Yelp의 robots.txt와 이용약관(Terms of Service)을 준수하는 공개 데이터 접근만을 다룹니다. 미국에서는 Computer Fraud and Abuse Act (CFAA)가 무단 시스템 접근을 제한하며, EU에서는 GDPR이 개인 데이터 처리를 엄격히 규제합니다. 로그인이 필요한 콘텐츠는 절대 수집하지 마십시오. 가능한 경우 Yelp Fusion API를 우선 사용하십시오.

공개 데이터 vs Fusion API: 무엇을 수집할 수 있는가?

Yelp의 비즈니스 페이지(/biz/<slug>)는 로그인 없이 접근 가능한 공개 데이터를 제공합니다. 다음 정보는 별도의 인증 없이 확인할 수 있습니다:

  • 비즈니스명, 주소, 전화번호 — 기본 프로필 정보
  • 평점 및 리뷰 수 — 별점(1~5점)과 총 리뷰 개수
  • 카테고리 및 태그 — 예: Restaurants, Mexican, Breakfast & Brunch
  • 영업시간 — 요일별 운영 시간
  • 리뷰 텍스트 — 각 리뷰의 작성자, 평점, 본문
  • 사진 메타데이터 — 썸네일 URL, 설명

Yelp는 공식 API인 Fusion API를 제공하지만, 비즈니스 상세 페이지당 최대 3개의 리뷰만 반환합니다. 이는 리뷰 데이터셋을 구축하려는 개발자에게 치명적인 제약입니다. 반면, 웹 페이지 자체에는 수백 개의 리뷰가 임베드되어 있으며, 페이지 내 __INITIAL_STATE__ JavaScript 객체나 review_feed JSON 엔드포인트를 통해 접근할 수 있습니다.

데이터 소스 리뷰 한도 인증 필요 봇 방어 적합한 용도
Fusion API 비즈니스당 3개 API Key 필요 없음 기본 비즈니스 정보
공개 웹 페이지 (/biz/) 전체 리뷰 불필요 PerimeterX 리뷰 데이터셋 구축
review_feed JSON 페이지당 ~10개 불필요 PerimeterX 페이지네이션 수집

Yelp의 봇 방어 시스템: PerimeterX/HUMAN 이해하기

Yelp는 HUMAN Security(구 PerimeterX)의 봇 방어 솔루션을 사용합니다. 이 시스템은 다음과 같은 다층 방어를 제공합니다:

1. _px3 쿠키와 센서 챌린지

PerimeterX는 방문자의 브라우저에 _px3 쿠키를 설정하고, JavaScript 기반 센서 데이터를 수집합니다. 이 센서는 마우스 움직임, 키보드 입력 패턴, 캔버스 핑거프린트, WebGL 렌더링 정보 등을 수집하여 봇과 인간을 구분합니다. 데이터센터 IP에서 요청이 들어오면 IP 평판 점수가 낮아져 몇 번의 요청 만으로 CAPTCHA 챌린지가 트리거됩니다.

2. TLS 핑거프린팅

PerimeterX는 TLS 핸드셰이크 메타데이터를 분석하여 클라이언트의 핑거프린트를 생성합니다. Python requests 라이브러리의 기본 TLS 핑거프린트는 Chrome 브라우저와 다르기 때문에, 추가 조치 없이는 쉽게 감지됩니다. curl_cffitls-client 같은 라이브러리를 사용하여 브라우저 TLS 핑거프린트를 모방할 수 있습니다.

3. CAPTCHA 및 요청 차단

데이터센터 IP에서 보통 5~10회 요청 후 PerimeterX가 CAPTCHA를 반환합니다. 이 시점에서 세션은 차단되며, 동일한 IP로 재시도해도 즉시 차단됩니다. 이것이 residential proxy가 필수적인 이유입니다.

왜 미국 지역 residential proxy가 필요한가?

Yelp는 지역별로 다른 비즈니스 검색 결과를 반환합니다. 예를 들어, 오스틴의 레스토랑을 검색할 때 미국 IP가 아닌 경우 결과가 제한되거나 다른 지역의 결과가 표시될 수 있습니다. 미국 지역 residential proxy는 두 가지 문제를 동시에 해결합니다:

  • 지역화된 결과: -country-US-city-austin 플래그로 오스틴 지역 비즈니스 데이터를 정확히 수집
  • IP 평판: 실제 ISP가 할당한 residential IP는 PerimeterX의 신뢰 점수가 높아 차단 확률이 대폭 감소
프록시 유형 IP 평판 PerimeterX 우회 비용 지역 타겟팅
Residential 높음 우수 중간 국가/도시
Datacenter 낮음 불량 낮음 제한적
Mobile 매우 높음 최상 높음 국가/도시

ProxyHat의 residential proxy는 국가 및 도시 수준의 지역 타겟팅을 지원합니다. 지원 지역 목록에서 원하는 도시를 확인할 수 있습니다.

Python으로 Yelp 리뷰 스크래핑하기: 실전 코드

다음 예제는 ProxyHat residential proxy를 통해 Yelp 비즈니스 페이지에 접근하고, __INITIAL_STATE__ 블롭에서 리뷰 데이터를 추출하는 Python 코드입니다.

import requests
import re
import json
import time
import random

# ProxyHat residential proxy - 미국 오스틴 지역, sticky session
proxy_url = "http://user-country-US-city-austin-session-yelp001:YOUR_PASSWORD@gate.proxyhat.com:8080"

proxies = {
    "http": proxy_url,
    "https": proxy_url,
}

# 브라우저와 유사한 헤더 구성
headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
    "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
    "Accept-Language": "en-US,en;q=0.9",
    "Accept-Encoding": "gzip, deflate, br",
    "Connection": "keep-alive",
    "Upgrade-Insecure-Requests": "1",
}

def scrape_yelp_biz(biz_slug, max_retries=3):
    """Yelp 비즈니스 페이지에서 리뷰 데이터를 추출합니다."""
    url = f"https://www.yelp.com/biz/{biz_slug}"

    for attempt in range(max_retries):
        try:
            response = requests.get(url, proxies=proxies, headers=headers, timeout=30)

            if response.status_code == 200:
                # __INITIAL_STATE__ 블롭 추출
                match = re.search(
                    r'__INITIAL_STATE__\s*=\s*({.*?});\s*</script>',
                    response.text,
                    re.DOTALL
                )
                if match:
                    state = json.loads(match.group(1))
                    biz_data = state.get("bizDetailsPage", {})
                    reviews = biz_data.get("reviews", [])

                    results = []
                    for r in reviews[:3]:
                        results.append({
                            "rating": r.get("rating"),
                            "text": r.get("comment", {}).get("text", "")[:200],
                            "user": r.get("user", {}).get("displayName", ""),
                            "date": r.get("localizedDate", ""),
                        })
                    return results
                else:
                    print("__INITIAL_STATE__ not found")
                    return None

            elif response.status_code == 403:
                print(f"Blocked (403). Retrying with new session...")
                # 새 세션 ID로 재시도
                proxy_url_new = proxy_url.replace(
                    "yelp001", f"yelp{random.randint(1000, 9999)}"
                )
                proxies["http"] = proxy_url_new
                proxies["https"] = proxy_url_new
                time.sleep(5)
            else:
                print(f"Status: {response.status_code}")
                time.sleep(3)

        except requests.exceptions.RequestException as e:
            print(f"Request failed: {e}")
            time.sleep(5)

    return None

# 실행
reviews = scrape_yelp_biz("tyler-taste-of-austin-austin")
if reviews:
    for r in reviews:
        print(f"[{r['rating']}★] {r['user']} ({r['date']}): {r['text'][:80]}...")

이 코드는 gate.proxyhat.com:8080을 통해 미국 오스틴 지역 residential IP로 접근합니다. -session-yelp001 플래그는 sticky session을 유지하여, 동일 IP로 여러 페이지를 순차적으로 요청할 수 있습니다.

Node.js에서 SOCKS5 프록시로 Yelp 스크래핑하기

Node.js 환경에서는 SOCKS5 프로토콜을 사용하여 ProxyHat에 연결할 수 있습니다. SOCKS5는 TCP 레벨에서 작동하여 HTTP 프록시보다 오버헤드가 적습니다.

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

// ProxyHat SOCKS5 - 미국 지역, sticky session
const proxyAgent = new SocksProxyAgent(
  'socks5://user-country-US-session-yelp002:YOUR_PASSWORD@gate.proxyhat.com:1080'
);

async function scrapeYelpReviews(bizSlug) {
  const url = `https://www.yelp.com/biz/${bizSlug}`;

  const headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
    'Accept-Language': 'en-US,en;q=0.9',
    'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
  };

  try {
    const res = await fetch(url, { agent: proxyAgent, headers, timeout: 30000 });
    const html = await res.text();

    // __INITIAL_STATE__ 추출
    const match = html.match(/__INITIAL_STATE__\s*=\s*({.*?});\s*<\/script>/s);
    if (match) {
      const state = JSON.parse(match[1]);
      const reviews = state.bizDetailsPage?.reviews || [];

      const truncated = reviews.slice(0, 3).map(r => ({
        rating: r.rating,
        text: r.comment?.text?.substring(0, 200) || '',
        user: r.user?.displayName || '',
        date: r.localizedDate || '',
      }));

      console.log(`Found ${reviews.length} reviews`);
      truncated.forEach(r => {
        console.log(`[${r.rating}★] ${r.user}: ${r.text.substring(0, 80)}...`);
      });

      return truncated;
    }
    console.log('__INITIAL_STATE__ not found');
    return null;
  } catch (err) {
    console.error('Scrape failed:', err.message);
    return null;
  }
}

scrapeYelpReviews('tyler-taste-of-austin-austin');

페이지네이션, 속도 제한, 세션 관리

페이지네이션 전략

Yelp 비즈니스 페이지는 초기 로딩 시 약 10개 리뷰를 렌더링하며, 추가 리뷰는 review_feed JSON 엔드포인트를 통해 비동기로 로드됩니다. URL 패턴은 다음과 같습니다:

https://www.yelp.com/biz/{slug}/review_feed?rl=&q=&sort_by=&start=10

start 파라미터를 10씩 증가시키며 페이지네이션을 수행합니다. 각 요청 사이에 3~5초의 지연을 두어 자연스러운 브라우징 패턴을 모방합니다.

속도 제한 및 요청 간격

PerimeterX는 요청 패턴을 분석하여 봇을 탐지합니다. 다음 간격을 권장합니다:

  • 첫 페이지 로드: 3초 대기
  • review_feed 요청: 4~6초 랜덤 대기
  • 비즈니스 간 이동: 5~8초 랜덤 대기
  • 차단 감지 시: 30초 대기 후 새 세션으로 재시도

Sticky session으로 연속성 유지

동일한 비즈니스의 여러 리뷰 페이지를 수집할 때는 sticky session을 사용해야 합니다. 세션 ID를 유지하면 같은 IP가 유지되어, PerimeterX가 갑작스러운 IP 변경을 의심하지 않습니다. 비즈니스가 바뀔 때 새 세션 ID를 할당하는 것이 안전합니다.

# 비즈니스 A - 동일 세션 유지
proxy_a = "http://user-country-US-city-austin-session-biz-001:PASS@gate.proxyhat.com:8080"

# 비즈니스 B - 새 세션 할당
proxy_b = "http://user-country-US-city-austin-session-biz-002:PASS@gate.proxyhat.com:8080"

User-Agent 회전으로 핑거프린트 위험 감소

단일 User-Agent를 사용하면 패턴이 감지되기 쉽습니다. 최신 Chrome, Firefox, Safari UA 문자열을 번갈아 사용하되, TLS 핑거프린트와 일치하는 UA를 선택하는 것이 중요합니다.

import random

user_agents = [
    "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",
    "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:121.0) Gecko/20100101 Firefox/121.0",
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.2 Safari/605.1.15",
]

headers["User-Agent"] = random.choice(user_agents)

ProxyHat 설정 및 프록시 구성

ProxyHat에서 Yelp 스크래핑용 프록시를 설정하는 방법은 간단합니다. 프라이싱 페이지에서 residential proxy 플랜을 선택한 후, 대시보드에서 인증 정보를 확인합니다.

핵심 연결 정보:

  • 게이트웨이: gate.proxyhat.com
  • HTTP 포트: 8080
  • SOCKS5 포트: 1080
  • 지역 타겟팅: 사용자 이름에 -country-US-city-austin 형식으로 추가
  • Sticky session: -session-{id} 형식으로 추가

자세한 설정 방법은 ProxyHat 문서를 참조하세요. 웹 스크래핑 사용 사례는 웹 스크래핑 사용 사례 페이지에서, SERP 추적은 SERP 추적 페이지에서 확인할 수 있습니다.

윤리적 스크래핑: 공식 API와 웹 스크래핑의 선택

Yelp 스크래핑을 시작하기 전에 다음 사항을 반드시 고려해야 합니다:

robots.txt 준수

Yelp의 robots.txt를 확인하여 수집이 허용된 경로인지 확인하세요. 검색 엔진 크롤링이 허용된 공개 페이지는 일반적으로 접근이 가능하지만, robots.txt에서 명시적으로 차단된 경로는 수집하지 않아야 합니다.

개인 데이터와 GDPR

Yelp 리뷰에는 사용자 이름, 프로필 사진, 위치 정보 등 개인 데이터가 포함됩니다. EU 사용자의 데이터를 수집하는 경우 GDPR 제6조에 따라 합법적 근거가 필요합니다. 리뷰 텍스트 자체는 공개적으로 게시된 것이지만, 데이터를 식별 가능한 형태로 저장하거나 재배포하는 것은 별도의 법적 검토가 필요합니다.

로그인이 필요한 콘텐츠

이 가이드는 로그인 없이 접근 가능한 공개 데이터만을 다룹니다. Yelp 계정으로 로그인해야만 볼 수 있는 콘텐츠(예: 친구의 비공개 리뷰, 메시지, 북마크)는 수집하지 마십시오. 이는 CFAA 위반의 소지가 있습니다.

공식 Fusion API를 먼저 고려하라

필요한 데이터가 비즈니스 기본 정보와 3개 이하의 리뷰로 충분하다면, Fusion API를 사용하는 것이 가장 안전하고 안정적인 방법입니다. API는 봇 방어 시스템이 없으며, 명확한 라이선스 조건과 속도 제한을 제공합니다. 웹 스크래핑은 API가 요구를 충족하지 못할 때만 고려해야 합니다.

기준 Fusion API 웹 스크래핑
리뷰 수 비즈니스당 3개 전체
안정성 높음 (99.9% uptime) 변동적
법적 리스크 낮음 중간~높음
비용 API 플랜 비용 프록시 + 인프라
봇 방어 없음 PerimeterX

Key Takeaways

  • 공개 데이터 우선: Yelp 비즈니스 페이지의 __INITIAL_STATE__review_feed JSON에서 리뷰 데이터를 추출할 수 있지만, 로그인이 필요한 콘텐츠는 수집하지 마십시오.
  • Residential proxy 필수: 데이터센터 IP는 PerimeterX에 의해 5~10회 요청 내 차단됩니다. 미국 지역 residential proxy로 IP 평판을 높이고 지역화된 결과를 얻으세요.
  • Sticky session으로 연속성 유지: 동일 비즈니스의 여러 리뷰 페이지를 수집할 때는 같은 세션 ID를 사용하고, 비즈니스가 바뀔 때 새 세션을 할당하세요.
  • 요청 간격 준수: 페이지당 3~5초, 비즈니스 간 5~8초의 랜덤 대기를 적용하여 자연스러운 패턴을 유지하세요.
  • Fusion API 먼저 고려: 3개 리뷰로 충분하다면 공식 API를 사용하는 것이 법적, 기술적으로 가장 안전합니다.
  • TLS 핑거프린트: requests 라이브러리의 기본 TLS 핑거프린트는 Chrome과 다릅니다. curl_cffi 등으로 브라우저 핑거프린트를 모방하는 것을 고려하세요.

FAQ

Q: Yelp 비즈니스 목록 및 리뷰 스크래핑이란 무엇인가요?
A: Yelp의 공개 비즈니스 페이지에서 비즈니스 정보(이름, 주소, 평점, 카테고리, 영업시간)와 리뷰 텍스트를 프로그래밍 방식으로 수집하는 작업입니다. 공식 Fusion API는 비즈니스당 최대 3개 리뷰만 반환하므로, 전체 리뷰 데이터셋이 필요한 경우 웹 스크래핑을 고려하게 됩니다.

Q: Yelp 스크래핑 시 어떤 프록시 유형이 가장 적합한가요?
A: 미국 지역 residential proxy가 가장 적합합니다. 데이터센터 IP는 PerimeterX/HUMAN의 IP 평판 시스템에 의해 5~10회 요청 내 차단되지만, 실제 ISP가 할당한 residential IP는 신뢰 점수가 높아 차단 확률이 크게 낮아집니다. 지역 타겟팅(-country-US-city-austin)으로 현지화된 검색 결과도 얻을 수 있습니다.

Q: PerimeterX 차단을 피하려면 어떻게 해야 하나요?
A: residential proxy 사용, 브라우저와 유사한 헤더 구성, User-Agent 회전, 3~5초 요청 간격, sticky session 유지, 그리고 TLS 핑거프린트 모방(curl_cffi 등)을 조합해야 합니다. 단일 기법만으로는 충분하지 않으며, 다층 방어가 필요합니다.

Q: Yelp Fusion API와 웹 스크래핑 중 어떤 것을 선택해야 하나요?
A: 비즈니스당 3개 이하의 리뷰로 충분하고 기본 비즈니스 정보만 필요하다면 Fusion API를 사용하세요. 전체 리뷰 데이터셋이 필요한 경우에만 웹 스크래핑을 고려하되, Yelp ToS와 GDPR/CFAA를 반드시 준수해야 합니다.

Q: Yelp 리뷰의 개인 데이터는 어떻게 처리해야 하나요?
A: 리뷰 작성자의 이름, 사진, 위치 정보는 개인 데이터입니다. EU 사용자 데이터의 경우 GDPR이 적용되며, 식별 가능한 형태로 저장하거나 재배포하려면 합법적 근거가 필요합니다. 리뷰 텍스트만 익명화하여 저장하는 것을 권장합니다.

시작할 준비가 되셨나요?

AI 필터링으로 148개국 이상에서 5천만 개 이상의 레지덴셜 IP에 액세스하세요.

가격 보기레지덴셜 프록시
← 블로그로 돌아가기