[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"blog-post-cn-scrape-bybit-v5-market-api-proxy":3},{"success":4,"payload":5,"related":63,"errors":157},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":15,"og_description":12,"og_image_url":16,"faq_json":17,"key_takeaways":14,"allow_index":4,"noindex_google_only":30,"allow_follow":4,"published_at":31,"updated_at":31,"content_updated_at":32,"featured_image_url":33,"featured_image_alt":34,"card_image_url":35,"reading_time_minutes":36,"author":37,"categories":41,"tags":48,"alternates":49,"locale_paths":60,"views":62},195,"scrape-bybit-v5-market-api-proxy","如何使用轮换代理采集加密货币市场数据：开发者指南（以 Bybit V5 Market API 为例）","面向加密货币交易机器人开发者的实战指南：用 ProxyHat 轮换住宅代理抓取 Bybit V5 公共市场 API，涵盖订单簿、Ticker、K线接口的限速规避、地理封锁绕过与 WebSocket 对比。","\u003Cp>如果你正在构建加密货币交易机器人或市场数据管道，如何使用轮换代理抓取 Bybit V5 Market API 是绕不开的工程难题。Bybit 的 V5 统一市场接口（\u003Ccode>api.bybit.com\u002Fv5\u002Fmarket\u002F...\u003C\u002Fcode>）提供了订单簿、Ticker、K线和最近成交等公共数据，但严格的 IP 限速和地理封锁会让高频抓取迅速失败。本指南从开发者视角出发，提供可运行的代码示例、限速策略、代理配置和生产级最佳实践。\u003C\u002Fp>\u003Cp>\u003Cstrong>法律声明：\u003C\u002Fstrong>本文仅涉及 Bybit 公共市场数据端点。在抓取前请阅读 \u003Ca href=\"https:\u002F\u002Fwww.bybit.com\u002Fen-US\u002Fhelp\u002Farticle\u002F118008998187\" rel=\"noopener noreferrer\">Bybit 服务条款\u003C\u002Fa> 和 API 使用规范，确保你的数据采集行为符合平台政策及所在司法管辖区的法规。ProxyHat 不鼓励违反任何平台 ToS 的行为。\u003C\u002Fp>\n\u003Ch2>Bybit V5 Market API 端点全景与响应信封\u003C\u002Fh2>\n\u003Cp>Bybit V5 将现货、合约、期权统一到 \u003Ccode>\u002Fv5\u002Fmarket\u002F\u003C\u002Fcode> 路径下，通过 \u003Ccode>category\u003C\u002Fcode> 参数区分产品类型。理解这些端点和返回结构是抓取的基础。\u003C\u002Fp>\n\u003Ch3>核心公共端点\u003C\u002Fh3>\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 \u002Fv5\u002Fmarket\u002Forderbook\u003C\u002Fcode>\u003C\u002Ftd>\u003Ctd>订单簿快照\u003C\u002Ftd>\u003Ctd>\u003Ccode>category=spot|linear\u003C\u002Fcode>, \u003Ccode>symbol\u003C\u002Fcode>, \u003Ccode>limit\u003C\u002Fcode>（深度 1-200）\u003C\u002Ftd>\u003Ctd>~30-50ms\u003C\u002Ftd>\u003C\u002Ftr>\n\u003Ctr>\u003Ctd>\u003Ccode>GET \u002Fv5\u002Fmarket\u002Ftickers\u003C\u002Fcode>\u003C\u002Ftd>\u003Ctd>最新行情汇总\u003C\u002Ftd>\u003Ctd>\u003Ccode>category\u003C\u002Fcode>, 可选 \u003Ccode>symbol\u003C\u002Fcode>\u003C\u002Ftd>\u003Ctd>~50-80ms\u003C\u002Ftd>\u003C\u002Ftr>\n\u003Ctr>\u003Ctd>\u003Ccode>GET \u002Fv5\u002Fmarket\u002Fkline\u003C\u002Fcode>\u003C\u002Ftd>\u003Ctd>K线\u002F蜡烛图数据\u003C\u002Ftd>\u003Ctd>\u003Ccode>category\u003C\u002Fcode>, \u003Ccode>symbol\u003C\u002Fcode>, \u003Ccode>interval\u003C\u002Fcode>, \u003Ccode>start\u003C\u002Fcode>, \u003Ccode>end\u003C\u002Fcode>, \u003Ccode>limit\u003C\u002Fcode>（最大 1000）\u003C\u002Ftd>\u003Ctd>~60-100ms\u003C\u002Ftd>\u003C\u002Ftr>\n\u003Ctr>\u003Ctd>\u003Ccode>GET \u002Fv5\u002Fmarket\u002Frecent-trade\u003C\u002Fcode>\u003C\u002Ftd>\u003Ctd>最近成交流水\u003C\u002Ftd>\u003Ctd>\u003Ccode>category\u003C\u002Fcode>, \u003Ccode>symbol\u003C\u002Fcode>, \u003Ccode>limit\u003C\u002Fcode>（最大 1000）\u003C\u002Ftd>\u003Ctd>~40-70ms\u003C\u002Ftd>\u003C\u002Ftr>\n\u003C\u002Ftbody>\n\u003C\u002Ftable>\n\u003Cp>所有 V5 响应遵循统一的 JSON 信封：\u003C\u002Fp>\n\u003Cpre>\u003Ccode>{\n  &quot;retCode&quot;: 0,\n  &quot;retMsg&quot;: &quot;OK&quot;,\n  &quot;result&quot;: {\n    &quot;category&quot;: &quot;spot&quot;,\n    &quot;symbol&quot;: &quot;BTCUSDT&quot;,\n    &quot;bids&quot;: [[&quot;65000.50&quot;, &quot;1.234&quot;], ...],\n    &quot;asks&quot;: [[&quot;65000.60&quot;, &quot;0.567&quot;], ...],\n    &quot;ts&quot;: 1719500000000\n  },\n  &quot;time&quot;: 1719500000000\n}\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>\u003Ccode>retCode=0\u003C\u002Fcode> 表示成功；非零值表示错误（如 \u003Ccode>10001\u003C\u002Fcode> 参数错误、\u003Ccode>10010\u003C\u002Fcode> 请求过于频繁）。务必在代码中检查 \u003Ccode>retCode\u003C\u002Fcode>，而非仅依赖 HTTP 200 状态码——Bybit 可能在 HTTP 200 下返回业务错误。\u003C\u002Fp>\n\u003Ch2>Bybit IP 限速机制：为什么高频抓取会失败\u003C\u002Fh2>\n\u003Cp>Bybit 对公共市场数据端点实施 \u003Cstrong>基于 IP 的限速\u003C\u002Fstrong>，不同端点有独立的速率上限。根据 Bybit V5 官方限速文档，\u003Ccode>\u002Fv5\u002Fmarket\u002Forderbook\u003C\u002Fcode> 等高频端点的默认限制约为每秒 10-20 次请求（具体值可能随时间调整，请以官方文档为准）。\u003C\u002Fp>\n\u003Cp>当超出限速时，Bybit 返回 HTTP \u003Cstrong>403\u003C\u002Fstrong> 状态码，响应体中的 \u003Ccode>retMsg\u003C\u002Fcode> 通常包含 \u003Ccode>too fast\u003C\u002Fcode> 或类似提示。更关键的是，触发限速后 IP 可能被临时封禁约 \u003Cstrong>10 分钟\u003C\u002Fstrong>，期间所有请求都会被拒绝。这对订单簿抓取尤其危险——开发者经常在循环中密集请求 \u003Ccode>\u002Fv5\u002Fmarket\u002Forderbook\u003C\u002Fcode>，很容易在几秒内触发封禁。\u003C\u002Fp>\n\u003Cp>具体限速行为包括：\u003C\u002Fp>\n\u003Cul>\n\u003Cli>\u003Cstrong>每端点独立计数\u003C\u002Fstrong>：\u003Ccode>orderbook\u003C\u002Fcode> 和 \u003Ccode>tickers\u003C\u002Fcode> 的限速池互不影响。\u003C\u002Fli>\n\u003Cli>突发惩罚：短时间内的请求尖峰比均匀速率更容易触发封禁。\u003C\u002Fli>\n\u003Cli>封禁窗口：约 600 秒（10 分钟），期间无法通过该 IP 访问任何端点。\u003C\u002Fli>\n\u003Cli>无重试头：Bybit 不总是返回标准的 \u003Ccode>Retry-After\u003C\u002Fcode> 头，需要自行实现退避策略。\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Cp>这就是轮换代理的核心价值：通过在不同 IP 之间分配请求，将单 IP 的请求频率控制在限速阈值以下。\u003C\u002Fp>\n\u003Ch2>地理封锁与住宅代理解决方案\u003C\u002Fh2>\n\u003Cp>Bybit 在多个司法管辖区受到监管限制。来自美国、英国等地区的 IP 可能直接收到 403 Forbidden 或被 CloudFront 边缘节点拦截，即使请求的是完全公开的市场数据。对于需要从受限地区访问 Bybit API 的开发者，\u003Ca href=\"\u002Fcn\u002Fproxy\u002Fresidential\">住宅代理\u003C\u002Fa>是合规且可靠的技术方案。\u003C\u002Fp>\n\u003Cp>ProxyHat 住宅代理通过 \u003Ccode>gate.proxyhat.com:8080\u003C\u002Fcode>（HTTP）或 \u003Ccode>gate.proxyhat.com:1080\u003C\u002Fcode>（SOCKS5）提供接入，支持在用户名中指定目标国家：\u003C\u002Fp>\n\u003Cpre>\u003Ccode># HTTP 代理 — 美国 IP\nhttp:\u002F\u002Fuser-country-US:pass@gate.proxyhat.com:8080\n\n# HTTP 代理 — 德国柏林 IP\nhttp:\u002F\u002Fuser-country-DE-region-state_of_berlin-city-berlin:pass@gate.proxyhat.com:8080\n\n# SOCKS5 代理\nsocks5:\u002F\u002Fuser-country-US:pass@gate.proxyhat.com:1080\n\n# 粘性会话（同一 IP 保持一段时间）\nhttp:\u002F\u002Fuser-sid-abc123-country-US:pass@gate.proxyhat.com:8080\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>使用 \u003Ccode>-country-US\u003C\u002Fcode> 格式的用户名，可以将出口 IP 固定到美国，从而绕过地理封锁。查看 \u003Ca href=\"\u002Fcn\u002Flocations\">ProxyHat 可用位置\u003C\u002Fa> 了解支持的国家列表。\u003C\u002Fp>\n\u003Ch2>代码实战：Node.js 抓取 Bybit V5 订单簿\u003C\u002Fh2>\n\u003Cp>以下示例展示如何用 Node.js（axios + https-proxy-agent）抓取 Bybit 订单簿，对比原始代理与 ProxyHat SDK两种方式。\u003C\u002Fp>\n\u003Ch3>方式一：原始代理配置\u003C\u002Fh3>\n\u003Cpre>\u003Ccode>const axios = require(&apos;axios&apos;);\nconst { HttpsProxyAgent } = require(&apos;https-proxy-agent&apos;);\n\nconst PROXY_URL = &apos;http:\u002F\u002Fuser-country-US:YOUR_PASSWORD@gate.proxyhat.com:8080&apos;;\nconst agent = new HttpsProxyAgent(PROXY_URL);\n\nasync function fetchOrderbook(symbol, category = &apos;spot&apos;, limit = 50) {\n  const url = &apos;https:\u002F\u002Fapi.bybit.com\u002Fv5\u002Fmarket\u002Forderbook&apos;;\n  try {\n    const resp = await axios.get(url, {\n      httpsAgent: agent,\n      params: { category, symbol, limit },\n      timeout: 10000\n    });\n    if (resp.data.retCode !== 0) {\n      throw new Error(`Bybit API error: ${resp.data.retCode} - ${resp.data.retMsg}`);\n    }\n    return resp.data.result;\n  } catch (err) {\n    if (err.response &amp;&amp; err.response.status === 403) {\n      console.error(&apos;Rate limited or geo-blocked, backing off...&apos;);\n    }\n    throw err;\n  }\n}\n\n\u002F\u002F 使用示例\nfetchOrderbook(&apos;BTCUSDT&apos;).then(ob =&gt; {\n  console.log(`Best bid: ${ob.bids[0]}, Best ask: ${ob.asks[0]}`);\n}).catch(console.error);\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch3>方式二：ProxyHat SDK + IP 轮换 + 退避重试\u003C\u002Fh3>\n\u003Cpre>\u003Ccode>const axios = require(&apos;axios&apos;);\nconst { HttpsProxyAgent } = require(&apos;https-proxy-agent&apos;);\n\n\u002F\u002F ProxyHat SDK 风格的代理管理器\nclass ProxyHatManager {\n  constructor(user, pass, countries = [&apos;US&apos;, &apos;DE&apos;, &apos;SG&apos;]) {\n    this.user = user;\n    this.pass = pass;\n    this.countries = countries;\n    this.idx = 0;\n  }\n\n  \u002F\u002F 每次请求轮换到不同国家的 IP\n  nextProxy() {\n    const country = this.countries[this.idx % this.countries.length];\n    this.idx++;\n    return `http:\u002F\u002F${this.user}-country-${country}:${this.pass}@gate.proxyhat.com:8080`;\n  }\n\n  \u002F\u002F 粘性会话代理\n  stickyProxy(sessionId, country = &apos;US&apos;) {\n    return `http:\u002F\u002F${this.user}-sid-${sessionId}-country-${country}:${this.pass}@gate.proxyhat.com:8080`;\n  }\n}\n\nconst proxyMgr = new ProxyHatManager(&apos;YOUR_USER&apos;, &apos;YOUR_PASS&apos;);\n\n\u002F\u002F 指数退避重试\nasync function fetchWithRetry(url, params, maxRetries = 5) {\n  for (let attempt = 0; attempt &lt; maxRetries; attempt++) {\n    const proxyUrl = proxyMgr.nextProxy();\n    const agent = new HttpsProxyAgent(proxyUrl);\n    try {\n      const resp = await axios.get(url, {\n        httpsAgent: agent,\n        params,\n        timeout: 10000\n      });\n      if (resp.data.retCode === 0) return resp.data.result;\n      \u002F\u002F retCode 非零但非限速错误，直接抛出\n      if (resp.data.retCode !== 10010 &amp;&amp; resp.data.retMsg.indexOf(&apos;too fast&apos;) === -1) {\n        throw new Error(`${resp.data.retCode}: ${resp.data.retMsg}`);\n      }\n    } catch (err) {\n      if (attempt === maxRetries - 1) throw err;\n    }\n    const delay = Math.min(1000 * Math.pow(2, attempt), 30000);\n    await new Promise(r =&gt; setTimeout(r, delay));\n  }\n}\n\n\u002F\u002F 批量抓取多个交易对订单簿，IP 自动轮换\nasync function scrapeOrderbooks(symbols) {\n  const results = [];\n  for (const symbol of symbols) {\n    try {\n      const ob = await fetchWithRetry(\n        &apos;https:\u002F\u002Fapi.bybit.com\u002Fv5\u002Fmarket\u002Forderbook&apos;,\n        { category: &apos;spot&apos;, symbol, limit: 50 }\n      );\n      results.push({ symbol, bid: ob.bids[0], ask: ob.asks[0] });\n      \u002F\u002F 每端点速率预算：控制在 ~5 req\u002Fs 以下\n      await new Promise(r =&gt; setTimeout(r, 200));\n    } catch (err) {\n      console.error(`Failed for ${symbol}:`, err.message);\n    }\n  }\n  return results;\n}\n\nscrapeOrderbooks([&apos;BTCUSDT&apos;, &apos;ETHUSDT&apos;, &apos;SOLUSDT&apos;]).then(console.log);\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch2>代码实战：Python 抓取 K线与粘性会话分页\u003C\u002Fh2>\n\u003Cp>K线数据通常需要分页拉取大量历史数据。使用粘性会话（sticky session）可以确保同一 IP 处理整个分页流程，避免中途 IP 切换导致的限速重置问题。\u003C\u002Fp>\n\u003Ch3>Python 原始代理 + 粘性会话\u003C\u002Fh3>\n\u003Cpre>\u003Ccode>import requests\nimport time\nimport logging\n\nlogging.basicConfig(level=logging.INFO, format=&apos;%(asctime)s %(levelname)s %(message)s&apos;)\n\nPROXIES = {\n    &apos;http&apos;: &apos;http:\u002F\u002Fuser-sid-kline-btc-country-US:YOUR_PASS@gate.proxyhat.com:8080&apos;,\n    &apos;https&apos;: &apos;http:\u002F\u002Fuser-sid-kline-btc-country-US:YOUR_PASS@gate.proxyhat.com:8080&apos;,\n}\n\ndef fetch_kline(symbol, category, interval, start, end, limit=1000):\n    url = &apos;https:\u002F\u002Fapi.bybit.com\u002Fv5\u002Fmarket\u002Fkline&apos;\n    params = {\n        &apos;category&apos;: category,\n        &apos;symbol&apos;: symbol,\n        &apos;interval&apos;: interval,\n        &apos;start&apos;: start,\n        &apos;end&apos;: end,\n        &apos;limit&apos;: limit,\n    }\n    for attempt in range(5):\n        try:\n            resp = requests.get(url, params=params, proxies=PROXIES, timeout=10)\n            if resp.status_code == 403:\n                logging.warning(&apos;403 received, backing off %.1fs&apos;, 2 ** attempt)\n                time.sleep(2 ** attempt)\n                continue\n            data = resp.json()\n            if data[&apos;retCode&apos;] != 0:\n                raise Exception(f&quot;Bybit error {data[&apos;retCode&apos;]}: {data[&apos;retMsg&apos;]}&quot;)\n            return data[&apos;result&apos;]\n        except requests.RequestException as e:\n            logging.error(&apos;Request failed: %s&apos;, e)\n            time.sleep(2 ** attempt)\n    raise Exception(f&apos;Failed after retries for {symbol}&apos;)\n\ndef scrape_kline_history(symbol, category, interval, start, end):\n    &quot;&quot;&quot;分页拉取 K线历史，使用粘性会话保持同一出口 IP&quot;&quot;&quot;\n    all_rows = []\n    cursor = start\n    while cursor &lt; end:\n        result = fetch_kline(symbol, category, interval, cursor, end)\n        rows = result.get(&apos;list&apos;, [])\n        if not rows:\n            break\n        all_rows.extend(rows)\n        # K线按时间倒序返回，取最早一条的时间戳作为下一页 cursor\n        cursor = int(rows[-1][0]) + 1\n        logging.info(&apos;Fetched %d rows for %s, total %d&apos;, len(rows), symbol, len(all_rows))\n        time.sleep(0.3)  # 端点速率预算\n    return all_rows\n\n# 示例：拉取 BTCUSDT 1分钟K线\nrows = scrape_kline_history(&apos;BTCUSDT&apos;, &apos;spot&apos;, &apos;1&apos;, 1719400000000, 1719500000000)\nprint(f&apos;Total klines: {len(rows)}&apos;)\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch3>Python ProxyHat SDK 风格 + 多交易对并发\u003C\u002Fh3>\n\u003Cpre>\u003Ccode>import requests\nimport time\nimport logging\nfrom concurrent.futures import ThreadPoolExecutor, as_completed\n\nlogging.basicConfig(level=logging.INFO, format=&apos;%(asctime)s %(levelname)s %(message)s&apos;)\n\nclass ProxyHatClient:\n    def __init__(self, user, passw, countries=None):\n        self.user = user\n        self.passw = passw\n        self.countries = countries or [&apos;US&apos;, &apos;DE&apos;, &apos;SG&apos;, &apos;JP&apos;]\n        self._idx = 0\n\n    def _proxy(self, session_id=None, country=None):\n        c = country or self.countries[self._idx % len(self.countries)]\n        self._idx += 1\n        if session_id:\n            auth = f&apos;{self.user}-sid-{session_id}-country-{c}:{self.passw}&apos;\n        else:\n            auth = f&apos;{self.user}-country-{c}:{self.passw}&apos;\n        url = f&apos;http:\u002F\u002F{auth}@gate.proxyhat.com:8080&apos;\n        return {&apos;http&apos;: url, &apos;https&apos;: url}\n\n    def get(self, url, params=None, session_id=None, max_retries=5):\n        for attempt in range(max_retries):\n            proxies = self._proxy(session_id=session_id)\n            try:\n                resp = requests.get(url, params=params, proxies=proxies, timeout=10)\n                if resp.status_code == 403:\n                    logging.warning(&apos;403 on attempt %d, backoff %ds&apos;, attempt + 1, 2 ** attempt)\n                    time.sleep(2 ** attempt)\n                    continue\n                data = resp.json()\n                if data[&apos;retCode&apos;] != 0:\n                    if data[&apos;retCode&apos;] == 10010 or &apos;too fast&apos; in data.get(&apos;retMsg&apos;, &apos;&apos;):\n                        time.sleep(2 ** attempt)\n                        continue\n                    raise Exception(f&quot;retCode={data[&apos;retCode&apos;]} retMsg={data[&apos;retMsg&apos;]}&quot;)\n                return data[&apos;result&apos;]\n            except requests.RequestException as e:\n                logging.error(&apos;Attempt %d failed: %s&apos;, attempt + 1, e)\n                time.sleep(2 ** attempt)\n        raise Exception(f&apos;Max retries ({max_retries}) exceeded&apos;)\n\nph = ProxyHatClient(&apos;YOUR_USER&apos;, &apos;YOUR_PASS&apos;)\n\ndef scrape_tickers(symbols):\n    &quot;&quot;&quot;并发抓取多个交易对的 ticker 数据&quot;&quot;&quot;\n    results = {}\n    with ThreadPoolExecutor(max_workers=4) as pool:\n        futures = {}\n        for sym in symbols:\n            f = pool.submit(\n                ph.get,\n                &apos;https:\u002F\u002Fapi.bybit.com\u002Fv5\u002Fmarket\u002Ftickers&apos;,\n                {&apos;category&apos;: &apos;spot&apos;, &apos;symbol&apos;: sym},\n                session_id=f&apos;ticker-{sym}&apos;\n            )\n            futures[f] = sym\n        for f in as_completed(futures):\n            sym = futures[f]\n            try:\n                result = f.result()\n                tickers = result.get(&apos;list&apos;, [])\n                if tickers:\n                    t = tickers[0]\n                    results[sym] = {\n                        &apos;lastPrice&apos;: t.get(&apos;lastPrice&apos;),\n                        &apos;volume24h&apos;: t.get(&apos;volume24h&apos;),\n                    }\n                    logging.info(&apos;%s: price=%s vol=%s&apos;, sym, t.get(&apos;lastPrice&apos;), t.get(&apos;volume24h&apos;))\n            except Exception as e:\n                logging.error(&apos;Failed for %s: %s&apos;, sym, e)\n    return results\n\ndata = scrape_tickers([&apos;BTCUSDT&apos;, &apos;ETHUSDT&apos;, &apos;SOLUSDT&apos;, &apos;XRPUSDT&apos;])\nprint(data)\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch2>cURL 快速验证：最近成交接口\u003C\u002Fh2>\n\u003Cp>在编写复杂代码之前，用 cURL 快速验证代理连通性和 API 响应：\u003C\u002Fp>\n\u003Cpre>\u003Ccode># 使用 ProxyHat 代理抓取最近成交\ncurl -x http:\u002F\u002Fuser-country-US:YOUR_PASS@gate.proxyhat.com:8080 \\\n  &apos;https:\u002F\u002Fapi.bybit.com\u002Fv5\u002Fmarket\u002Frecent-trade?category=spot&amp;symbol=BTCUSDT&amp;limit=10&apos;\n\n# 验证 SOCKS5 代理\ncurl -x socks5:\u002F\u002Fuser-country-US:YOUR_PASS@gate.proxyhat.com:1080 \\\n  &apos;https:\u002F\u002Fapi.bybit.com\u002Fv5\u002Fmarket\u002Ftickers?category=linear&apos;\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch2>REST 快照 vs WebSocket 实时深度\u003C\u002Fh2>\n\u003Cp>对于需要实时订单簿的交易策略，REST 轮询 \u003Ccode>\u002Fv5\u002Fmarket\u002Forderbook\u003C\u002Fcode> 存在固有局限：每次请求只返回某一时刻的快照，高频轮询容易触发限速。Bybit 同时提供公共 WebSocket 流，其中 \u003Ccode>orderbook.50.{symbol}\u003C\u002Fcode> 推送 50 档深度的增量更新。\u003C\u002Fp>\n\u003Ctable>\n\u003Cthead>\n\u003Ctr>\u003Cth>维度\u003C\u002Fth>\u003Cth>REST \u002Fv5\u002Fmarket\u002Forderbook\u003C\u002Fth>\u003Cth>WebSocket orderbook.50\u003C\u002Fth>\u003C\u002Ftr>\n\u003C\u002Fthead>\n\u003Ctbody>\n\u003Ctr>\u003Ctd>数据类型\u003C\u002Ftd>\u003Ctd>完整快照\u003C\u002Ftd>\u003Ctd>增量更新 + 定期快照\u003C\u002Ftd>\u003C\u002Ftr>\n\u003Ctr>\u003Ctd>延迟\u003C\u002Ftd>\u003Ctd>取决于轮询间隔（通常 200ms-1s）\u003C\u002Ftd>\u003Ctd>~10-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>历史回测、低频监控\u003C\u002Ftd>\u003Ctd>实时交易、做市策略\u003C\u002Ftd>\u003C\u002Ftr>\n\u003C\u002Ftbody>\n\u003C\u002Ftable>\n\u003Cp>WebSocket 连接同样需要通过代理。使用 ProxyHat SOCKS5 代理建立 WebSocket 连接时，建议使用粘性会话避免连接中途断开：\u003C\u002Fp>\n\u003Cpre>\u003Ccode>const WebSocket = require(&apos;ws&apos;);\nconst { SocksProxyAgent } = require(&apos;socks-proxy-agent&apos;);\n\nconst proxyUrl = &apos;socks5:\u002F\u002Fuser-sid-ws-btc-country-US:YOUR_PASS@gate.proxyhat.com:1080&apos;;\nconst agent = new SocksProxyAgent(proxyUrl);\n\nconst ws = new WebSocket(&apos;wss:\u002F\u002Fstream.bybit.com\u002Fv5\u002Fpublic\u002Fspot&apos;, { agent });\n\nws.on(&apos;open&apos;, () =&gt; {\n  ws.send(JSON.stringify({ op: &apos;subscribe&apos;, args: [&apos;orderbook.50.BTCUSDT&apos;] }));\n});\n\nws.on(&apos;message&apos;, (data) =&gt; {\n  const msg = JSON.parse(data);\n  if (msg.topic &amp;&amp; msg.topic.startsWith(&apos;orderbook.50&apos;)) {\n    console.log(&apos;Depth update:&apos;, msg.data);\n  }\n});\n\nws.on(&apos;error&apos;, (err) =&gt; console.error(&apos;WS error:&apos;, err.message));\nws.on(&apos;close&apos;, () =&gt; console.log(&apos;WS closed&apos;));\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch2>常见错误与边界情况\u003C\u002Fh2>\n\u003Cul>\n\u003Cli>忽略 retCode 检查：HTTP 200 不代表成功，必须检查 \u003Ccode>retCode === 0\u003C\u002Fcode>。常见错误码包括 \u003Ccode>10001\u003C\u002Fcode>（参数错误）、\u003Ccode>10010\u003C\u002Fcode>（请求过频）、\u003Ccode>10009\u003C\u002Fcode>（签名无效——公共接口不需要签名）。\u003C\u002Fli>\n\u003Cli>订单簿深度限制：\u003Ccode>limit\u003C\u002Fcode> 参数最大为 200，传入更大值会被截断或返回错误。对于需要完整深度的场景，考虑使用 WebSocket。\u003C\u002Fli>\n\u003Cli>K线时间戳单位：Bybit V5 的 \u003Ccode>start\u003C\u002Fcode>\u002F\u003Ccode>end\u003C\u002Fcode> 参数使用毫秒级时间戳，而非秒级。混淆会导致返回空数据。\u003C\u002Fli>\n\u003Cli>代理认证格式错误：用户名中的 flag 用 \u003Ccode>-\u003C\u002Fcode> 连接，如 \u003Ccode>user-country-US-sid-abc123\u003C\u002Fcode>，顺序不强制但必须用正确分隔符。\u003C\u002Fli>\n\u003Cli>并发请求过多：即使使用不同代理 IP，本地并发过高也可能导致系统资源耗尽。建议控制在 10-20 并发。\u003C\u002Fli>\n\u003Cli>未处理 CloudFront 拦截：地理封锁可能返回 CloudFront 的 HTML 错误页而非 JSON，需检查 \u003Ccode>Content-Type\u003C\u002Fcode> 头。\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Ch2>ProxyHat 配置与最佳实践\u003C\u002Fh2>\n\u003Cp>ProxyHat 住宅代理为 Bybit API 抓取提供了灵活的 IP 轮换能力。以下是生产环境的关键配置建议：\u003C\u002Fp>\n\u003Cul>\n\u003Cli>端点速率预算：将每个 IP 的请求频率控制在 5 req\u002Fs 以下，远低于 Bybit 的封禁阈值。\u003C\u002Fli>\n\u003Cli>IP 轮换策略：对于订单簿等高频端点，使用每次请求轮换（per-request rotation）；对于 K线分页，使用粘性会话。\u003C\u002Fli>\n\u003Cli>重试与退避：遇到 403 或 \u003Ccode>retCode=10010\u003C\u002Fcode> 时，实施指数退避（1s → 2s → 4s → 8s → 16s），并切换到新 IP。\u003C\u002Fli>\n\u003Cli>断路器：连续 3 次 403 后暂停该 IP 10 分钟（匹配 Bybit 封禁窗口），切换到备用 IP 池。\u003C\u002Fli>\n\u003Cli>日志与监控：记录每个请求的代理 IP、响应时间、retCode，用于后续优化和故障排查。\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Cp>查看 \u003Ca href=\"\u002Fcn\u002Fpricing\">ProxyHat 定价方案\u003C\u002Fa> 选择适合你抓取规模的代理套餐，或访问 \u003Ca href=\"https:\u002F\u002Fdocs.proxyhat.com\u002F\" rel=\"noopener noreferrer\">ProxyHat 官方文档\u003C\u002Fa> 了解更多 SDK 用法。更多抓取场景可参考 \u003Ca href=\"\u002Fcn\u002Fuse-cases\u002Fweb-scraping\">Web Scraping 用例\u003C\u002Fa> 和 \u003Ca href=\"\u002Fcn\u002Fuse-cases\u002Fserp-tracking\">SERP 追踪用例\u003C\u002Fa>。\u003C\u002Fp>\n\u003Ch2>关键要点总结\u003C\u002Fh2>\n\u003Cblockquote>\n\u003Cp>核心实践：\u003C\u002Fp>\n\u003Cul>\n\u003Cli>始终检查 \u003Ccode>retCode\u003C\u002Fcode>，不要仅依赖 HTTP 状态码。\u003C\u002Fli>\n\u003Cli>将每 IP 请求频率控制在 5 req\u002Fs 以下，避免触发 10 分钟封禁。\u003C\u002Fli>\n\u003Cli>订单簿等高频端点使用 per-request 轮换，K线分页使用粘性会话。\u003C\u002Fli>\n\u003Cli>地理封锁场景下用 \u003Ccode>-country-US\u003C\u002Fcode> 指定出口国家。\u003C\u002Fli>\n\u003Cli>实时需求优先用 WebSocket，历史数据用 REST + 代理轮换。\u003C\u002Fli>\n\u003Cli>实施指数退避和断路器，而非简单重试。\u003C\u002Fli>\n\u003C\u002Ful>\n\u003C\u002Fblockquote>\n\u003Cp>通过 ProxyHat 轮换住宅代理，你可以在遵守 Bybit 限速规则的前提下，稳定地抓取 V5 市场数据，为交易策略和数据分析提供可靠的数据源。开始构建你的 Bybit 数据管道，请访问 \u003Ca href=\"\u002Fcn\u002Fpricing\">ProxyHat 定价页面\u003C\u002Fa>。\u003C\u002Fp>","用轮换代理采集加密货币市场数据（Bybit V5） | ProxyHat","开发者实战指南：用 ProxyHat 轮换住宅代理抓取 Bybit V5 市场数据 API，涵盖订单簿、Ticker、K线端点限速规避与地理封锁绕过，附可运行代码。","\u002Fcn\u002Fblog\u002Fscrape-bybit-v5-market-api-proxy",null,"用轮换代理采集加密货币市场数据 | ProxyHat","https:\u002F\u002Fstatic.proxyhat.com\u002Fstorage\u002Fblog-covers\u002Fzh\u002Fscrape-bybit-v5-market-api-proxy-og.webp",[18,21,24,27],{"question":19,"answer":20},"如何使用轮换代理抓取 Bybit V5 Market API？","通过 ProxyHat 住宅代理网关 gate.proxyhat.com:8080 接入，在用户名中指定 -country-US 等地理标识，将出口 IP 轮换到 Bybit 允许的地区。代码层面使用 axios 或 requests 配置 HTTPS 代理，对 \u002Fv5\u002Fmarket\u002Forderbook、\u002Fv5\u002Fmarket\u002Ftickers、\u002Fv5\u002Fmarket\u002Fkline 等端点实施每请求轮换 IP，配合指数退避重试和每端点速率预算（建议 5 req\u002Fs 以下），即可稳定抓取公共市场数据。",{"question":22,"answer":23},"为什么抓取 Bybit V5 Market API 需要轮换代理？","Bybit 对公共市场数据端点实施基于 IP 的限速，超出阈值后返回 HTTP 403 并可能封禁 IP 约 10 分钟。同时，来自美国、英国等受限地区的 IP 会直接被 CloudFront 拦截。轮换代理通过在不同 IP 间分配请求，将单 IP 频率控制在限速以下，并通过地理定位绕过区域封锁，确保数据采集的连续性和稳定性。",{"question":25,"answer":26},"抓取 Bybit V5 Market API 用哪种代理类型最好？","住宅代理是最佳选择，因为 Bybit 和 CloudFront 会检测数据中心 IP 并可能直接封锁。住宅代理使用真实 ISP 分配的 IP 地址，更难被识别为自动化流量。ProxyHat 住宅代理通过 gate.proxyhat.com:8080（HTTP）或 :1080（SOCKS5）提供接入，支持国家\u002F城市级地理定位和粘性会话，适合高频 REST 抓取和 WebSocket 长连接场景。",{"question":28,"answer":29},"抓取 Bybit API 时如何避免被封禁？","关键策略包括：将每 IP 请求频率控制在 5 req\u002Fs 以下；遇到 403 或 retCode=10010 时实施指数退避（1s→2s→4s→8s→16s）并切换到新 IP；对订单簿等高频端点使用 per-request 轮换，对 K线分页使用粘性会话保持同一 IP；实施断路器模式，连续 3 次 403 后暂停该 IP 10 分钟；始终检查 retCode 而非仅依赖 HTTP 状态码；实时需求优先使用 WebSocket 而非 REST 轮询。",false,"2026-08-03T16:09:16+00:00","2026-10-04T01:29:51+00:00","https:\u002F\u002Fstatic.proxyhat.com\u002Fstorage\u002Fblog-covers\u002Fzh\u002Fscrape-bybit-v5-market-api-proxy-master.webp","How to Scrape the Bybit V5 Market API with Rotating Proxies","https:\u002F\u002Fstatic.proxyhat.com\u002Fstorage\u002Fblog-covers\u002Fzh\u002Fscrape-bybit-v5-market-api-proxy-card.webp",12,{"name":38,"slug":39,"bio":40,"avatar_url":14,"website_url":14,"social_links":14},"ProxyHat Team","proxyhat-team","The ProxyHat editorial team covers proxies, web scraping, and data extraction.",[42],{"id":43,"slug":44,"name":45,"description":14,"meta_title":46,"meta_description":47,"parent_id":14},4,"kaifa-zhinan","开发者指南","开发者指南 | ProxyHat 博客","代码教程和SDK指南，帮助您将代理集成到应用程序中。",[],{"ko":50,"de":51,"fr":52,"pt":53,"zh":13,"pl":54,"ru":55,"it":56,"es":57,"en":58,"ja":59,"x-default":58},"\u002Fko\u002Fblog\u002Fbybit-v5-market-api-proxy-scraping","\u002Fde\u002Fblog\u002Fbybit-v5-market-api-mit-rotating-proxies-scrapen","\u002Ffr\u002Fblog\u002Fscraper-api-bybit-v5-proxys-rotatifs","\u002Fpt\u002Fblog\u002Fcomo-raspar-bybit-v5-market-api-proxies","\u002Fpl\u002Fblog\u002Fjak-scrapowac-bybit-v5-api-proxy","\u002Fru\u002Fblog\u002Fkak-skrejpit-bybit-v5-market-api","\u002Fit\u002Fblog\u002Fscrape-bybit-v5-market-api-proxy","\u002Fes\u002Fblog\u002Fscrapear-api-mercado-bybit-v5-proxies","\u002Fblog\u002Fscrape-bybit-v5-market-api-rotating-proxies","\u002Fja\u002Fblog\u002Fbybit-v5-market-api-proxy-scraping",{"ko":50,"de":51,"fr":52,"pt":53,"zh":13,"pl":54,"ru":55,"it":56,"es":57,"en":58,"ja":59,"tr":61},"\u002Ftr\u002Fblog\u002Fbybit-v5-market-api-dondurulen-proxy",87,[64,98,125,141],{"id":65,"slug":66,"title":67,"excerpt":68,"featured_image_url":69,"featured_image_alt":70,"card_image_url":71,"og_image_url":72,"published_at":73,"updated_at":74,"content_updated_at":75,"reading_time_minutes":76,"is_featured":30,"indexable":4,"views":77,"author":78,"categories":79,"tags":81},210,"ai-agent-daili-peizhi","AI Agent 代理配置：browser-use、Crawl4AI、MCP","运行在云服务器上的智能体从数据中心 IP 出口。本文给出 browser-use、Crawl4AI 和 MCP 服务器当前可用的代理配置，附粘性与轮换的决策表，以及需要避开的成本陷阱。","https:\u002F\u002Fstatic.proxyhat.com\u002Fstorage\u002Fblog-covers\u002Fzh\u002Fai-agent-daili-peizhi-master.webp","Proxy Setup for AI Agents: browser-use, Crawl4AI and an MCP Server","https:\u002F\u002Fstatic.proxyhat.com\u002Fstorage\u002Fblog-covers\u002Fzh\u002Fai-agent-daili-peizhi-card.webp","https:\u002F\u002Fstatic.proxyhat.com\u002Fstorage\u002Fblog-covers\u002Fzh\u002Fai-agent-daili-peizhi-og.webp","2026-10-24T09:00:00+00:00","2026-10-24T09:00:20+00:00","2026-10-03T09:41:40+00:00",14,15,{"name":38,"slug":39,"bio":40,"avatar_url":14,"website_url":14,"social_links":14},[80],{"id":43,"slug":44,"name":45,"description":14,"meta_title":46,"meta_description":47,"parent_id":14},[82,86,90,94],{"id":83,"slug":84,"name":85},1,"web-scraping","网页抓取",{"id":87,"slug":88,"name":89},2,"residential-proxies","住宅代理",{"id":91,"slug":92,"name":93},9,"python","Python",{"id":95,"slug":96,"name":97},22,"playwright","Playwright",{"id":99,"slug":100,"title":101,"excerpt":102,"featured_image_url":103,"featured_image_alt":104,"card_image_url":105,"og_image_url":106,"published_at":107,"updated_at":108,"content_updated_at":75,"reading_time_minutes":76,"is_featured":30,"indexable":4,"views":109,"author":110,"categories":111,"tags":113},206,"camoufox-zhuzhai-daili-python-zhinan","Camoufox 搭配住宅代理：代码优先的 Python 指南","如何让在 C++ 层打补丁的 Firefox——Camoufox 在住宅代理后运行：当前的 Python API、geoip 为什么需要粘性会话、指纹一致性检查清单，以及何时 Patchright 或 nodriver 更合适。","https:\u002F\u002Fstatic.proxyhat.com\u002Fstorage\u002Fblog-covers\u002Fzh\u002Fcamoufox-zhuzhai-daili-python-zhinan-master.webp","Camoufox with Residential Proxies: A Code-First Python Guide","https:\u002F\u002Fstatic.proxyhat.com\u002Fstorage\u002Fblog-covers\u002Fzh\u002Fcamoufox-zhuzhai-daili-python-zhinan-card.webp","https:\u002F\u002Fstatic.proxyhat.com\u002Fstorage\u002Fblog-covers\u002Fzh\u002Fcamoufox-zhuzhai-daili-python-zhinan-og.webp","2026-10-13T09:00:00+00:00","2026-10-13T09:00:22+00:00",31,{"name":38,"slug":39,"bio":40,"avatar_url":14,"website_url":14,"social_links":14},[112],{"id":43,"slug":44,"name":45,"description":14,"meta_title":46,"meta_description":47,"parent_id":14},[114,115,116,120,121],{"id":83,"slug":84,"name":85},{"id":87,"slug":88,"name":89},{"id":117,"slug":118,"name":119},6,"anti-detection","反检测",{"id":91,"slug":92,"name":93},{"id":122,"slug":123,"name":124},21,"headless-browser","无头浏览器",{"id":126,"slug":127,"title":128,"excerpt":129,"featured_image_url":130,"featured_image_alt":131,"card_image_url":132,"og_image_url":133,"published_at":134,"updated_at":134,"content_updated_at":135,"reading_time_minutes":36,"is_featured":30,"indexable":4,"views":136,"author":137,"categories":138,"tags":140},176,"got-scraping-nodejs-proxy-guide","Node.js 中的 got-scraping 完整指南：头部生成与住宅代理实战","深入解析 Apify 的 got-scraping 库——从 header-generator 生成连贯浏览器头部、HTTP\u002F2 支持，到通过 ProxyHat 住宅代理实现大规模 Node.js 爬虫。包含可运行代码、重试钩子、并发控制与生产模式最佳实践。","https:\u002F\u002Fstatic.proxyhat.com\u002Fstorage\u002Fblog-covers\u002Fzh\u002Fgot-scraping-nodejs-proxy-guide-master.webp","got-scraping in Node.js: A Developer's Guide with Residential Proxies","https:\u002F\u002Fstatic.proxyhat.com\u002Fstorage\u002Fblog-covers\u002Fzh\u002Fgot-scraping-nodejs-proxy-guide-card.webp","https:\u002F\u002Fstatic.proxyhat.com\u002Fstorage\u002Fblog-covers\u002Fzh\u002Fgot-scraping-nodejs-proxy-guide-og.webp","2026-08-04T16:05:06+00:00","2026-10-03T08:29:58+00:00",121,{"name":38,"slug":39,"bio":40,"avatar_url":14,"website_url":14,"social_links":14},[139],{"id":43,"slug":44,"name":45,"description":14,"meta_title":46,"meta_description":47,"parent_id":14},[],{"id":142,"slug":143,"title":144,"excerpt":145,"featured_image_url":146,"featured_image_alt":147,"card_image_url":148,"og_image_url":149,"published_at":150,"updated_at":150,"content_updated_at":151,"reading_time_minutes":36,"is_featured":30,"indexable":30,"views":152,"author":153,"categories":154,"tags":156},175,"colly-lunhuan-daili-shixian-zhinan","Colly轮换代理完整指南：用Go构建高吞吐爬虫的实战方案","深入讲解如何在Go的Colly框架中实现代理轮换，涵盖RoundRobinProxySwitcher、SetProxyFunc自定义函数、住宅代理地理定位与会话保持、生产级重试与并发控制，以及分布式存储后端等核心模式。","https:\u002F\u002Fstatic.proxyhat.com\u002Fstorage\u002Fblog-covers\u002Fzh\u002Fcolly-lunhuan-daili-shixian-zhinan-master.webp","Rotating Proxies in Colly: A Framework-Idiomatic Guide for Go Developers","https:\u002F\u002Fstatic.proxyhat.com\u002Fstorage\u002Fblog-covers\u002Fzh\u002Fcolly-lunhuan-daili-shixian-zhinan-card.webp","https:\u002F\u002Fstatic.proxyhat.com\u002Fstorage\u002Fblog-covers\u002Fzh\u002Fcolly-lunhuan-daili-shixian-zhinan-og.webp","2026-08-04T10:05:34+00:00","2026-10-03T08:29:56+00:00",71,{"name":38,"slug":39,"bio":40,"avatar_url":14,"website_url":14,"social_links":14},[155],{"id":43,"slug":44,"name":45,"description":14,"meta_title":46,"meta_description":47,"parent_id":14},[],[]]