2026年版:Yelpのビジネスリスティングとレビューをスクレイピングする方法

Yelpの公開ビジネスデータとレビューをスクレイピングする方法を解説。PerimeterX対策、住宅プロキシの活用、Python/Node.jsのコード例、ページネーション戦略まで網羅した開発者向け実践ガイドです。

How to Scrape Yelp Business Listings and Reviews in 2026: Public Data, PerimeterX, and Proxies
この記事の内容

Yelpのビジネスリスティングとレビューのスクレイピング:2026年の実践ガイド

法的注意事項:本記事は公開データへのアクセスのみを対象としています。Yelpの利用規約を遵守し、米国ではComputer Fraud and Abuse Act(CFAA)、EUではGDPRに準拠してください。ログインが必要なコンテンツのスクレイピングは推奨しません。

Yelpのビジネスリスティングとレビューのスクレイピングは、ローカルビジネスデータセットを構築する開発者にとって重要な技術です。2026年現在、YelpはPerimeterX(現HUMAN)による強力なボット検知システムを運用しており、データセンタープロキシからのリクエストはわずか5〜10回でブロックされるのが一般的です。本ガイドでは、公開データへの合法的なアクセス方法、PerimeterXの仕組み、回転住宅プロキシを用いた実践的なスクレイピング手法を解説します。

公開データとFusion APIの制限

Yelpには公式のFusion APIが用意されていますが、無料プランでは各ビジネスにつき3件のレビューしか取得できません。一方、Webページ上では以下のデータがログインなしで公開されています:

  • ビジネス名、住所、電話番号(/biz/<slug>ページ)
  • 評価(星の数)とレビュー総数
  • カテゴリ、営業時間、価格帯
  • レビュー本文、投稿者名、投稿日付、役に立った数
  • 写真のURL

Fusion APIの詳細についてはYelp Fusion API公式ドキュメントを参照してください。APIが要件を満たす場合は、スクレイピングよりもAPIの使用を優先すべきです。

Fusion API vs スクレイピングの比較

項目Fusion APIWebスクレイピング
レビュー取得数最大3件/ビジネス全レビュー(ページネーション)
認証APIキー必須不要(公開ページ)
レート制限5000リクエスト/日プロキシで拡張可能
データの鮮度API応答依存リアルタイム
利用規約リスク低(公式)中(ToS確認必須)

Yelpのアンチボット防御:PerimeterX/HUMAN

YelpはPerimeterX(現在はHUMAN Securityが提供)を利用してボットトラフィックを検知しています。主な防御メカニズムは以下の通りです:

PerimeterXは_px3というCookieを発行し、ブラウザの「センサーデータ」(マウス動作、キーボード入力タイミング、デバイス指纹など)を収集します。このデータが人間らしいパターンと一致しない場合、CAPTCHAページにリダイレクトされます。

TLS指纹

PerimeterXはTLSハンドシェイクの指纹も検査します。Pythonのrequestsライブラリが使用するTLSスタックは、ChromeやFirefoxのそれと異なるため、ボットとして検知される可能性があります。ProxyHatドキュメントで推奨されているTLS指纹の偽装手法を検討してください。

IPレピュテーションスコアリング

データセンターIP(AWS、GCP、Azureなど)からのリクエストは、IPレピュテーションが低いため即座にフラグ付けされます。住宅プロキシを使用することで、実際のISPに割り当てられたIPアドレスからのアクセスとして扱われます。

なぜ回転住宅プロキシが必要なのか

Yelpのスクレイピングに住宅プロキシが必須な理由は3つあります:

  1. IPレピュテーション:データセンターIPはPerimeterXによって即座にブロックされます。住宅IPは実際のISPに登録されているため、検知リスクが大幅に低下します。
  2. 地理的ターゲティング:Yelpの検索結果は位置に依存します。-country-US-city-austinのようなジオターゲティングフラグを使用することで、オースティン周辺のローカルビジネス結果を取得できます。
  3. 回転によるレート制限回避:リクエストごとにIPを回転させることで、単一IPあたりのリクエスト数を低く保ち、レート制限トリガーを回避できます。

ProxyHatの住宅プロキシは99.9%の稼働率100の同時セッションをサポートしており、Yelpスクレイピングに適しています。ProxyHatの料金プラン利用可能なロケーションを確認してください。

実装例:PythonでYelpビジネスページをスクレイピング

以下の例では、ProxyHatの住宅プロキシを使用してYelpビジネスページにアクセスし、埋め込まれた__INITIAL_STATE__JSONブロブからビジネスデータとレビューを抽出します。

import requests
import json
import re
import time
import random

# ProxyHat residential proxy with US geo-targeting
# ジオターゲティングとスティッキーセッションを設定
proxy_url = (
    "http://user-country-US-city-austin-session-yelp01:"
    "PASSWORD@gate.proxyhat.com:8080"
)

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

# Rotating User-Agents to lower fingerprint risk
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 (X11; Linux x86_64) AppleWebKit/537.36 "
    "(KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
]

headers = {
    "User-Agent": random.choice(user_agents),
    "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
    "Accept-Language": "en-US,en;q=0.9",
    "Referer": "https://www.yelp.com/",
}

def scrape_yelp_biz(biz_slug, max_retries=3):
    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:
                # Extract __INITIAL_STATE__ blob
                match = re.search(
                    r'__INITIAL_STATE__\s*=\s*({.*?});',
                    response.text,
                    re.DOTALL
                )
                if match:
                    state = json.loads(match.group(1))
                    biz = state.get(
                        "bizDetailsPageProps", {}
                    ).get("bizResponse", {})
                    
                    # Parse truncated review object
                    reviews = biz.get("reviews", [])[:3]
                    result = {
                        "name": biz.get("name", ""),
                        "rating": biz.get("rating", 0),
                        "review_count": biz.get("reviewCount", 0),
                        "categories": [
                            c.get("title", "")
                            for c in biz.get("categories", [])
                        ],
                        "reviews": [
                            {
                                "text": r.get("comment", {}).get("text", "")[:200],
                                "rating": r.get("rating", 0),
                                "author": r.get("author", {}).get("name", ""),
                            }
                            for r in reviews
                        ],
                    }
                    return result
            elif response.status_code == 403:
                print(f"Blocked (403), retrying... attempt {attempt + 1}")
                time.sleep(random.uniform(5, 15))
            else:
                print(f"Status {response.status_code}")
                time.sleep(2)
        except Exception as e:
            print(f"Error: {e}")
            time.sleep(5)
    
    return None

# Example usage
result = scrape_yelp_biz("some-business-austin")
if result:
    print(json.dumps(result, indent=2, ensure_ascii=False))

このコードは__INITIAL_STATE__からビジネス名、評価、レビュー総数、カテゴリ、および最初の3件のレビュー(テキストは200文字で切り詰め)を抽出します。スティッキーセッション(-session-yelp01)を使用することで、ページネーション時のIP一貫性を保ちます。

実装例:Node.jsでSOCKS5プロキシを使用

Node.js環境では、SOCKS5プロキシ(ポート1080)を使用してYelpにアクセスできます。

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

// ProxyHat SOCKS5 proxy with US geo-targeting
const agent = new SocksProxyAgent(
  'socks5://user-country-US-city-austin-session-yelp02:' +
  'PASSWORD@gate.proxyhat.com:1080'
);

async function scrapeYelpBusiness(slug) {
  const url = `https://www.yelp.com/biz/${slug}`;
  
  const response = await fetch(url, {
    agent,
    headers: {
      'User-Agent': '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',
      'Accept': 'text/html,application/xhtml+xml',
      'Accept-Language': 'en-US,en;q=0.9',
      'Referer': 'https://www.yelp.com/',
    },
  });
  
  if (!response.ok) {
    throw new Error(`HTTP ${response.status}`);
  }
  
  const html = await response.text();
  const match = html.match(/__INITIAL_STATE__\s*=\s*({.*?});/s);
  
  if (match) {
    const state = JSON.parse(match[1]);
    const biz = state?.bizDetailsPageProps?.bizResponse || {};
    const reviews = (biz.reviews || []).slice(0, 3);
    
    return {
      name: biz.name || '',
      rating: biz.rating || 0,
      reviewCount: biz.reviewCount || 0,
      reviews: reviews.map(r => ({
        text: (r.comment?.text || '').slice(0, 200),
        rating: r.rating || 0,
        author: r.author?.name || '',
      })),
    };
  }
  
  return null;
}

// Example
scrapeYelpBusiness('some-business-austin')
  .then(data => console.log(JSON.stringify(data, null, 2)))
  .catch(err => console.error(err));

ページネーションとレート制限のペーシング

Yelpのレビューはページごとに表示され、URLパラメータstart=20start=40などでページネーションできます。ただし、同じIPから短時間に多数のページをリクエストするとPerimeterXがトリガーされます。

推奨されるペーシング戦略

  • リクエスト間隔:各リクエストの間に3〜8秒のランダムな遅延を挿入します。一定間隔ではなくランダム化が重要です。
  • セッション切り替え:10〜20リクエストごとにスティッキーセッションIDを変更し、新しいIPに切り替えます。
  • ジオターゲティングの維持:セッションを切り替えても-country-USフラグは維持し、一貫した地理的コンテキストを保ちます。
  • User-Agentの回転:5〜10リクエストごとにUser-Agentを切り替え、ブラウザ指纹の多様性を確保します。
# Pagination with rate-limit pacing
import time
import random

def scrape_all_reviews(biz_slug, max_pages=10):
    all_reviews = []
    session_counter = 0
    
    for page in range(max_pages):
        start = page * 20
        session_id = f"yelp-page-{page // 5}"
        
        proxy_url = (
            f"http://user-country-US-city-austin-"
            f"session-{session_id}:"
            f"PASSWORD@gate.proxyhat.com:8080"
        )
        
        url = f"https://www.yelp.com/biz/{biz_slug}?start={start}"
        # ... fetch and parse ...
        
        # Random delay between 3-8 seconds
        delay = random.uniform(3, 8)
        time.sleep(delay)
        session_counter += 1
        
        # Rotate session every 5 pages
        if session_counter >= 5:
            session_counter = 0
    
    return all_reviews

よくある失敗とエッジケース

1. CAPTCHAループ

データセンターIPを使用すると、最初のリクエストでCAPTCHAページにリダイレクトされることがあります。これは_px3Cookieが発行されていないことを意味します。解決策は住宅プロキシに切り替えることです。

2. レビューの動的読み込み

Yelpは一部のレビューをJavaScriptで動的に読み込みます。__INITIAL_STATE__には最初の数件のレビューのみ含まれ、追加のレビューは/review_feedエンドポイントから取得する必要があります。

3. スティッキーセッションの切り替えタイミング

同じセッションIDを長期間使用すると、そのIPがPerimeterXにフラグ付けされる可能性があります。10〜20リクエストごとにセッションを切り替えることを推奨します。

4. robots.txtの確認

スクレイピングを開始する前に、必ずYelpのrobots.txtを確認し、クロールが許可されているパスかどうかを検証してください。

倫理的スクレイピングと公式APIの優先

スクレイピングは強力なツールですが、責任を持って使用する必要があります。以下のガイドラインに従ってください:

  • 公式APIを優先:Fusion APIが要件を満たす場合は、スクレイピングではなくAPIを使用してください。APIは安定しており、ToSに準拠しています。
  • 個人情報の取り扱い:レビュー投稿者の名前や写真は個人データに該当する可能性があります。GDPR下では、個人データの処理には法的根拠が必要です。
  • ログイン壁のコンテンツ:ログインが必要なコンテンツ(友達のレビューやプライベートメッセージなど)のスクレイピングは避けてください。
  • サーバーへの配慮:適切なレート制限を設定し、Yelpのサーバーに過度な負荷をかけないようにしてください。
  • データの利用目的:取得したデータをYelpの競合サービスの構築に使用しないでください。これは多くのプラットフォームのToSで明示的に禁止されています。

ウェブスクレイピングのベストプラクティスについては、ProxyHatのウェブスクレイピングユースケースも参照してください。SERP追跡についての詳細はSERPトラッキングページをご覧ください。

Key Takeaways

  • Yelpの公開ページにはビジネスプロファイル、評価、レビュー本文がログインなしでアクセス可能。Fusion APIは3件のレビューに制限。
  • PerimeterX/HUMANは_px3 Cookie、TLS指纹、IPレピュテーションでボットを検知。データセンターIPは5〜10回でブロック。
  • 回転住宅プロキシ(USジオターゲティング付き)がYelpスクレイピングに必須。ProxyHatはgate.proxyhat.com:8080(HTTP)または:1080(SOCKS5)で接続。
  • ページネーション時は3〜8秒のランダム遅延、5ページごとのセッション切り替え、User-Agent回転で指纹リスクを低減。
  • 倫理的スクレイピングを徹底:robots.txtを確認、個人情報を尊重、公式APIを優先。

ProxyHatの住宅プロキシを使えば、Yelpの公開データに安定してアクセスできます。料金プランを確認し、ProxyHatドキュメントで詳細な設定方法を参照してください。

よくある質問

Yelpのビジネスリスティングとレビューのスクレイピングとは何ですか?

Yelpの公開ビジネスページ(/biz/)から、ビジネス名、住所、評価、カテゴリ、営業時間、レビュー本文などの公開データをプログラム的に取得する手法です。Fusion APIでは3件のレビューしか取得できないため、全レビューを取得するにはWebスクレイピングが必要になる場合があります。ただし、Yelpの利用規約を遵守し、公開データのみを対象とする必要があります。

なぜYelpのスクレイピングにプロキシが必要なのですか?

YelpはPerimeterX(HUMAN)によるアンチボットシステムを運用しており、データセンターIPからのリクエストを5〜10回でブロックします。住宅プロキシを使用することで、実際のISPに登録されたIPアドレスからのアクセスとして扱われ、IPレピュテーションスコアリングを回避できます。また、USジオターゲティングによりローカルビジネス結果を正確に取得できます。

Yelpのスクレイピングに最適なプロキシタイプは何ですか?

回転住宅プロキシが最適です。データセンタープロキシはPerimeterXによって即座にブロックされます。住宅プロキシは実際のISP IPアドレスを使用するため検知リスクが低く、USジオターゲティング(-country-US-city-austinなど)でローカル検索結果を取得できます。モバイルプロキシも有効ですがコストが高いため、住宅プロキシが費用対効果のバランスが最も良い選択肢です。

Yelpのスクレイピングでブロックを回避するにはどうすればよいですか?

ブロックを回避するには以下の対策を組み合わせてください:回転住宅プロキシの使用、リクエスト間に3〜8秒のランダム遅延、10〜20リクエストごとのセッション切り替え、User-Agentの回転、TLS指纹の偽装、robots.txtの遵守。また、__INITIAL_STATE__ブロブからデータを抽出することで、JavaScriptレンダリングを回避できます。

スクレイピング中にプロキシがブロックされていませんか?

無料のプロキシチェックを実行 — ブロック率・速度・匿名性を数秒で確認。登録不要。

プロキシを無料でチェック
← ブログに戻る