2026年版 Best Buyの価格と在庫をスクレイピングする方法

Best Buyの公式Products APIは承認制でレート制限が厳しいため、リアルタイム価格と店舗レベル在庫はサイトから取得する必要があります。Akamai Bot Manager対策からUSレジデンシャルプロキシを使った実装まで解説します。

How to Scrape Best Buy Prices and Stock in 2026: Proxies, Selectors & Anti-Bot Workarounds

Best Buyの価格と在庫をスクレイピングする方法 2026を探しているなら、最初に理解すべきはAPIとHTMLのトレードオフです。Best Buyは公式のBest Buy Developer APIを提供していますが、利用には申請と承認が必要で、発行されたAPIキーにはリクエスト上限が設定されています。そのため、リアルタイムの価格変動や店舗ごとの在庫状況を継続的にモニタリングしたいエンジニアは、多くの場合ウェブサイト自体からデータを取得する道を選びます。

本記事では、Best Buyのスクレイピングで直面する技術的課題——Akamai Bot Managerのセンサークッキー、URLパターンとセレクター、店舗別在庫に必要なUSレジデンシャルプロキシ——を順を追って解説し、ProxyHatを使った実践的なPython実装例を示します。

Best BuyのアンチボットスタックとDatacenter IPの限界

Best BuyはAkamai Bot Managerをフロントに配置しています。このシステムはブラウザのJavaScriptエンジンを実行して「センサーデータ」を生成させ、それを_abckおよびbm_szというクッキーに格納します。リクエストごとにこのセンサーデータが検証され、人間らしくないリクエストパターンは即座にチャレンジ(403やCAPTCHA)をトリガーします。

DatacenterプロキシIPを使った場合、典型的な挙動は次のとおりです:

  • 最初の3〜5リクエストは成功する
  • 6〜10リクエスト目あたりで_abckの検証が失敗し、403が返る
  • IPがブラックリストに登録され、以降のリクエストはすべてチャレンジページにリダイレクトされる

これはDatacenter IPのASNがクラウドプロバイダー(AWS、GCP、DigitalOceanなど)に属しているため、Akamaiがボットとして分類しやすいからです。一方、USレジデンシャルプロキシはISPに登録された実際の住宅IPアドレスを使用するため、Akamaiのリスクスコアが大幅に低くなります。

URLパターンとセレクター

Best BuyのSKUページは次のパターンで構成されています:

https://www.bestbuy.com/site/<product-slug>/<sku>.p?skuId=<sku>

例えばSKU 6523493のページは https://www.bestbuy.com/site/apple-airpods-pro-2nd-generation/6523493.p?skuId=6523493 となります。スラッグ部分はSEO用の可変文字列ですが、SKU IDが一意の識別子です。

HTMLセレクター

価格とタイトルの抽出には以下のCSSセレクターが使えます:

/* 価格 */
.priceView-customer-price > div:first-child
/* 商品タイトル */
.sku-title h1
/* 在庫ステータス */
.fulfillment-fulfillment-summary

内部JSONエンドポイント

HTMLをパースする以外に、Best Buyは内部APIエンドポイントを公開しています。これらはページのJavaScriptから呼び出されるもので、より構造化されたデータを返します:

# 価格・在庫情報(skuIdとzipコードでキー付け)
https://www.bestbuy.com/pricing/v1/price?skuId=6523493&zip=60601

# 店舗別フルフィルメント
https://api.bestbuy.com/v1/products/6523493/fulfillment?zip=60601

これらのエンドポイントはskuIdzip(郵便番号)をクエリパラメータとして受け取り、該当エリアの価格と在庫状況をJSONで返します。ただし、これらのエンドポイントにもAkamaiの保護が及んでいるため、適切なプロキシとヘッダー管理が不可欠です。

店舗別在庫にUSレジデンシャルプロキシが必須な理由

Best Buyの在庫情報は店舗ごとに管理されており、ユーザーの位置情報(ZIPコード)に基づいて表示されます。つまり、シカゴの店舗の在庫を確認するには、リクエストがシカゴ周辺のIPから来ている必要があります。

ProxyHatのレジデンシャルプロキシでは、ユーザー名に国と都市を指定できます:

# シカゴのレジデンシャルIPを使用
http://user-country-US-city-chicago:pass@gate.proxyhat.com:8080

これにより、Best Buyのサーバーはリクエストをシカゴ地域のユーザーとして扱い、該当エリアの店舗在庫を返します。Datacenter IPでは地理的ターゲティングが機能せず、在庫データが不正確または空になります。

プロキシタイプの比較

プロキシタイプAkamai突破率Geoターゲティングコスト推奨用途
Datacenter低(3-5リクエストでブロック)不可APIティアの利用時のみ
Mobile国レベルモバイル専用コンテンツ
Residential (US)国・都市レベルBest Buyスクレイピングに最適

実装例:curl_cffi + ProxyHatでSKUページを取得

以下はPythonでBest BuyのSKUページを取得し、価格と在庫JSONをパースする実装例です。curl_cffiはTLSフィンガープリントをブラウザに模倣させるライブラリで、AkamaiのTLS検査を回避するのに有効です。

from curl_cffi import requests
import json

# ProxyHat USレジデンシャルプロキシ(シカゴ)
proxy_url = "http://user-country-US-city-chicago-session-zip60601:pass@gate.proxyhat.com:8080"

sku = "6523493"
zip_code = "60601"

# SKUページを取得(ブラウザTLSフィンガープリント)
headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36",
    "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
    "Accept-Language": "en-US,en;q=0.9",
}

url = f"https://www.bestbuy.com/site/product/{sku}.p?skuId={sku}"
resp = requests.get(url, headers=headers, proxies={"http": proxy_url, "https": proxy_url}, impersonate="chrome")

if resp.status_code == 200:
    # 価格エンドポイントを叩く
    price_url = f"https://www.bestbuy.com/pricing/v1/price?skuId={sku}&zip={zip_code}"
    price_resp = requests.get(price_url, headers=headers, proxies={"http": proxy_url, "https": proxy_url}, impersonate="chrome")
    
    if price_resp.status_code == 200:
        data = price_resp.json()
        print(json.dumps(data, indent=2)[:500])
    else:
        print(f"Price API returned {price_resp.status_code}")
else:
    print(f"SKU page returned {resp.status_code}")

価格エンドポイントのレスポンスは次のような構造になります(一部省略):

{
  "sku": "6523493",
  "currentPrice": 199.99,
  "regularPrice": 249.99,
  "onSale": true,
  "inStoreAvailability": true,
  "onlineAvailability": true,
  "stores": [
    {"storeId": 123, "name": "Chicago Bricktown", "stock": 4},
    {"storeId": 456, "name": "Chicago Magnolia", "stock": 0}
  ]
}

ローテーション戦略:ZIPごとのスティッキーセッションとバックオフ

Best Buyをスクレイピングする際の重要な戦略は「ZIPコードごとにスティッキーセッションを使う」ことです。異なるZIPコードの在庫を確認するたびに新しいIPに切り替えると、Akamaiのセンサーデータがリセットされ、チャレンジがトリガーされます。

ProxyHatでは-session-フラグでスティッキーセッションを維持できます:

# ZIP 60601用の固定セッション
http://user-country-US-city-chicago-session-zip60601:pass@gate.proxyhat.com:8080

# ZIP 10001(ニューヨーク)用の固定セッション
http://user-country-US-city-newyork-session-zip10001:pass@gate.proxyhat.com:8080

403/Akamaiチャレンジ時のバックオフ

403レスポンスを受け取った場合は、即座に指数バックオフを実行し、セッションを切り替えます:

import time
import random

def fetch_with_backoff(url, max_retries=5):
    for attempt in range(max_retries):
        session_id = f"retry-{attempt}-{random.randint(1000,9999)}"
        proxy = f"http://user-country-US-city-chicago-session-{session_id}:pass@gate.proxyhat.com:8080"
        
        resp = requests.get(url, headers=headers, 
                           proxies={"http": proxy, "https": proxy}, 
                           impersonate="chrome")
        
        if resp.status_code == 200:
            return resp
        elif resp.status_code == 403:
            wait = (2 ** attempt) + random.uniform(0, 1)
            print(f"403 received, backing off {wait:.1f}s")
            time.sleep(wait)
        else:
            print(f"Status {resp.status_code}, retrying...")
            time.sleep(2)
    return None

カテゴリページのページネーション

カテゴリページは?cp=2?cp=3の形式でページネーションされます。各ページには24件の商品が表示され、SKUリンクが含まれます。ページ間のリクエスト間隔は最低3〜5秒を空けることを推奨します。1ページあたり24商品、1カテゴリに50ページある場合、約1,200商品のSKUを取得できます。

倫理と利用規約

Best Buyのスクレイピングを行う際は、以下のガイドラインを遵守してください:

  • 公開カタログ・価格データのみを取得する:ログインが必要なページやアカウント固有のデータは取得しないでください。
  • チェックアウト自動化は行わない:購入プロセスの自動化はBest Buyの利用規約違反であり、CFAA(Computer Fraud and Abuse Act)に抵触する可能性があります。
  • robots.txtを確認するhttps://www.bestbuy.com/robots.txtでクロールが許可されているパスを確認してください。
  • GDPR/CCPAを尊重する:個人データは収集せず、公開されている商品情報のみを対象としてください。
  • 公式APIティアで十分な場合はそちらを使う:Best Buy Developer APIの商用ティアは1秒あたり200リクエストまで許可されており、価格比較や在庫確認の用途であれば公式APIで十分な場合があります。

ProxyHatのセットアップ

ProxyHatのレジデンシャルプロキシを使い始めるには、プランページからアカウントを作成し、ダッシュボードで認証情報を取得します。接続の詳細は公式ドキュメントで確認できます。

ProxyHatの主な特徴:

  • USレジデンシャルIPで国・都市レベルのGeoターゲティングが可能
  • スティッキーセッションで最大30分間同じIPを維持
  • HTTP(ポート8080)とSOCKS5(ポート1080)の両方をサポート
  • 200以上のロケーションに対応

詳細なユースケースについては、ウェブスクレイピングのユースケースおよびSERPトラッキングのユースケースを参照してください。

Key Takeaways

  • Best Buyの公式APIは承認制でレート制限が厳しいため、リアルタイム価格と店舗別在庫にはウェブスクレイピングが必要。
  • Akamai Bot Manager(_abckbm_szクッキー)がDatacenter IPを数リクエストでブロックするため、USレジデンシャルプロキシが必須。
  • 店舗別在庫はZIPコードに依存するため、-country-US-city-フラグで都市を指定し、-session-でスティッキーセッションを維持する。
  • curl_cffiのimpersonate="chrome"でTLSフィンガープリントを模倣し、403時は指数バックオフでリトライする。
  • 公開データのみを取得し、チェックアウト自動化やアカウント操作は行わない。公式APIティアで十分な場合はそちらを優先する。

FAQ

Best Buyの価格と在庫をスクレイピングする方法とは?

Best BuyのSKUページ(/site/-/<sku>.p?skuId=<sku>)にアクセスし、CSSセレクター(.priceView-customer-priceなど)で価格を抽出するか、内部の価格JSONエンドポイント(/pricing/v1/price?skuId=<sku>&zip=<zip>)を叩いて構造化データを取得します。Akamai Bot Managerの保護を回避するため、USレジデンシャルプロキシとTLSフィンガープリント模倣ライブラリ(curl_cffiなど)の使用が必要です。

なぜプロキシユーザーにとってBest Buyのスクレイピングが重要なのか?

Best Buyは米国最大級の家電量販店で、価格変動と在庫状況が頻繁に変わります。価格モニタリング、競合分析、転売目的の在庫アラートなど、リアルタイムデータがビジネス価値に直結するユースケースが多数あります。しかし、Akamaiの強力なアンチボット保護により、適切なプロキシ戦略なしではデータの継続的取得が不可能です。

Best Buyのスクレイピングに最適なプロキシタイプは?

USレジデンシャルプロキシが最適です。Datacenter IPはAkamaiによって3〜5リクエストでブロックされ、Mobile IPはコストが高いため大量スクレイピングに不向きです。レジデンシャルプロキシはISP登録の住宅IPを使用し、都市レベルのGeoターゲティングが可能なため、店舗別在庫の取得に必要なZIPコードベースのリクエストに対応できます。

Best Buyのスクレイピングでブロックを回避するには?

ZIPコードごとにスティッキーセッション(-session-フラグ)を維持し、リクエスト間隔を3〜5秒空け、403レスポンス時は指数バックオフでリトライします。curl_cffiでChromeのTLSフィンガープリントを模倣し、適切なUser-AgentとAccept-Languageヘッダーを設定することが重要です。また、robots.txtを確認し、公開データのみを取得してください。

始める準備はできましたか?

AIフィルタリングで148か国以上、5,000万以上のレジデンシャルIPにアクセス。

料金を見るレジデンシャルプロキシ
← ブログに戻る