[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"blog-post-ja-binance-api-scraping-proxy":3},{"success":4,"payload":5,"related":62,"errors":126},true,{"id":6,"slug":7,"title":8,"excerpt":9,"body_html":10,"meta_title":11,"meta_description":12,"canonical_url":13,"canonical_override":14,"og_title":11,"og_description":12,"og_image_url":15,"faq_json":16,"key_takeaways":14,"allow_index":29,"noindex_google_only":4,"allow_follow":4,"published_at":30,"updated_at":30,"content_updated_at":31,"featured_image_url":32,"featured_image_alt":33,"card_image_url":34,"reading_time_minutes":35,"author":36,"categories":40,"tags":47,"alternates":48,"locale_paths":55,"views":61},194,"binance-api-scraping-proxy","Binance REST APIをプロキシでスクレイピングする完全ガイド","Binanceの公開マーケットデータREST APIをプロキシ経由で大規模収集する方法を、エンドポイント別のウェイト制限、IPローテーション、リトライ戦略まで含めて解説します。","\u003Cp>\u003Cstrong>注意（コンプライアンス）:\u003C\u002Fstrong> 本記事はBinanceの\u003Cstrong>公開マーケットデータ\u003C\u002Fstrong>の収集のみを対象とします。API利用規約（\u003Ca href=\"https:\u002F\u002Fwww.binance.com\u002Fen\u002Fterms\" rel=\"noopener noreferrer\">Binance Terms of Service\u003C\u002Fa>）を遵守し、ウェイト制限を尊重し、公式APIアクセスが義務付けられる場合はそちらを優先してください。認証が必要なエンドポイントやユーザーデータには触れません。\u003C\u002Fp>\n\n\u003Cp>仮想通貨の価格・オーダーブック・ティッカーデータを大規模に収集するquant developerやcrypto data engineerにとって、Binance REST APIのプロキシ経由スクレイピング方法の理解は必須です。Binanceは世界最大級の取引所であり、高品質な公開マーケットデータをREST APIで提供していますが、IPごとのウェイトベースレート制限が厳しく、対策なしでは数分でIPバンを受ける可能性があります。本記事では、\u003Ca href=\"https:\u002F\u002Fwww.binance.com\u002Fen\u002Fsupport\u002Ffaq\u002Fintroduction-to-binance-api-documents-360036820911\" rel=\"noopener noreferrer\">Binance API Documentation\u003C\u002Fa>に基づき、エンドポイント別のウェイト、プロキシローテーション戦略、本番運用向けのコード例を解説します。\u003C\u002Fp>\n\n\u003Ch2>Binance REST APIのプロキシ経由スクレイピング方法：基本概念\u003C\u002Fh2>\n\n\u003Cp>Binance REST API（\u003Ccode>https:\u002F\u002Fapi.binance.com\u003C\u002Fcode>）は、認証不要で公開マーケットデータにアクセスできる複数のエンドポイントを提供しています。ただし、すべてのリクエストには「ウェイト」という概念が割り当てられており、IPごとに1分あたり約6,000ウェイトまでという制限があります。この制限を超えるとHTTP 429（Too Many Requests）が返り、継続するとHTTP 418でIPが一時的にBANされます。\u003C\u002Fp>\n\n\u003Cp>プロキシを使ってリクエスト元IPを分散させることで、ウェイト予算を複数IPに分割し、実質的なスループットを向上させることができます。ProxyHatのレジデンシャルプロキシ（\u003Ccode>gate.proxyhat.com:8080\u003C\u002Fcode>）を使えば、リクエストごとにIPをローテーションし、Binance.comとBinance.USの地理的分割（HTTP 451）もバイパスできます。\u003C\u002Fp>\n\n\u003Ch2>主要エンドポイントとウェイト\u003C\u002Fh2>\n\n\u003Cp>Binanceの公開マーケットデータエンドポイントのうち、本記事で扱う4つを以下の表にまとめます。ウェイト値は\u003Ca href=\"https:\u002F\u002Fdevelopers.binance.com\u002Fdocs\u002Fbinance-spot-api-docs\u002Frest-api\" rel=\"noopener noreferrer\">Binance Spot API Documentation\u003C\u002Fa>に基づきます。\u003C\u002Fp>\n\n\u003Ctable>\n\u003Cthead>\n\u003Ctr>\u003Cth>エンドポイント\u003C\u002Fth>\u003Cth>用途\u003C\u002Fth>\u003Cth>ウェイト\u003C\u002Fth>\u003Cth>備考\u003C\u002Fth>\u003C\u002Ftr>\n\u003C\u002Fthead>\n\u003Ctbody>\n\u003Ctr>\u003Ctd>\u003Ccode>GET \u002Fapi\u002Fv3\u002Fklines\u003C\u002Fcode>\u003C\u002Ftd>\u003Ctd>ローソク足（OHLCV）\u003C\u002Ftd>\u003Ctd>1〜2\u003C\u002Ftd>\u003Ctd>limit パラメータで変動（1500まで）\u003C\u002Ftd>\u003C\u002Ftr>\n\u003Ctr>\u003Ctd>\u003Ccode>GET \u002Fapi\u002Fv3\u002Fdepth\u003C\u002Fcode>\u003C\u002Ftd>\u003Ctd>オーダーブック\u003C\u002Ftd>\u003Ctd>5〜20\u003C\u002Ftd>\u003Ctd>limit=5000 でウェイト20、高コスト\u003C\u002Ftd>\u003C\u002Ftr>\n\u003Ctr>\u003Ctd>\u003Ccode>GET \u002Fapi\u002Fv3\u002Fticker\u002F24hr\u003C\u002Fcode>\u003C\u002Ftd>\u003Ctd>24時間ティッカー\u003C\u002Ftd>\u003Ctd>1〜80\u003C\u002Ftd>\u003Ctd>全シンボル取得でウェイト80\u003C\u002Ftd>\u003C\u002Ftr>\n\u003Ctr>\u003Ctd>\u003Ccode>GET \u002Fapi\u002Fv3\u002Fticker\u002Fprice\u003C\u002Fcode>\u003C\u002Ftd>\u003Ctd>現在価格\u003C\u002Ftd>\u003Ctd>1〜2\u003C\u002Ftd>\u003Ctd>全シンボルでウェイト2\u003C\u002Ftd>\u003C\u002Ftr>\n\u003C\u002Ftbody>\n\u003C\u002Ftable>\n\n\u003Cp>すべてのレスポンスには \u003Ccode>X-MBX-USED-WEIGHT-1M\u003C\u002Fcode> ヘッダーが含まれており、直近1分間に消費した累計ウェイトを確認できます。この値を監視することで、429に到達する前にスロットリングできます。\u003C\u002Fp>\n\n\u003Ch2>ウェイトベースレート制限の仕組みとIPバンの危険性\u003C\u002Fh2>\n\n\u003Cp>Binanceのレート制限は単純な「リクエスト数」ではなく「ウェイトの合計」で管理されています。IPごとに1分あたり約6,000ウェイトが上限です。\u003C\u002Fp>\n\n\u003Cul>\n\u003Cli>\u003Cstrong>HTTP 429:\u003C\u002Fstrong> ウェイト上限超過時。\u003Ccode>Retry-After\u003C\u002Fcode> ヘッダーで待機秒数が指定される。\u003C\u002Fli>\n\u003Cli>\u003Cstrong>HTTP 418:\u003C\u002Fstrong> 429後も継続リクエストを続けた場合のIP自動BAN。通常2分〜数日。\u003C\u002Fli>\n\u003Cli>\u003Cstrong>HTTP 451:\u003C\u002Fstrong> 地理的制限（Binance.USエリアからのBinance.comアクセスなど）。\u003C\u002Fli>\n\u003C\u002Ful>\n\n\u003Cp>たとえば \u003Ccode>\u002Fapi\u002Fv3\u002Fdepth?limit=5000\u003C\u002Fcode> はウェイト20を消費します。1IPで連続ポーリングすると、6,000 ÷ 20 = 300リクエスト\u002F分で上限に達します。5秒間隔でも1分あたり12リクエストでウェイト240ですが、複数シンボルを同時にポーリングすればあっという間に上限に到達します。これがプロキシによるIP分散が不可欠な理由です。\u003C\u002Fp>\n\n\u003Ch2>プロキシローテーション戦略：レジデンシャル vs データセンター\u003C\u002Fh2>\n\n\u003Cp>Binanceはデータセン�ーIPを検出しやすく、制限を厳しくかける傾向があります。レジデンシャルプロキシはISP発の本物の住宅IPを使用するため、検出リスクが低く、大規模収集に適しています。\u003C\u002Fp>\n\n\u003Ctable>\n\u003Cthead>\n\u003Ctr>\u003Cth>プロキシタイプ\u003C\u002Fth>\u003Cth>検出リスク\u003C\u002Fth>\u003Cth>スループット\u003C\u002Fth>\u003Cth>用途\u003C\u002Fth>\u003C\u002Ftr>\n\u003C\u002Fthead>\n\u003Ctbody>\n\u003Ctr>\u003Ctd>レジデンシャル\u003C\u002Ftd>\u003Ctd>低\u003C\u002Ftd>\u003Ctd>中〜高\u003C\u002Ftd>\u003Ctd>大規模マーケットデータ収集\u003C\u002Ftd>\u003C\u002Ftr>\n\u003Ctr>\u003Ctd>モバイル\u003C\u002Ftd>\u003Ctd>極低\u003C\u002Ftd>\u003Ctd>中\u003C\u002Ftd>\u003Ctd>最高のステルス性が必要な場合\u003C\u002Ftd>\u003C\u002Ftr>\n\u003Ctr>\u003Ctd>データセンター\u003C\u002Ftd>\u003Ctd>高\u003C\u002Ftd>\u003Ctd>高\u003C\u002Ftd>\u003Ctd>軽量・低ウェイトのエンドポイント\u003C\u002Ftd>\u003C\u002Ftr>\n\u003C\u002Ftbody>\n\u003C\u002Ftable>\n\n\u003Cp>ProxyHatのレジデンシャルプロキシは \u003Ccode>gate.proxyhat.com:8080\u003C\u002Fcode>（HTTP）または \u003Ccode>:1080\u003C\u002Fcode>（SOCKS5）でアクセスでき、ユーザー名に国・都市・セッションフラグを指定できます。詳細は\u003Ca href=\"https:\u002F\u002Fdocs.proxyhat.com\u002F\" rel=\"noopener noreferrer\">ProxyHat公式ドキュメント\u003C\u002Fa>を参照してください。\u003C\u002Fp>\n\n\u003Ch2>実装例1：Python requests + プロキシローテーション（生プロキシ）\u003C\u002Fh2>\n\n\u003Cp>まずはProxyHat SDKを使わず、生のプロキシURLを直接指定する例です。リクエストごとにIPをローテーションし、ウェイトヘッダーを監視します。\u003C\u002Fp>\n\n\u003Cpre>\u003Ccode>import requests\nimport time\nimport random\nimport logging\nfrom urllib.parse import urlencode\n\nlogging.basicConfig(level=logging.INFO)\nlogger = logging.getLogger(__name__)\n\nBINANCE_BASE = &quot;https:\u002F\u002Fapi.binance.com&quot;\nPROXYHAT_USER = &quot;user-country-US&quot;\nPROXYHAT_PASS = &quot;your_password&quot;\n\ndef get_proxy_url():\n    &quot;&quot;&quot;リクエストごとに新しいIPを割り当てる（ローテーション）&quot;&quot;&quot;\n    session_id = f&quot;req-{random.randint(100000, 999999)}&quot;\n    return f&quot;http:\u002F\u002F{PROXYHAT_USER}-sid-{session_id}:{PROXYHAT_PASS}@gate.proxyhat.com:8080&quot;\n\ndef fetch_klines(symbol=&quot;BTCUSDT&quot;, interval=&quot;1m&quot;, limit=500, max_retries=5):\n    params = {&quot;symbol&quot;: symbol, &quot;interval&quot;: interval, &quot;limit&quot;: limit}\n    url = f&quot;{BINANCE_BASE}\u002Fapi\u002Fv3\u002Fklines?{urlencode(params)}&quot;\n\n    for attempt in range(max_retries):\n        proxy_url = get_proxy_url()\n        proxies = {&quot;http&quot;: proxy_url, &quot;https&quot;: proxy_url}\n        try:\n            resp = requests.get(url, proxies=proxies, timeout=15)\n            used_weight = int(resp.headers.get(&quot;X-MBX-USED-WEIGHT-1M&quot;, 0))\n            logger.info(f&quot;Attempt {attempt+1} | Status: {resp.status_code} | Used weight: {used_weight}&quot;)\n\n            if resp.status_code == 429:\n                retry_after = int(resp.headers.get(&quot;Retry-After&quot;, 10))\n                logger.warning(f&quot;429 received. Sleeping {retry_after}s&quot;)\n                time.sleep(retry_after)\n                continue\n            if resp.status_code == 418:\n                logger.error(&quot;IP banned (418). Rotating to new IP.&quot;)\n                continue\n            if resp.status_code == 451:\n                logger.error(&quot;Geo-blocked (451). Using US geo-targeting.&quot;)\n                continue\n\n            resp.raise_for_status()\n            return resp.json()\n\n        except requests.RequestException as e:\n            backoff = (2 ** attempt) + random.uniform(0, 1)\n            logger.warning(f&quot;Error: {e}. Backing off {backoff:.1f}s&quot;)\n            time.sleep(backoff)\n\n    raise RuntimeError(f&quot;Failed after {max_retries} retries&quot;)\n\n# 実行\ndata = fetch_klines(symbol=&quot;ETHUSDT&quot;, interval=&quot;5m&quot;, limit=1000)\nprint(f&quot;Retrieved {len(data)} candles&quot;)\n\u003C\u002Fcode>\u003C\u002Fpre>\n\n\u003Ch2>実装例2：ProxyHat SDK + IPローテーション（Python httpx）\u003C\u002Fh2>\n\n\u003Cp>ProxyHat SDKを使うと、プロキシ管理がよりシンプルになります。以下は \u003Ccode>httpx\u003C\u002Fcode> と組み合わせた例です。\u003C\u002Fp>\n\n\u003Cpre>\u003Ccode>import httpx\nimport random\nimport asyncio\nimport logging\n\nlogging.basicConfig(level=logging.INFO)\nlogger = logging.getLogger(__name__)\n\nBINANCE_BASE = &quot;https:\u002F\u002Fapi.binance.com&quot;\nPROXYHAT_USER = &quot;user-country-US&quot;\nPROXYHAT_PASS = &quot;your_password&quot;\n\ndef proxyhat_proxy(session_id=None):\n    &quot;&quot;&quot;ProxyHat SDK風プロキシ生成ヘルパー&quot;&quot;&quot;\n    sid = session_id or f&quot;req-{random.randint(100000, 999999)}&quot;\n    username = f&quot;{PROXYHAT_USER}-sid-{sid}&quot;\n    return f&quot;http:\u002F\u002F{username}:{PROXYHAT_PASS}@gate.proxyhat.com:8080&quot;\n\nasync def fetch_ticker_price(symbol=&quot;BTCUSDT&quot;):\n    url = f&quot;{BINANCE_BASE}\u002Fapi\u002Fv3\u002Fticker\u002Fprice?symbol={symbol}&quot;\n    proxy = proxyhat_proxy()\n\n    async with httpx.AsyncClient(proxy=proxy, timeout=15) as client:\n        for attempt in range(5):\n            try:\n                resp = await client.get(url)\n                weight = resp.headers.get(&quot;X-MBX-USED-WEIGHT-1M&quot;, &quot;0&quot;)\n                logger.info(f&quot;Status: {resp.status_code} | Weight: {weight}&quot;)\n\n                if resp.status_code == 429:\n                    retry_after = int(resp.headers.get(&quot;Retry-After&quot;, 10))\n                    await asyncio.sleep(retry_after)\n                    continue\n\n                resp.raise_for_status()\n                return resp.json()\n            except httpx.HTTPError as e:\n                backoff = (2 ** attempt) + random.uniform(0, 1)\n                logger.warning(f&quot;Retry {attempt+1}: {e}, backoff {backoff:.1f}s&quot;)\n                await asyncio.sleep(backoff)\n\n    raise RuntimeError(&quot;Max retries exceeded&quot;)\n\n# 実行\nresult = asyncio.run(fetch_ticker_price(&quot;BNBUSDT&quot;))\nprint(result)\n\u003C\u002Fcode>\u003C\u002Fpre>\n\n\u003Ch2>実装例3：スティッキーセッションでklinesバックフィル\u003C\u002Fh2>\n\n\u003Cp>過去データのバックフィル（ページネーション）では、同じIPを維持して連続リクエストを行う方が効率的です。\u003Ccode>-sid-abc123\u003C\u002Fcode> フラグでスティッキーセッションを作成します。\u003C\u002Fp>\n\n\u003Cpre>\u003Ccode>import requests\nimport time\nimport logging\n\nlogging.basicConfig(level=logging.INFO)\nlogger = logging.getLogger(__name__)\n\nBINANCE_BASE = &quot;https:\u002F\u002Fapi.binance.com&quot;\nPROXYHAT_USER = &quot;user-country-US&quot;\nPROXYHAT_PASS = &quot;your_password&quot;\n\ndef fetch_klines_backfill(symbol=&quot;BTCUSDT&quot;, interval=&quot;1m&quot;, start_time=None, end_time=None, batch_size=1000):\n    &quot;&quot;&quot;スティッキーセッションでklinesをバックフィル&quot;&quot;&quot;\n    session_id = f&quot;backfill-{symbol}-{int(time.time())}&quot;\n    proxy_url = f&quot;http:\u002F\u002F{PROXYHAT_USER}-sid-{session_id}:{PROXYHAT_PASS}@gate.proxyhat.com:8080&quot;\n    proxies = {&quot;http&quot;: proxy_url, &quot;https&quot;: proxy_url}\n\n    all_candles = []\n    current_start = start_time\n    weight_budget = 5000  # 安全マージン\n\n    while True:\n        params = {\n            &quot;symbol&quot;: symbol,\n            &quot;interval&quot;: interval,\n            &quot;limit&quot;: batch_size,\n        }\n        if current_start:\n            params[&quot;startTime&quot;] = current_start\n        if end_time:\n            params[&quot;endTime&quot;] = end_time\n\n        url = f&quot;{BINANCE_BASE}\u002Fapi\u002Fv3\u002Fklines&quot;\n\n        try:\n            resp = requests.get(url, params=params, proxies=proxies, timeout=15)\n            used_weight = int(resp.headers.get(&quot;X-MBX-USED-WEIGHT-1M&quot;, 0))\n            logger.info(f&quot;Weight used: {used_weight}\u002F{weight_budget}&quot;)\n\n            if resp.status_code == 429:\n                retry_after = int(resp.headers.get(&quot;Retry-After&quot;, 10))\n                logger.warning(f&quot;429: sleeping {retry_after}s&quot;)\n                time.sleep(retry_after)\n                continue\n\n            resp.raise_for_status()\n            data = resp.json()\n\n            if not data:\n                break\n\n            all_candles.extend(data)\n            last_open_time = data[-1][0]\n            current_start = last_open_time + 1\n\n            # ウェイトが閾値に近づいたらスロットリング\n            if used_weight &gt; 4500:\n                sleep_time = max(0, (6000 - used_weight) \u002F 100)\n                logger.info(f&quot;Throttling: sleeping {sleep_time:.1f}s&quot;)\n                time.sleep(sleep_time)\n\n            if len(data) &lt; batch_size:\n                break\n\n        except requests.RequestException as e:\n            logger.error(f&quot;Error: {e}&quot;)\n            time.sleep(5)\n\n    return all_candles\n\n# 過去24時間の1分足を取得（ミリ秒タイムスタンプ）\nnow_ms = int(time.time() * 1000)\nstart_ms = now_ms - (24 * 60 * 60 * 1000)\ncandles = fetch_klines_backfill(&quot;BTCUSDT&quot;, &quot;1m&quot;, start_ms, now_ms)\nprint(f&quot;Total candles: {len(candles)}&quot;)\n\u003C\u002Fcode>\u003C\u002Fpre>\n\n\u003Ch2>実装例4：Node.js (axios) でプロキシローテーション\u003C\u002Fh2>\n\n\u003Cp>Node.js環境でも同様のパターンが使えます。\u003Ccode>axios\u003C\u002Fcode> と \u003Ccode>https-proxy-agent\u003C\u002Fcode> を組み合わせます。\u003C\u002Fp>\n\n\u003Cpre>\u003Ccode>const axios = require(&apos;axios&apos;);\nconst { HttpsProxyAgent } = require(&apos;https-proxy-agent&apos;);\nconst logger = require(&apos;.\u002Flogger&apos;); \u002F\u002F 任意のロガー\n\nconst BINANCE_BASE = &apos;https:\u002F\u002Fapi.binance.com&apos;;\nconst PROXYHAT_USER = &apos;user-country-US&apos;;\nconst PROXYHAT_PASS = &apos;your_password&apos;;\n\nfunction getProxyUrl() {\n  const sessionId = `req-${Math.floor(Math.random() * 900000) + 100000}`;\n  return `http:\u002F\u002F${PROXYHAT_USER}-sid-${sessionId}:${PROXYHAT_PASS}@gate.proxyhat.com:8080`;\n}\n\nasync function fetchDepth(symbol = &apos;BTCUSDT&apos;, limit = 100, maxRetries = 5) {\n  const url = `${BINANCE_BASE}\u002Fapi\u002Fv3\u002Fdepth?symbol=${symbol}&amp;limit=${limit}`;\n\n  for (let attempt = 0; attempt &lt; maxRetries; attempt++) {\n    const proxyUrl = getProxyUrl();\n    const agent = new HttpsProxyAgent(proxyUrl);\n\n    try {\n      const resp = await axios.get(url, {\n        httpsAgent: agent,\n        timeout: 15000,\n      });\n\n      const usedWeight = parseInt(resp.headers[&apos;x-mbx-used-weight-1m&apos;] || &apos;0&apos;, 10);\n      logger.info(`Attempt ${attempt + 1} | Status: ${resp.status} | Weight: ${usedWeight}`);\n\n      if (resp.status === 429) {\n        const retryAfter = parseInt(resp.headers[&apos;retry-after&apos;] || &apos;10&apos;, 10);\n        logger.warn(`429: waiting ${retryAfter}s`);\n        await new Promise(r =&gt; setTimeout(r, retryAfter * 1000));\n        continue;\n      }\n\n      return resp.data;\n    } catch (err) {\n      const backoff = Math.pow(2, attempt) * 1000 + Math.random() * 1000;\n      logger.warn(`Error: ${err.message}, backing off ${backoff}ms`);\n      await new Promise(r =&gt; setTimeout(r, backoff));\n    }\n  }\n\n  throw new Error(`Failed after ${maxRetries} retries`);\n}\n\n\u002F\u002F 実行\nfetchDepth(&apos;ETHUSDT&apos;, 100).then(data =&gt; {\n  console.log(`Bids: ${data.bids.length}, Asks: ${data.asks.length}`);\n});\n\u003C\u002Fcode>\u003C\u002Fpre>\n\n\u003Ch2>実装例5：並行ポーリング + ウェイトアウェアスロットリング\u003C\u002Fh2>\n\n\u003Cp>複数シンボルを並行ポーリングする場合は、全体のウェイト消費を追跡し、サーキットブレーカーを導入します。\u003C\u002Fp>\n\n\u003Cpre>\u003Ccode>import httpx\nimport asyncio\nimport random\nimport logging\nimport time\n\nlogging.basicConfig(level=logging.INFO)\nlogger = logging.getLogger(__name__)\n\nBINANCE_BASE = &quot;https:\u002F\u002Fapi.binance.com&quot;\nPROXYHAT_USER = &quot;user-country-US&quot;\nPROXYHAT_PASS = &quot;your_password&quot;\n\n# ウェイト追跡\nclass WeightTracker:\n    def __init__(self, max_weight=5000):\n        self.current_weight = 0\n        self.max_weight = max_weight\n        self.last_reset = time.time()\n\n    def update(self, weight_header):\n        if weight_header:\n            self.current_weight = int(weight_header)\n        # 1分経過でリセット\n        if time.time() - self.last_reset &gt; 60:\n            self.current_weight = 0\n            self.last_reset = time.time()\n\n    def can_request(self, expected_weight=1):\n        return (self.current_weight + expected_weight) &lt; self.max_weight\n\n    async def wait_for_budget(self, expected_weight=1):\n        while not self.can_request(expected_weight):\n            sleep_time = max(0.1, (self.max_weight - self.current_weight) \u002F 200)\n            logger.info(f&quot;Waiting for weight budget: {self.current_weight}\u002F{self.max_weight}&quot;)\n            await asyncio.sleep(sleep_time)\n\ndef proxyhat_proxy():\n    sid = f&quot;req-{random.randint(100000, 999999)}&quot;\n    return f&quot;http:\u002F\u002F{PROXYHAT_USER}-sid-{sid}:{PROXYHAT_PASS}@gate.proxyhat.com:8080&quot;\n\nasync def fetch_ticker_24hr(symbol, tracker, client):\n    await tracker.wait_for_budget(expected_weight=1)\n    url = f&quot;{BINANCE_BASE}\u002Fapi\u002Fv3\u002Fticker\u002F24hr?symbol={symbol}&quot;\n    proxy = proxyhat_proxy()\n\n    try:\n        async with httpx.AsyncClient(proxy=proxy, timeout=15) as c:\n            resp = await c.get(url)\n            tracker.update(resp.headers.get(&quot;X-MBX-USED-WEIGHT-1M&quot;))\n\n            if resp.status_code == 429:\n                retry_after = int(resp.headers.get(&quot;Retry-After&quot;, 10))\n                await asyncio.sleep(retry_after)\n                return None\n\n            resp.raise_for_status()\n            return resp.json()\n    except Exception as e:\n        logger.error(f&quot;Error fetching {symbol}: {e}&quot;)\n        return None\n\nasync def poll_multiple_symbols(symbols, interval_sec=5):\n    tracker = WeightTracker(max_weight=5000)\n\n    while True:\n        tasks = [fetch_ticker_24hr(s, tracker, None) for s in symbols]\n        results = await asyncio.gather(*tasks, return_exceptions=True)\n        valid = [r for r in results if r and not isinstance(r, Exception)]\n        logger.info(f&quot;Fetched {len(valid)}\u002F{len(symbols)} tickers | Weight: {tracker.current_weight}&quot;)\n        await asyncio.sleep(interval_sec)\n\n# 実行\nsymbols = [&quot;BTCUSDT&quot;, &quot;ETHUSDT&quot;, &quot;BNBUSDT&quot;, &quot;SOLUSDT&quot;, &quot;XRPUSDT&quot;]\nasyncio.run(poll_multiple_symbols(symbols, interval_sec=10))\n\u003C\u002Fcode>\u003C\u002Fpre>\n\n\u003Ch2>WebSocket vs RESTポーリング：いつどちらを使うか\u003C\u002Fh2>\n\n\u003Cp>Binanceは公開WebSocketストリーム（\u003Ccode>wss:\u002F\u002Fstream.binance.com:9443\u003C\u002Fcode>）も提供しており、\u003Ccode>kline\u003C\u002Fcode> や \u003Ccode>depth\u003C\u002Fcode> のリアルタイム更新が可能です。\u003C\u002Fp>\n\n\u003Ctable>\n\u003Cthead>\n\u003Ctr>\u003Cth>比較項目\u003C\u002Fth>\u003Cth>RESTポーリング\u003C\u002Fth>\u003Cth>WebSocketストリーム\u003C\u002Fth>\u003C\u002Ftr>\n\u003C\u002Fthead>\n\u003Ctbody>\n\u003Ctr>\u003Ctd>レイテンシ\u003C\u002Ftd>\u003Ctd>100ms〜500ms\u003C\u002Ftd>\u003Ctd>10ms〜50ms\u003C\u002Ftd>\u003C\u002Ftr>\n\u003Ctr>\u003Ctd>ウェイト消費\u003C\u002Ftd>\u003Ctd>リクエストごと\u003C\u002Ftd>\u003Ctd>接続時のみ\u003C\u002Ftd>\u003C\u002Ftr>\n\u003Ctr>\u003Ctd>プロキシの必要性\u003C\u002Ftd>\u003Ctd>高（IP分散）\u003C\u002Ftd>\u003Ctd>低〜中\u003C\u002Ftd>\u003C\u002Ftr>\n\u003Ctr>\u003Ctd>過去データ取得\u003C\u002Ftd>\u003Ctd>可能（klines）\u003C\u002Ftd>\u003Ctd>不可（リアルタイムのみ）\u003C\u002Ftd>\u003C\u002Ftr>\n\u003Ctr>\u003Ctd>実装の複雑さ\u003C\u002Ftd>\u003Ctd>低\u003C\u002Ftd>\u003Ctd>中（再接続管理）\u003C\u002Ftd>\u003C\u002Ftr>\n\u003C\u002Ftbody>\n\u003C\u002Ftable>\n\n\u003Cp>原則として、リアルタイム監視にはWebSocket、過去データのバックフィルやスナップショット取得にはREST + プロキシローテーションが適しています。\u003C\u002Fp>\n\n\u003Ch2>よくある間違いとエッジケース\u003C\u002Fh2>\n\n\u003Cul>\n\u003Cli>ウェイトヘッダーを無視: \u003Ccode>X-MBX-USED-WEIGHT-1M\u003C\u002Fcode> を読まないと429が頻発します。\u003C\u002Fli>\n\u003Cli>固定IPで連続リクエスト: 1IPで6,000ウェイトを使い切ると429→418の連鎖が始まります。\u003C\u002Fli>\n\u003Cli>geo-blockの無視: Binance.comは米国IPを451で拒否する場合があります。\u003Ccode>-country-US\u003C\u002Fcode> でBinance.US向けIPを使うか、別の国を指定します。\u003C\u002Fli>\n\u003Cli>Retry-Afterの無視: 429時は必ず \u003Ccode>Retry-After\u003C\u002Fcode> ヘッダーの秒数待機してください。\u003C\u002Fli>\n\u003Cli>並行しすぎ: 100並行でリクエストすると、プロキシ側またはBinance側でコネクションが飽和します。10〜20並行が安全な目安です。\u003C\u002Fli>\n\u003C\u002Ful>\n\n\u003Ch2>ProxyHatのセットアップ\u003C\u002Fh2>\n\n\u003Cp>ProxyHatのアカウント作成後、ダッシュボード（\u003Ca href=\"\u002Fja\u002Fpricing\">ProxyHat 料金プラン\u003C\u002Fa>）から認証情報を取得し、上記コードの \u003Ccode>PROXYHAT_USER\u003C\u002Fcode> と \u003Ccode>PROXYHAT_PASS\u003C\u002Fcode> を置き換えます。利用可能なロケーションは\u003Ca href=\"\u002Fja\u002Flocations\">プロキシロケーション一覧\u003C\u002Fa>で確認できます。\u003C\u002Fp>\n\n\u003Cp>より一般的なWebスクレイピングのユースケースについては\u003Ca href=\"\u002Fja\u002Fuse-cases\u002Fweb-scraping\">Webスクレイピングのユースケース\u003C\u002Fa>を、SERP追跡については\u003Ca href=\"\u002Fja\u002Fuse-cases\u002Fserp-tracking\">SERP追跡\u003C\u002Fa>を参照してください。\u003C\u002Fp>\n\n\u003Ch2>Key Takeaways（重要ポイント）\u003C\u002Fh2>\n\n\u003Cblockquote>\n\u003Cul>\n\u003Cli>Binance REST APIはIPごとに1分あたり約6,000ウェイトの制限。429→418の連鎖に注意。\u003C\u002Fli>\n\u003Cli>\u003Ccode>X-MBX-USED-WEIGHT-1M\u003C\u002Fcode> ヘッダーを必ず監視し、4,500〜5,000ウェイトでスロットリング。\u003C\u002Fli>\n\u003Cli>レジデンシャルプロキシでIPをローテーションし、ウェイト予算を分散。\u003Ccode>gate.proxyhat.com:8080\u003C\u002Fcode>（HTTP）または \u003Ccode>:1080\u003C\u002Fcode>（SOCKS5）を使用。\u003C\u002Fli>\n\u003Cli>過去データのバックフィルにはスティッキーセッション（\u003Ccode>-sid-xxx\u003C\u002Fcode>）、リアルタイム監視にはWebSocketが適する。\u003C\u002Fli>\n\u003Cli>指数バックオフ + Retry-After尊重 + 10〜20並行が本番運用の基本。\u003C\u002Fli>\n\u003C\u002Ful>\n\u003C\u002Fblockquote>\n\n\u003Cp>ProxyHatのレジデンシャルプロキシを使えば、Binanceの公開マーケットデータを大規模かつ安全に収集できます。まずは\u003Ca href=\"https:\u002F\u002Fdocs.proxyhat.com\u002F\" rel=\"noopener noreferrer\">ProxyHatドキュメント\u003C\u002Fa>で接続方法を確認し、少額プランからテストを始めることをお勧めします。\u003C\u002Fp>","Binance REST APIをプロキシでスクレイピングする方法 | ProxyHat","Binance REST APIのプロキシ経由スクレイピング方法を解説。ウェイト制限、IPローテーション、リトライ戦略、ProxyHat SDKのコード例を含む開発者向けガイド。","\u002Fja\u002Fblog\u002Fbinance-api-scraping-proxy",null,"https:\u002F\u002Fstatic.proxyhat.com\u002Fstorage\u002Fblog-covers\u002Fja\u002Fbinance-api-scraping-proxy-og.webp",[17,20,23,26],{"question":18,"answer":19},"なぜBinance REST APIのスクレイピングにプロキシが必要なのですか？","BinanceはIPごとにウェイトベースのレート制限を設けており、制限を超えるとHTTP 429（Too Many Requests）、継続するとHTTP 418でIPバンを科します。プロキシでIPを分散することでウェイト予算を複数IPに分割し、429や418を回避しながら高頻度でデータを取得できます。",{"question":21,"answer":22},"Binance REST APIのスクレイピングに最適なプロキシタイプは何ですか？","レジデンシャルプロキシが最適です。BinanceはデータセンタIPを検出しやすく制限を厳しくかける傾向がありますが、レジデンシャルプロキシはISP発の本物の住宅IPを使用するため検出リスクが低く、大規模なマーケットデータ収集に適しています。ProxyHatのレジデンシャルプロキシはgate.proxyhat.com:8080（HTTP）または:1080（SOCKS5）でアクセスできます。",{"question":24,"answer":25},"Binance REST APIのスクレイピングでブロックを回避するにはどうすればよいですか？","X-MBX-USED-WEIGHT-1Mヘッダーを監視して4,500〜5,000ウェイトでスロットリングし、429時はRetry-Afterヘッダーの秒数を尊重して待機します。リクエストごとにIPをローテーションし、指数バックオフでリトライし、並行数を10〜20に制限することでブロックをほぼ回避できます。",{"question":27,"answer":28},"BinanceのWebSocketストリームとRESTポーリングのどちらを使うべきですか？","リアルタイムの価格・オーダーブック監視にはWebSocketストリーム（wss:\u002F\u002Fstream.binance.com:9443）が適しています。レイテンシが10〜50msでウェイト消費もほぼありません。一方、過去データのバックフィルやスナップショット取得にはREST API + プロキシローテーションが適しています。用途に応じて使い分けるのがベストプラクティスです。",false,"2026-08-03T10:04:04+00:00","2026-10-03T08:21:25+00:00","https:\u002F\u002Fstatic.proxyhat.com\u002Fstorage\u002Fblog-covers\u002Fja\u002Fbinance-api-scraping-proxy-master.webp","How to Scrape the Binance REST API with Proxies: A Developer Guide","https:\u002F\u002Fstatic.proxyhat.com\u002Fstorage\u002Fblog-covers\u002Fja\u002Fbinance-api-scraping-proxy-card.webp",12,{"name":37,"slug":38,"bio":39,"avatar_url":14,"website_url":14,"social_links":14},"ProxyHat Team","proxyhat-team","The ProxyHat editorial team covers proxies, web scraping, and data extraction.",[41],{"id":42,"slug":43,"name":44,"description":14,"meta_title":45,"meta_description":46,"parent_id":14},4,"kaihatsusha-gaido","開発者ガイド","開発者ガイド | ProxyHat ブログ","プロキシをアプリケーションに統合するためのコードチュートリアルとSDKガイド。",[],{"fr":49,"en":50,"pt":51,"ko":52,"ru":53,"zh":54,"x-default":50},"\u002Ffr\u002Fblog\u002Fcomment-scraper-api-rest-binance-proxies","\u002Fblog\u002Fscrape-binance-rest-api-proxies","\u002Fpt\u002Fblog\u002Fcomo-raspar-api-binance-proxies","\u002Fko\u002Fblog\u002Fbinance-rest-api-proxy-scraping","\u002Fru\u002Fblog\u002Fkak-skrejpit-binance-rest-api-proksi","\u002Fcn\u002Fblog\u002Fbinance-rest-api-proxy-scraping-guide",{"tr":56,"fr":49,"en":50,"ja":13,"pt":51,"ko":52,"pl":57,"es":58,"ru":53,"zh":54,"it":59,"de":60},"\u002Ftr\u002Fblog\u002Fbinance-rest-api-proxy-tarama","\u002Fpl\u002Fblog\u002Fjak-scrapowac-rest-api-binance-proxy","\u002Fes\u002Fblog\u002Fscrapear-api-binance-proxies","\u002Fit\u002Fblog\u002Fscraping-binance-rest-api-con-proxy","\u002Fde\u002Fblog\u002Fbinance-rest-api-mit-proxies-scrapen",81,[63,79,94,110],{"id":64,"slug":65,"title":66,"excerpt":67,"featured_image_url":68,"featured_image_alt":69,"card_image_url":70,"og_image_url":71,"published_at":72,"updated_at":72,"content_updated_at":73,"reading_time_minutes":35,"is_featured":29,"indexable":4,"views":74,"author":75,"categories":76,"tags":78},176,"got-scraping-nodejs-purokishi","Node.jsでgot-scrapingを使ったプロキシ連携の完全ガイド","got-scrapingのheader-generatorとProxyHatレジデンシャルプロキシを組み合わせ、Node.jsでブロックされないスクレイピングを構築する方法を解説。実践的なコード例付き。","https:\u002F\u002Fstatic.proxyhat.com\u002Fstorage\u002Fblog-covers\u002Fja\u002Fgot-scraping-nodejs-purokishi-master.webp","got-scraping in Node.js: A Developer's Guide with Residential Proxies","https:\u002F\u002Fstatic.proxyhat.com\u002Fstorage\u002Fblog-covers\u002Fja\u002Fgot-scraping-nodejs-purokishi-card.webp","https:\u002F\u002Fstatic.proxyhat.com\u002Fstorage\u002Fblog-covers\u002Fja\u002Fgot-scraping-nodejs-purokishi-og.webp","2026-08-04T16:05:06+00:00","2026-10-03T08:57:49+00:00",120,{"name":37,"slug":38,"bio":39,"avatar_url":14,"website_url":14,"social_links":14},[77],{"id":42,"slug":43,"name":44,"description":14,"meta_title":45,"meta_description":46,"parent_id":14},[],{"id":80,"slug":81,"title":82,"excerpt":83,"featured_image_url":84,"featured_image_alt":85,"card_image_url":86,"og_image_url":87,"published_at":88,"updated_at":88,"content_updated_at":73,"reading_time_minutes":35,"is_featured":29,"indexable":29,"views":89,"author":90,"categories":91,"tags":93},175,"colly-purokushi-roteshon-gaido","Collyでのローテーティングプロキシ完全ガイド: Goスクレイパーの本番運用","Collyでのローテーティングプロキシの実装方法を解説。RoundRobinProxySwitcherとカスタムプロキシ関数でResidentialプロキシをリクエストごとに切り替え、ブロック回避と高スループットを実現する実践的なGoコード例を提供します。","https:\u002F\u002Fstatic.proxyhat.com\u002Fstorage\u002Fblog-covers\u002Fja\u002Fcolly-purokushi-roteshon-gaido-master.webp","Rotating Proxies in Colly: A Framework-Idiomatic Guide for Go Developers","https:\u002F\u002Fstatic.proxyhat.com\u002Fstorage\u002Fblog-covers\u002Fja\u002Fcolly-purokushi-roteshon-gaido-card.webp","https:\u002F\u002Fstatic.proxyhat.com\u002Fstorage\u002Fblog-covers\u002Fja\u002Fcolly-purokushi-roteshon-gaido-og.webp","2026-08-04T10:05:34+00:00",71,{"name":37,"slug":38,"bio":39,"avatar_url":14,"website_url":14,"social_links":14},[92],{"id":42,"slug":43,"name":44,"description":14,"meta_title":45,"meta_description":46,"parent_id":14},[],{"id":95,"slug":96,"title":97,"excerpt":98,"featured_image_url":99,"featured_image_alt":100,"card_image_url":101,"og_image_url":102,"published_at":103,"updated_at":103,"content_updated_at":104,"reading_time_minutes":35,"is_featured":29,"indexable":4,"views":105,"author":106,"categories":107,"tags":109},195,"bybit-v5-market-api-proxy-scraping","暗号資産取引所の市場データをローテーションプロキシで収集する完全ガイド（Bybit V5 APIの例）","Bybit V5 Market APIのorderbook・tickers・klineエンドポイントをローテーションプロキシ経由でスクレイピングする方法を、Node.js・Pythonのコード例とともに解説。レート制限・地域制限の回避策もカバーします。","https:\u002F\u002Fstatic.proxyhat.com\u002Fstorage\u002Fblog-covers\u002Fja\u002Fbybit-v5-market-api-proxy-scraping-master.webp","How to Scrape the Bybit V5 Market API with Rotating Proxies","https:\u002F\u002Fstatic.proxyhat.com\u002Fstorage\u002Fblog-covers\u002Fja\u002Fbybit-v5-market-api-proxy-scraping-card.webp","https:\u002F\u002Fstatic.proxyhat.com\u002Fstorage\u002Fblog-covers\u002Fja\u002Fbybit-v5-market-api-proxy-scraping-og.webp","2026-08-03T16:09:16+00:00","2026-10-04T01:29:51+00:00",86,{"name":37,"slug":38,"bio":39,"avatar_url":14,"website_url":14,"social_links":14},[108],{"id":42,"slug":43,"name":44,"description":14,"meta_title":45,"meta_description":46,"parent_id":14},[],{"id":111,"slug":112,"title":113,"excerpt":114,"featured_image_url":115,"featured_image_alt":116,"card_image_url":117,"og_image_url":118,"published_at":119,"updated_at":119,"content_updated_at":120,"reading_time_minutes":35,"is_featured":29,"indexable":29,"views":121,"author":122,"categories":123,"tags":125},172,"swift-urlsession-proxy-guide","Swiftでプロキシを使用する完全ガイド：URLSessionで residential プロキシを活用する方法","iOS・macOS開発者向けに、SwiftのURLSessionでresidentialプロキシを設定・認証・活用する実践的なコードファーストガイド。ProxyHatゲートウェイを使ったHTTP\u002FSOCKS5構成、async\u002Fawait並行処理、本番運用のベストプラクティスまで網羅。","https:\u002F\u002Fstatic.proxyhat.com\u002Fstorage\u002Fblog-covers\u002Fja\u002Fswift-urlsession-proxy-guide-master.webp","Using Proxies in Swift: A Code-First Guide to URLSession, SOCKS5 & Residential IPs","https:\u002F\u002Fstatic.proxyhat.com\u002Fstorage\u002Fblog-covers\u002Fja\u002Fswift-urlsession-proxy-guide-card.webp","https:\u002F\u002Fstatic.proxyhat.com\u002Fstorage\u002Fblog-covers\u002Fja\u002Fswift-urlsession-proxy-guide-og.webp","2026-07-26T16:03:44+00:00","2026-10-03T23:53:00+00:00",230,{"name":37,"slug":38,"bio":39,"avatar_url":14,"website_url":14,"social_links":14},[124],{"id":42,"slug":43,"name":44,"description":14,"meta_title":45,"meta_description":46,"parent_id":14},[],[]]