[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"blog-post-ru-kak-skrejpit-bybit-v5-market-api":3},{"success":4,"payload":5,"related":64,"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":16,"og_image_url":17,"faq_json":18,"key_takeaways":14,"allow_index":4,"noindex_google_only":31,"allow_follow":4,"published_at":32,"updated_at":32,"content_updated_at":33,"featured_image_url":34,"featured_image_alt":35,"card_image_url":36,"reading_time_minutes":37,"author":38,"categories":42,"tags":49,"alternates":50,"locale_paths":61,"views":63},195,"kak-skrejpit-bybit-v5-market-api","Сбор рыночных данных криптобирж через ротационные прокси: руководство разработчика (на примере Bybit V5 Market API)","Практическое руководство по скрейпингу публичных эндпоинтов Bybit V5 Market API (orderbook, tickers, kline, recent-trade) с ротационными residential-прокси через gate.proxyhat.com. Примеры на Python и Node.js, обработка rate limit, 403-банов и geo-блокировок.","\u003Cp>\u003Cstrong>Внимание:\u003C\u002Fstrong> данное руководство охватывает только \u003Cem>публичные\u003C\u002Fem> рыночные данные Bybit V5 API. Убедитесь, что ваше использование соответствует \u003Ca href=\"https:\u002F\u002Fwww.bybit.com\u002Fen-US\u002Fterms\" rel=\"noopener noreferrer\">Условиям обслуживания Bybit\u003C\u002Fa> и применимому законодательству. Не скрейпьте приватные или аутентифицированные эндпоинты без явного разрешения.\u003C\u002Fp>\n\u003Cp>Скрейпинг Bybit V5 Market API через ротационные прокси — это техника сбора публичных рыночных данных (стаканы, тикеры, свечи, последние сделки) с эндпоинтов \u003Ccode>api.bybit.com\u002Fv5\u002Fmarket\u002F*\u003C\u002Fcode> при помощи пула \u003Ca href=\"\u002Fru\u002Fproxy\u002Fresidential\">residential-IP\u003C\u002Fa>, которые ротируются между запросами для обхода IP-based rate limit и geo-блокировок. В этом руководстве мы разберём маппинг эндпоинтов, формат ответа, лимиты, блокировки и дадим минимум пять runnable-примеров на Python и Node.js.\u003C\u002Fp>\n\n\u003Ch2>Карта публичных эндпоинтов Bybit V5 Market API\u003C\u002Fh2>\n\u003Cp>Bybit V5 API объединяет spot, linear и inverse рынки под единым базовым URL \u003Ccode>api.bybit.com\u003C\u002Fcode>. Все рыночные эндпоинты находятся под префиксом \u003Ccode>\u002Fv5\u002Fmarket\u002F\u003C\u002Fcode> и не требуют аутентификации. Ключевой параметр — \u003Ccode>category\u003C\u002Fcode>, который принимает значения \u003Ccode>spot\u003C\u002Fcode>, \u003Ccode>linear\u003C\u002Fcode> или \u003Ccode>option\u003C\u002Fcode>.\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>\u002Fv5\u002Fmarket\u002Forderbook\u003C\u002Fcode>\u003C\u002Ftd>\u003Ctd>GET\u003C\u002Ftd>\u003Ctd>\u003Ccode>category\u003C\u002Fcode>, \u003Ccode>symbol\u003C\u002Fcode>, \u003Ccode>limit\u003C\u002Fcode> (25\u002F50\u002F100\u002F200\u002F500)\u003C\u002Ftd>\u003Ctd>Снимок стакана заявок\u003C\u002Ftd>\u003C\u002Ftr>\n\u003Ctr>\u003Ctd>\u003Ccode>\u002Fv5\u002Fmarket\u002Ftickers\u003C\u002Fcode>\u003C\u002Ftd>\u003Ctd>GET\u003C\u002Ftd>\u003Ctd>\u003Ccode>category\u003C\u002Fcode>, опционально \u003Ccode>symbol\u003C\u002Fcode>\u003C\u002Ftd>\u003Ctd>Список тикеров с lastPrice, volume24h и т.д.\u003C\u002Ftd>\u003C\u002Ftr>\n\u003Ctr>\u003Ctd>\u003Ccode>\u002Fv5\u002Fmarket\u002Fkline\u003C\u002Fcode>\u003C\u002Ftd>\u003Ctd>GET\u003C\u002Ftd>\u003Ctd>\u003Ccode>category\u003C\u002Fcode>, \u003Ccode>symbol\u003C\u002Fcode>, \u003Ccode>interval\u003C\u002Fcode>, \u003Ccode>limit\u003C\u002Fcode>, \u003Ccode>cursor\u003C\u002Fcode>\u003C\u002Ftd>\u003Ctd>Исторические свечи (OHLCV)\u003C\u002Ftd>\u003C\u002Ftr>\n\u003Ctr>\u003Ctd>\u003Ccode>\u002Fv5\u002Fmarket\u002Frecent-trade\u003C\u002Fcode>\u003C\u002Ftd>\u003Ctd>GET\u003C\u002Ftd>\u003Ctd>\u003Ccode>category\u003C\u002Fcode>, \u003Ccode>symbol\u003C\u002Fcode>, \u003Ccode>limit\u003C\u002Fcode> (max 1000)\u003C\u002Ftd>\u003Ctd>Последние сделки\u003C\u002Ftd>\u003C\u002Ftr>\n\u003C\u002Ftbody>\n\u003C\u002Ftable>\n\n\u003Cp>Все ответы V5 API используют единый конверт. Поле \u003Ccode>retCode\u003C\u002Fcode> равно \u003Ccode>0\u003C\u002Fcode> при успехе; ненулевое значение означает ошибку, текст которой находится в \u003Ccode>retMsg\u003C\u002Fcode>. Данные — в \u003Ccode>result\u003C\u002Fcode>. Всегда проверяйте \u003Ccode>retCode\u003C\u002Fcode> перед обработкой \u003Ccode>result\u003C\u002Fcode>, иначе можно silently получить пустой результат.\u003C\u002Fp>\n\n\u003Ch3>Пример 1: curl с raw-прокси — снимок стакана\u003C\u002Fh3>\n\u003Cpre>\u003Ccode>curl -x http:\u002F\u002Fuser-country-DE:pass@gate.proxyhat.com:8080 \\\n  &quot;https:\u002F\u002Fapi.bybit.com\u002Fv5\u002Fmarket\u002Forderbook?category=spot&amp;symbol=BTCUSDT&amp;limit=50&quot;\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>Параметр \u003Ccode>-country-DE\u003C\u002Fcode> в username указывает ProxyHat выдать немецкий residential-IP. Порт \u003Ccode>8080\u003C\u002Fcode> — стандартный HTTP-шлюз. Ответ содержит \u003Ccode>b\u003C\u002Fcode> (bids) и \u003Ccode>a\u003C\u002Fcode> (asks) — массивы пар [цена, размер].\u003C\u002Fp>\n\n\u003Ch2>Rate limit и IP-баны: почему bursts на orderbook опасны\u003C\u002Fh2>\n\u003Cp>Bybit применяет IP-based rate limit на каждый эндпоинт. Для \u003Ccode>\u002Fv5\u002Fmarket\u002Forderbook\u003C\u002Fcode> лимит составляет примерно 50–120 запросов в секунду на IP (точное значение зависит от категории и нагрузки). При превышении API возвращает HTTP 403 или 429, а при повторных нарушениях IP может попасть в бан на ~10 минут.\u003C\u002Fp>\n\u003Cp>Проблема усугубляется тем, что orderbook — самый «жадный» эндпоинт: разработчики часто опрашивают его в цикле с малым интервалом для построения локального стакана. Burst из 200+ запросов за секунду с одного IP почти гарантированно вызывает 403. Решение — ротация IP между запросами через residential-прокси, чтобы каждый запрос шёл с нового IP с собственным rate budget.\u003C\u002Fp>\n\n\u003Ch3>Пример 2: Python requests с raw-прокси — тикеры\u003C\u002Fh3>\n\u003Cpre>\u003Ccode>import requests\n\nproxy_url = &quot;http:\u002F\u002Fuser-country-DE:pass@gate.proxyhat.com:8080&quot;\nproxies = {&quot;http&quot;: proxy_url, &quot;https&quot;: proxy_url}\n\nresp = requests.get(\n    &quot;https:\u002F\u002Fapi.bybit.com\u002Fv5\u002Fmarket\u002Ftickers&quot;,\n    params={&quot;category&quot;: &quot;linear&quot;},\n    proxies=proxies,\n    timeout=10,\n)\ndata = resp.json()\nif data[&quot;retCode&quot;] != 0:\n    raise Exception(f&quot;Bybit error: {data[&apos;retMsg&apos;]}&quot;)\nprint(f&quot;Tickers returned: {data[&apos;result&apos;][&apos;tickerCount&apos;]}&quot;)\nfor t in data[&quot;result&quot;][&quot;list&quot;][:3]:\n    print(t[&quot;symbol&quot;], t[&quot;lastPrice&quot;])\u003C\u002Fcode>\u003C\u002Fpre>\n\n\u003Ch2>Geo-блокировки: 403 и CloudFront\u003C\u002Fh2>\n\u003Cp>Bybit ограничивает доступ из ряда юрисдикций, включая США, Великобританию и другие регионы. Запросы из заблокированных IP получают HTTP 403 или блокируются на уровне CloudFront (AWS CDN), который Bybit использует для защиты. Это значит, что datacenter-IP из США почти всегда получит 403, даже если rate limit не превышен.\u003C\u002Fp>\n\u003Cp>Residential-прокси решают эту задачу: запрос маршрутизируется через реальный домашний IP из разрешённой страны (например, Германия или Япония). ProxyHat поддерживает geo-таргетинг через username-флаг \u003Ccode>-country-XX\u003C\u002Fcode>. Для город-уровня используйте \u003Ccode>-country-DE-region-state_of_berlin-city-berlin\u003C\u002Fcode>. Подробнее о доступных локациях — на странице \u003Ca href=\"\u002Fru\u002Flocations\">локаций ProxyHat\u003C\u002Fa>.\u003C\u002Fp>\n\n\u003Ch3>Пример 3: Node.js (axios) с ротацией IP через ProxyHat SDK\u003C\u002Fh3>\n\u003Cpre>\u003Ccode>const axios = require(&apos;axios&apos;);\nconst { HttpsProxyAgent } = require(&apos;https-proxy-agent&apos;);\nconst { ProxyHat } = require(&apos;@proxyhat\u002Fsdk&apos;);\n\nconst ph = new ProxyHat({ username: &apos;user&apos;, password: &apos;pass&apos; });\nconst symbols = [&apos;BTCUSDT&apos;, &apos;ETHUSDT&apos;, &apos;SOLUSDT&apos;, &apos;XRPUSDT&apos;, &apos;DOGEUSDT&apos;];\n\nasync function fetchTicker(symbol) {\n  \u002F\u002F Каждый вызов getHttpUrl выдаёт новый residential-IP\n  const proxyUrl = ph.getHttpUrl({ country: &apos;DE&apos; });\n  const agent = new HttpsProxyAgent(proxyUrl);\n  const { data } = await axios.get(\n    &apos;https:\u002F\u002Fapi.bybit.com\u002Fv5\u002Fmarket\u002Ftickers&apos;,\n    {\n      params: { category: &apos;spot&apos;, symbol },\n      httpsAgent: agent,\n      proxy: false,\n      timeout: 10000,\n    }\n  );\n  if (data.retCode !== 0) throw new Error(data.retMsg);\n  return data.result.list[0];\n}\n\n(async () =&gt; {\n  for (const sym of symbols) {\n    try {\n      const t = await fetchTicker(sym);\n      console.log(sym, t?.lastPrice);\n    } catch (e) {\n      console.error(sym, e.message);\n    }\n    await new Promise(r =&gt; setTimeout(r, 200)); \u002F\u002F soft pacing\n  }\n})();\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>Здесь каждый символ запрашивается с нового IP. Задержка 200ms — мягкий pacing для вежливого скрейпинга; при использовании ротационных прокси её можно сократить, но не убирать полностью.\u003C\u002Fp>\n\n\u003Ch2>Sticky-сессии для пагинации kline\u003C\u002Fh2>\n\u003Cp>Эндпоинт \u003Ccode>\u002Fv5\u002Fmarket\u002Fkline\u003C\u002Fcode> поддерживает пагинацию через параметр \u003Ccode>cursor\u003C\u002Fcode>, возвращаемый в \u003Ccode>result.nextPageCursor\u003C\u002Fcode>. Для консистентности пагинации полезно сохранять один IP на всю серию запросов — это даёт sticky-сессия через флаг \u003Ccode>-sid-ID\u003C\u002Fcode> в username ProxyHat.\u003C\u002Fp>\n\n\u003Ch3>Пример 4: Python — пагинация kline со sticky-сессией\u003C\u002Fh3>\n\u003Cpre>\u003Ccode>import requests\nimport time\n\ndef fetch_klines_paginated(symbol, interval=&quot;60&quot;, max_pages=5):\n    session_id = f&quot;kl-{symbol}-{int(time.time())}&quot;\n    proxy_url = (\n        f&quot;http:\u002F\u002Fuser-country-DE-sid-{session_id}:pass@gate.proxyhat.com:8080&quot;\n    )\n    proxies = {&quot;http&quot;: proxy_url, &quot;https&quot;: proxy_url}\n\n    all_candles = []\n    cursor = None\n    for page in range(max_pages):\n        params = {\n            &quot;category&quot;: &quot;spot&quot;,\n            &quot;symbol&quot;: symbol,\n            &quot;interval&quot;: interval,\n            &quot;limit&quot;: 1000,\n        }\n        if cursor:\n            params[&quot;cursor&quot;] = cursor\n\n        resp = requests.get(\n            &quot;https:\u002F\u002Fapi.bybit.com\u002Fv5\u002Fmarket\u002Fkline&quot;,\n            params=params,\n            proxies=proxies,\n            timeout=10,\n        )\n        data = resp.json()\n        if data[&quot;retCode&quot;] != 0:\n            raise Exception(f&quot;API error: {data[&apos;retMsg&apos;]}&quot;)\n\n        result = data[&quot;result&quot;]\n        all_candles.extend(result[&quot;list&quot;])\n        cursor = result.get(&quot;nextPageCursor&quot;)\n        if not cursor:\n            break\n        time.sleep(0.15)\n\n    return all_candles\n\ncandles = fetch_klines_paginated(&quot;BTCUSDT&quot;)\nprint(f&quot;Fetched {len(candles)} candles&quot;)\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>Sticky-сессия гарантирует, что все страницы пагинации идут с одного residential-IP, что снижает риск рассинхронизации данных и уменьшает количество уникальных IP в логах Bybit.\u003C\u002Fp>\n\n\u003Ch2>Production-паттерны: retries, backoff, rate budgeting\u003C\u002Fh2>\n\u003Cp>В продакшене нужен комплексный подход: экспоненциальный backoff при 429\u002F5xx, per-endpoint rate budget, circuit breaker при серии 403 и логирование. Ниже — класс на Python с интеграцией urllib3 Retry и ручным rate budget для orderbook.\u003C\u002Fp>\n\n\u003Ch3>Пример 5: Python — retries, backoff, per-endpoint rate budget\u003C\u002Fh3>\n\u003Cpre>\u003Ccode>import requests\nimport time\nimport logging\nfrom requests.adapters import HTTPAdapter\nfrom urllib3.util.retry import Retry\n\nlogging.basicConfig(level=logging.INFO)\nlogger = logging.getLogger(&quot;bybit-scraper&quot;)\n\nclass BybitScraper:\n    BASE_URL = &quot;https:\u002F\u002Fapi.bybit.com&quot;\n    ORDERBOOK_BUDGET = 0.25  # 4 req\u002Fs per IP\n\n    def __init__(self, proxy_user, proxy_pass, country=&quot;DE&quot;):\n        self.proxy_url = (\n            f&quot;http:\u002F\u002F{proxy_user}-country-{country}:{proxy_pass}&quot;\n            f&quot;@gate.proxyhat.com:8080&quot;\n        )\n        self.proxies = {&quot;http&quot;: self.proxy_url, &quot;https&quot;: self.proxy_url}\n        self.session = requests.Session()\n        retry = Retry(\n            total=5,\n            backoff_factor=1.5,\n            status_forcelist=[429, 500, 502, 503],\n            allowed_methods=[&quot;GET&quot;],\n        )\n        adapter = HTTPAdapter(max_retries=retry)\n        self.session.mount(&quot;https:\u002F\u002F&quot;, adapter)\n        self.session.mount(&quot;http:\u002F\u002F&quot;, adapter)\n        self._last_ob_ts = 0.0\n\n    def _rate_limit(self, budget):\n        elapsed = time.time() - self._last_ob_ts\n        wait = budget - elapsed\n        if wait &gt; 0:\n            time.sleep(wait)\n        self._last_ob_ts = time.time()\n\n    def get_orderbook(self, symbol, category=&quot;spot&quot;, depth=50):\n        self._rate_limit(self.ORDERBOOK_BUDGET)\n        resp = self.session.get(\n            f&quot;{self.BASE_URL}\u002Fv5\u002Fmarket\u002Forderbook&quot;,\n            params={&quot;category&quot;: category, &quot;symbol&quot;: symbol, &quot;limit&quot;: depth},\n            proxies=self.proxies,\n            timeout=10,\n        )\n        if resp.status_code == 403:\n            logger.warning(&quot;403 — IP ban or geo-block, rotate proxy&quot;)\n            raise Exception(&quot;IP blocked&quot;)\n        data = resp.json()\n        if data[&quot;retCode&quot;] != 0:\n            raise Exception(f&quot;retCode={data[&apos;retCode&apos;]}: {data[&apos;retMsg&apos;]}&quot;)\n        return data[&quot;result&quot;]\n\nscraper = BybitScraper(&quot;user&quot;, &quot;pass&quot;, country=&quot;DE&quot;)\nob = scraper.get_orderbook(&quot;BTCUSDT&quot;)\nprint(f&quot;Bids: {len(ob[&apos;b&apos;])}, Asks: {len(ob[&apos;a&apos;])}&quot;)\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>Ключевые моменты: \u003Ccode>backoff_factor=1.5\u003C\u002Fcode> даёт задержки 1.5s, 2.25s, 3.375s и т.д. \u003Ccode>ORDERBOOK_BUDGET = 0.25\u003C\u002Fcode> ограничивает частоту до ~4 запросов в секунду на IP — безопасно ниже лимита Bybit. При 403 логируется предупреждение и поднимается исключение для rotation на уровне вызывающего кода.\u003C\u002Fp>\n\n\u003Ch2>REST-снимки vs WebSocket orderbook.50\u003C\u002Fh2>\n\u003Cp>REST-эндпоинт \u003Ccode>\u002Fv5\u002Fmarket\u002Forderbook\u003C\u002Fcode> возвращает \u003Cem>снимок\u003C\u002Fem> стакана на момент запроса. Для live-обновлений Bybit предоставляет публичный WebSocket \u003Ccode>wss:\u002F\u002Fstream.bybit.com\u002Fv5\u002Fpublic\u002Fspot\u003C\u002Fcode> с топиком \u003Ccode>orderbook.50.BTCUSDT\u003C\u002Fcode>, который пушит дельты стакана в реальном времени. WebSocket не подвержен IP-based rate limit на эндпоинты REST, но соединение всё равно может быть geo-заблокировано.\u003C\u002Fp>\n\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>~100–300ms на запрос\u003C\u002Ftd>\u003Ctd>&lt;50ms (push)\u003C\u002Ftd>\u003C\u002Ftr>\n\u003Ctr>\u003Ctd>Rate limit\u003C\u002Ftd>\u003Ctd>IP-based, ~50–120 req\u002Fs\u003C\u002Ftd>\u003Ctd>Ограничение на подписки\u002Fсообщения\u003C\u002Ftd>\u003C\u002Ftr>\n\u003Ctr>\u003Ctd>Geo-блок\u003C\u002Ftd>\u003Ctd>Да, 403\u002FCloudFront\u003C\u002Ftd>\u003Ctd>Да, на уровне соединения\u003C\u002Ftd>\u003C\u002Ftr>\n\u003Ctr>\u003Ctd>Использование прокси\u003C\u002Ftd>\u003Ctd>HTTP-прокси (8080)\u003C\u002Ftd>\u003Ctd>SOCKS5 (1080) для ws:\u002F\u002F\u003C\u002Ftd>\u003C\u002Ftr>\n\u003C\u002Ftbody>\n\u003C\u002Ftable>\n\n\u003Ch3>Пример 6: WebSocket orderbook.50 через SOCKS5-прокси\u003C\u002Fh3>\n\u003Cpre>\u003Ccode>import asyncio\nimport json\nimport socks\nimport websockets\n\nasync def stream_orderbook():\n    # SOCKS5-прокси для WebSocket-соединения\n    proxy_url = &quot;socks5:\u002F\u002Fuser-country-DE:pass@gate.proxyhat.com:1080&quot;\n    uri = &quot;wss:\u002F\u002Fstream.bybit.com\u002Fv5\u002Fpublic\u002Fspot&quot;\n\n    async with websockets.connect(\n        uri,\n        proxy=proxy_url,\n        ping_interval=20,\n    ) as ws:\n        await ws.send(json.dumps({\n            &quot;op&quot;: &quot;subscribe&quot;,\n            &quot;args&quot;: [&quot;orderbook.50.BTCUSDT&quot;],\n        }))\n        while True:\n            msg = json.loads(await ws.recv())\n            if msg.get(&quot;type&quot;) == &quot;snapshot&quot; and &quot;data&quot; in msg:\n                bids = msg[&quot;data&quot;].get(&quot;b&quot;, [])\n                if bids:\n                    print(f&quot;Top bid: {bids[0]}&quot;)\n\nasyncio.run(stream_orderbook())\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>Для WebSocket используйте SOCKS5-порт \u003Ccode>1080\u003C\u002Fcode> ProxyHat. Это позволяет проксировать долгоживущие TCP-соединения через residential-IP. Если соединение разрывается из-за ротации IP, реализуйте reconnect-логику с повторной подпиской.\u003C\u002Fp>\n\n\u003Ch2>Типичные ошибки и edge cases\u003C\u002Fh2>\n\u003Cul>\n\u003Cli>\u003Cstrong>Игнорирование retCode.\u003C\u002Fstrong> API может вернуть HTTP 200 с \u003Ccode>retCode=10001\u003C\u002Fcode> (invalid symbol) и пустым \u003Ccode>result\u003C\u002Fcode>. Всегда проверяйте \u003Ccode>retCode == 0\u003C\u002Fcode>.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>Превышение limit на orderbook.\u003C\u002Fstrong> Параметр \u003Ccode>limit\u003C\u002Fcode> принимает только значения 25, 50, 100, 200, 500. Передача 1000 вызовет ошибку.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>CloudFront 403 без retMsg.\u003C\u002Fstrong> При geo-блоке CloudFront может вернуть HTML-страницу, а не JSON. Парсите \u003Ccode>resp.status_code\u003C\u002Fcode> перед \u003Ccode>resp.json()\u003C\u002Fcode>.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>Слишком частая ротация для kline.\u003C\u002Fstrong> Если менять IP на каждый запрос пагинации, cursor может оказаться невалидным для нового IP. Используйте sticky-сессии.\u003C\u002Fli>\n\u003Cli>Отсутствие timeout. Residential-прокси могут иметь задержку 200–800ms. Без timeout запрос зависнет. Всегда ставьте \u003Ccode>timeout=10\u003C\u002Fcode>.\u003C\u002Fli>\n\u003C\u002Ful>\n\n\u003Ch2>Настройка ProxyHat и внутренние ссылки\u003C\u002Fh2>\n\u003Cp>Для начала работы зарегистрируйтесь в \u003Ca href=\"\u002Fru\u002Fblog\">дашборде ProxyHat\u003C\u002Fa> и получите credentials. Residential-прокси поддерживают geo-таргетинг по стране и городу, sticky-сессии и ротацию. Для скрейпинга рыночных данных рекомендуется residential-тип — он реже блокируется CloudFront, чем datacenter-IP.\u003C\u002Fp>\n\u003Cul>\n\u003Cli>\u003Ca href=\"\u002Fru\u002Fpricing\">Тарифы ProxyHat\u003C\u002Fa> — выберите план под объём запросов.\u003C\u002Fli>\n\u003Cli>\u003Ca href=\"\u002Fru\u002Fuse-cases\u002Fweb-scraping\">Use-case: web scraping\u003C\u002Fa> — общие паттерны скрейпинга.\u003C\u002Fli>\n\u003Cli>\u003Ca href=\"\u002Fru\u002Fuse-cases\u002Fserp-tracking\">Use-case: SERP tracking\u003C\u002Fa> — если нужен параллельный сбор поисковых данных.\u003C\u002Fli>\n\u003Cli>\u003Ca href=\"\u002Fru\u002Flocations\">Локации прокси\u003C\u002Fa> — список доступных стран и городов.\u003C\u002Fli>\n\u003Cli>\u003Ca href=\"https:\u002F\u002Fdocs.proxyhat.com\u002F\" rel=\"noopener noreferrer\">Документация ProxyHat\u003C\u002Fa> — полные спецификации SDK и API.\u003C\u002Fli>\n\u003C\u002Ful>\n\n\u003Ch2>Key Takeaways\u003C\u002Fh2>\n\u003Cblockquote>\n\u003Cp>• Bybit V5 Market API использует единый конверт с \u003Ccode>retCode\u003C\u002Fcode>\u002F\u003Ccode>retMsg\u003C\u002Fcode> — всегда проверяйте retCode перед обработкой result.\u003Cbr>\n• IP-based rate limit на orderbook — ~50–120 req\u002Fs; превышение даёт 403 и ~10-минутный бан.\u003Cbr>\n• Geo-блокировки (US\u002FUK) реализуются через CloudFront 403; residential-прокси с \u003Ccode>-country-DE\u003C\u002Fcode> решают задачу.\u003Cbr>\n• Sticky-сессии (\u003Ccode>-sid-ID\u003C\u002Fcode>) нужны для консистентной пагинации kline.\u003Cbr>\n• WebSocket \u003Ccode>orderbook.50\u003C\u002Fcode> — для live-данных; используйте SOCKS5-порт 1080.\u003Cbr>\n• Production-код: retries с backoff, per-endpoint rate budget, timeout=10s, логирование 403.\u003C\u002Fp>\n\u003C\u002Fblockquote>","Данные криптобирж через ротационные прокси (Bybit V5) | ProxyHat","Узнайте, как скрейпить Bybit V5 Market API (orderbook, tickers, kline) через ротационные residential-прокси gate.proxyhat.com. Примеры кода, rate limit, geo-блокировки.","\u002Fru\u002Fblog\u002Fkak-skrejpit-bybit-v5-market-api",null,"Рыночные данные криптобирж через ротационные прокси | ProxyHat","Руководство разработчика: Bybit V5 Market API, ротационные прокси, rate limit, geo-блокировки, примеры на Python и Node.js.","https:\u002F\u002Fstatic.proxyhat.com\u002Fstorage\u002Fblog-covers\u002Fru\u002Fkak-skrejpit-bybit-v5-market-api-og.webp",[19,22,25,28],{"question":20,"answer":21},"Зачем нужны ротационные прокси для Bybit V5 Market API?","Bybit применяет IP-based rate limit (50–120 req\u002Fs на orderbook) и geo-блокировки через CloudFront. Без ротации серия запросов с одного IP быстро получает 403 и бан на ~10 минут. Ротационные residential-прокси дают каждому запросу отдельный IP с собственным rate budget, а geo-таргетинг обходит региональные блокировки.",{"question":23,"answer":24},"Какой тип прокси лучше для скрейпинга Bybit V5 Market API?","Residential-прокси. Datacenter-IP часто блокируются CloudFront, особенно из США и Великобритании. Residential-IP выглядят как реальные пользовательские подключения из разрешённых стран, что снижает риск 403. Mobile-прокси тоже работают, но обычно дороже и медленнее. Для WebSocket-потоков используйте SOCKS5-порт 1080.",{"question":26,"answer":27},"Как избежать блокировок при скрейпинге Bybit V5 Market API?","Используйте ротационные residential-прокси с geo-таргетингом на разрешённую страну, соблюдайте per-endpoint rate budget (не более 4–10 req\u002Fs на IP для orderbook), реализуйте retries с экспоненциальным backoff, проверяйте \u003Ccode>retCode\u003C\u002Fcode> в каждом ответе, и используйте sticky-сессии для пагинации. Логируйте все 403-ответы для мониторинга качества IP-пула.",{"question":29,"answer":30},"Можно ли использовать WebSocket вместо REST для стакана Bybit?","Да. Поток orderbook.50.BTCUSDT через wss:\u002F\u002Fstream.bybit.com\u002Fv5\u002Fpublic\u002Fspot пушит дельты стакана с задержкой менее 50ms, что быстрее REST-снимков. Для проксирования WebSocket используйте SOCKS5-порт 1080 ProxyHat. При ротации IP долгоживущее соединение может разорваться — реализуйте reconnect с повторной подпиской.",false,"2026-08-03T16:09:16+00:00","2026-10-04T01:29:51+00:00","https:\u002F\u002Fstatic.proxyhat.com\u002Fstorage\u002Fblog-covers\u002Fru\u002Fkak-skrejpit-bybit-v5-market-api-master.webp","How to Scrape the Bybit V5 Market API with Rotating Proxies","https:\u002F\u002Fstatic.proxyhat.com\u002Fstorage\u002Fblog-covers\u002Fru\u002Fkak-skrejpit-bybit-v5-market-api-card.webp",12,{"name":39,"slug":40,"bio":41,"avatar_url":14,"website_url":14,"social_links":14},"ProxyHat Team","proxyhat-team","The ProxyHat editorial team covers proxies, web scraping, and data extraction.",[43],{"id":44,"slug":45,"name":46,"description":14,"meta_title":47,"meta_description":48,"parent_id":14},4,"rukovodstva-dlya-razrabotchikov","Руководства для разработчиков","Руководства для разработчиков | Блог ProxyHat","Туториалы по коду и SDK для интеграции прокси в ваши приложения.",[],{"de":51,"fr":52,"it":53,"ko":54,"pt":55,"zh":56,"ru":13,"pl":57,"es":58,"en":59,"ja":60,"x-default":59},"\u002Fde\u002Fblog\u002Fbybit-v5-market-api-mit-rotating-proxies-scrapen","\u002Ffr\u002Fblog\u002Fscraper-api-bybit-v5-proxys-rotatifs","\u002Fit\u002Fblog\u002Fscrape-bybit-v5-market-api-proxy","\u002Fko\u002Fblog\u002Fbybit-v5-market-api-proxy-scraping","\u002Fpt\u002Fblog\u002Fcomo-raspar-bybit-v5-market-api-proxies","\u002Fcn\u002Fblog\u002Fscrape-bybit-v5-market-api-proxy","\u002Fpl\u002Fblog\u002Fjak-scrapowac-bybit-v5-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",{"de":51,"fr":52,"it":53,"ko":54,"pt":55,"zh":56,"ru":13,"pl":57,"es":58,"en":59,"ja":60,"tr":62},"\u002Ftr\u002Fblog\u002Fbybit-v5-market-api-dondurulen-proxy",87,[65,98,125,141],{"id":66,"slug":67,"title":68,"excerpt":69,"featured_image_url":70,"featured_image_alt":71,"card_image_url":72,"og_image_url":73,"published_at":74,"updated_at":75,"content_updated_at":76,"reading_time_minutes":77,"is_featured":31,"indexable":4,"views":77,"author":78,"categories":79,"tags":81},210,"nastrojka-proksi-dlya-ai-agentov","Прокси для AI-агентов: browser-use, Crawl4AI и MCP-сервер","Агенты на облачных виртуалках выходят в сеть с IP дата-центров. Даём актуальную рабочую настройку прокси для browser-use, Crawl4AI и MCP-сервера, таблицу выбора между sticky и ротацией и разбираем ловушки, на которых сгорает бюджет.","https:\u002F\u002Fstatic.proxyhat.com\u002Fstorage\u002Fblog-covers\u002Fru\u002Fnastrojka-proksi-dlya-ai-agentov-master.webp","Proxy Setup for AI Agents: browser-use, Crawl4AI and an MCP Server","https:\u002F\u002Fstatic.proxyhat.com\u002Fstorage\u002Fblog-covers\u002Fru\u002Fnastrojka-proksi-dlya-ai-agentov-card.webp","https:\u002F\u002Fstatic.proxyhat.com\u002Fstorage\u002Fblog-covers\u002Fru\u002Fnastrojka-proksi-dlya-ai-agentov-og.webp","2026-10-24T09:00:00+00:00","2026-10-24T09:00:20+00:00","2026-10-03T09:41:40+00:00",14,{"name":39,"slug":40,"bio":41,"avatar_url":14,"website_url":14,"social_links":14},[80],{"id":44,"slug":45,"name":46,"description":14,"meta_title":47,"meta_description":48,"parent_id":14},[82,86,90,94],{"id":83,"slug":84,"name":85},1,"veb-skraping","Веб-скрапинг",{"id":87,"slug":88,"name":89},2,"rezidentskie-proksi","Резидентские прокси",{"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":76,"reading_time_minutes":77,"is_featured":31,"indexable":4,"views":109,"author":110,"categories":111,"tags":113},206,"camoufox-rezidentnye-proksi-python","Camoufox с резидентными прокси: практическое руководство на Python","Как запустить Camoufox — Firefox с патчами на C++ — за резидентными прокси: актуальный Python API, почему geoip нужна sticky-сессия, чек-лист согласованности отпечатка и когда лучше подойдут Patchright или nodriver.","https:\u002F\u002Fstatic.proxyhat.com\u002Fstorage\u002Fblog-covers\u002Fru\u002Fcamoufox-rezidentnye-proksi-python-master.webp","Camoufox with Residential Proxies: A Code-First Python Guide","https:\u002F\u002Fstatic.proxyhat.com\u002Fstorage\u002Fblog-covers\u002Fru\u002Fcamoufox-rezidentnye-proksi-python-card.webp","https:\u002F\u002Fstatic.proxyhat.com\u002Fstorage\u002Fblog-covers\u002Fru\u002Fcamoufox-rezidentnye-proksi-python-og.webp","2026-10-13T09:00:00+00:00","2026-10-13T09:00:22+00:00",30,{"name":39,"slug":40,"bio":41,"avatar_url":14,"website_url":14,"social_links":14},[112],{"id":44,"slug":45,"name":46,"description":14,"meta_title":47,"meta_description":48,"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-obnaruzhenie","Анти-обнаружение",{"id":91,"slug":92,"name":93},{"id":122,"slug":123,"name":124},21,"bezgolovnyj-brauzer","Headless-браузер",{"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":37,"is_featured":31,"indexable":4,"views":136,"author":137,"categories":138,"tags":140},176,"got-scraping-nodejs-residential-proxies","got-scraping в Node.js: руководство по парсингу с резидентными прокси","Практическое руководство для Node.js-разработчиков: как использовать got-scraping с генератором заголовков, HTTP\u002F2 и резидентными прокси ProxyHat для масштабного парсинга без блокировок.","https:\u002F\u002Fstatic.proxyhat.com\u002Fstorage\u002Fblog-covers\u002Fru\u002Fgot-scraping-nodejs-residential-proxies-master.webp","got-scraping in Node.js: A Developer's Guide with Residential Proxies","https:\u002F\u002Fstatic.proxyhat.com\u002Fstorage\u002Fblog-covers\u002Fru\u002Fgot-scraping-nodejs-residential-proxies-card.webp","https:\u002F\u002Fstatic.proxyhat.com\u002Fstorage\u002Fblog-covers\u002Fru\u002Fgot-scraping-nodejs-residential-proxies-og.webp","2026-08-04T16:05:06+00:00","2026-10-03T08:29:58+00:00",121,{"name":39,"slug":40,"bio":41,"avatar_url":14,"website_url":14,"social_links":14},[139],{"id":44,"slug":45,"name":46,"description":14,"meta_title":47,"meta_description":48,"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":37,"is_featured":31,"indexable":31,"views":152,"author":153,"categories":154,"tags":156},175,"rotaciya-proksi-v-colly-1","Ротация прокси в Colly: Полное руководство для Go-разработчиков","Практическое руководство по ротации прокси в Colly — от встроенного RoundRobinProxySwitcher до кастомных SetProxyFunc с резидентными IP. Примеры кода, продакшн-паттерны и типичные ошибки.","https:\u002F\u002Fstatic.proxyhat.com\u002Fstorage\u002Fblog-covers\u002Fru\u002Frotaciya-proksi-v-colly-1-master.webp","Rotating Proxies in Colly: A Framework-Idiomatic Guide for Go Developers","https:\u002F\u002Fstatic.proxyhat.com\u002Fstorage\u002Fblog-covers\u002Fru\u002Frotaciya-proksi-v-colly-1-card.webp","https:\u002F\u002Fstatic.proxyhat.com\u002Fstorage\u002Fblog-covers\u002Fru\u002Frotaciya-proksi-v-colly-1-og.webp","2026-08-04T10:05:34+00:00","2026-10-03T08:29:56+00:00",71,{"name":39,"slug":40,"bio":41,"avatar_url":14,"website_url":14,"social_links":14},[155],{"id":44,"slug":45,"name":46,"description":14,"meta_title":47,"meta_description":48,"parent_id":14},[],[]]