[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"blog-post-it-scrape-bybit-v5-market-api-proxy":3},{"success":4,"payload":5,"related":66,"errors":131},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":33,"allow_follow":4,"published_at":34,"updated_at":34,"content_updated_at":35,"featured_image_url":36,"featured_image_alt":37,"card_image_url":38,"reading_time_minutes":39,"author":40,"categories":44,"tags":51,"alternates":52,"locale_paths":63,"views":65},195,"scrape-bybit-v5-market-api-proxy","Raccogliere Dati di Mercato Crypto con Proxy Rotanti: Guida per Sviluppatori (Esempio Bybit V5)","Guida pratica per sviluppatori su come scrapeare gli endpoint pubblici \u002Fv5\u002Fmarket\u002F di Bybit con proxy rotanti ProxyHat. Esempi in Node.js e Python, gestione dei rate limit e geo-restrizioni.","\u003Cp>Se stai costruendo un bot di trading o un sistema di monitoraggio dei dati di mercato su Bybit, prima o poi ti scontri con i limiti di frequenza IP e i blocchi geografici di CloudFront. In questa guida spieghiamo come scrapeare la Bybit V5 Market API con proxy rotanti, coprendo gli endpoint pubblici \u003Ccode>\u002Fv5\u002Fmarket\u002F\u003C\u002Fcode>, il modello di rate limiting di Bybit e come i proxy residenziali ProxyHat ripristinano l'accesso da paesi consentiti.\u003C\u002Fp>\n\n\u003Cblockquote>\u003Cstrong>Avviso legale:\u003C\u002Fstrong> gli endpoint pubblici di mercato di Bybit restituiscono dati di dominio pubblico, ma devi rispettare i Termini di Servizio (ToS) di Bybit e il file \u003Ccode>robots.txt\u003C\u002Fcode>. Non fare scraping di dati privati o autenticati senza autorizzazione. Consulta i \u003Ca href=\"https:\u002F\u002Fwww.bybit.com\u002Fen\u002Flegal\u002Fterms-of-service\u002FBybit-Platform-Terms-and-Conditions\" rel=\"noopener noreferrer\">Termini di Servizio di Bybit\u003C\u002Fa> prima di avviare qualsiasi progetto.\u003C\u002Fp>\u003C\u002Fblockquote>\n\n\u003Ch2>Come Scrapeare la Bybit V5 Market API con Proxy Rotanti: panoramica\u003C\u002Fh2>\n\n\u003Cp>La V5 Market API di Bybit è l'interfaccia REST pubblica per orderbook, ticker, candele (kline) e trade recenti. È un'API unificata che copre spot, derivati lineari, opzioni e futures inversi tramite il parametro \u003Ccode>category\u003C\u002Fcode>. A differenza delle API private, non richiede chiavi API, ma è soggetta a rigidi rate limit per IP e a restrizioni geografiche.\u003C\u002Fp>\n\n\u003Cp>Scrapearla in modo affidabile richiede tre cose: capire la struttura della risposta \u003Ccode>retCode\u002FretMsg\u003C\u002Fcode>, gestire i limiti di frequenza per-endpoint e usare proxy rotanti per distribuire le richieste su più IP. I \u003Ca href=\"\u002Fit\u002Fproxy\u002Fresidential\">proxy residenziali\u003C\u002Fa> di ProxyHat (accessibili via \u003Ccode>gate.proxyhat.com:8080\u003C\u002Fcode> per HTTP e \u003Ccode>:1080\u003C\u002Fcode> per SOCKS5) sono particolarmente efficaci perché usano IP ISP reali, riducendo il rischio di blocchi CloudFront.\u003C\u002Fp>\n\n\u003Ch2>Endpoint pubblici sotto \u002Fv5\u002Fmarket\u002F\u003C\u002Fh2>\n\n\u003Cp>La V5 Market API espone quattro endpoint pubblici principali. Ognuno accetta il parametro \u003Ccode>category\u003C\u002Fcode> (\u003Ccode>spot\u003C\u002Fcode>, \u003Ccode>linear\u003C\u002Fcode>, \u003Ccode>inverse\u003C\u002Fcode>, \u003Ccode>option\u003C\u002Fcode>) e restituisce un envelope JSON standard con i campi \u003Ccode>retCode\u003C\u002Fcode> e \u003Ccode>retMsg\u003C\u002Fcode>.\u003C\u002Fp>\n\n\u003Ctable>\n\u003Cthead>\n\u003Ctr>\u003Cth>Endpoint\u003C\u002Fth>\u003Cth>Scopo\u003C\u002Fth>\u003Cth>Parametri chiave\u003C\u002Fth>\u003Cth>Rate limit tipico\u003C\u002Fth>\u003C\u002Ftr>\n\u003C\u002Fthead>\n\u003Ctbody>\n\u003Ctr>\u003Ctd>\u003Ccode>GET \u002Fv5\u002Fmarket\u002Forderbook\u003C\u002Fcode>\u003C\u002Ftd>\u003Ctd>Snapshot dell'orderbook\u003C\u002Ftd>\u003Ctd>\u003Ccode>category\u003C\u002Fcode>, \u003Ccode>symbol\u003C\u002Fcode>, \u003Ccode>limit\u003C\u002Fcode> (depth)\u003C\u002Ftd>\u003Ctd>~50 req\u002Fs per IP\u003C\u002Ftd>\u003C\u002Ftr>\n\u003Ctr>\u003Ctd>\u003Ccode>GET \u002Fv5\u002Fmarket\u002Ftickers\u003C\u002Fcode>\u003C\u002Ftd>\u003Ctd>Ticker di mercato (prezzo, volume, funding)\u003C\u002Ftd>\u003Ctd>\u003Ccode>category\u003C\u002Fcode>, \u003Ccode>symbol\u003C\u002Fcode> (opzionale)\u003C\u002Ftd>\u003Ctd>~10 req\u002Fs per IP\u003C\u002Ftd>\u003C\u002Ftr>\n\u003Ctr>\u003Ctd>\u003Ccode>GET \u002Fv5\u002Fmarket\u002Fkline\u003C\u002Fcode>\u003C\u002Ftd>\u003Ctd>Candele storiche\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>\u003C\u002Ftd>\u003Ctd>~10 req\u002Fs per IP\u003C\u002Ftd>\u003C\u002Ftr>\n\u003Ctr>\u003Ctd>\u003Ccode>GET \u002Fv5\u002Fmarket\u002Frecent-trade\u003C\u002Fcode>\u003C\u002Ftd>\u003Ctd>Trade recenti\u003C\u002Ftd>\u003Ctd>\u003Ccode>category\u003C\u002Fcode>, \u003Ccode>symbol\u003C\u002Fcode>, \u003Ccode>limit\u003C\u002Fcode>\u003C\u002Ftd>\u003Ctd>~20 req\u002Fs per IP\u003C\u002Ftd>\u003C\u002Ftr>\n\u003C\u002Ftbody>\n\u003C\u002Ftable>\n\n\u003Ch3>L'envelope di risposta retCode\u002FretMsg\u003C\u002Fh3>\n\n\u003Cp>Ogni risposta V5 segue lo stesso schema:\u003C\u002Fp>\n\n\u003Cpre>\u003Ccode>{\n  &quot;retCode&quot;: 0,\n  &quot;retMsg&quot;: &quot;OK&quot;,\n  &quot;result&quot;: { ... },\n  &quot;time&quot;: 1700000000000\n}\u003C\u002Fcode>\u003C\u002Fpre>\n\n\u003Cp>Un \u003Ccode>retCode\u003C\u002Fcode> pari a \u003Ccode>0\u003C\u002Fcode> indica successo. Qualsiasi altro valore indica un errore: \u003Ccode>10001\u003C\u002Fcode> per parametri invalidi, \u003Ccode>10010\u003C\u002Fcode> per rate limit, \u003Ccode>403\u003C\u002Fcode>- stile per blocchi regionali. Il campo \u003Ccode>retMsg\u003C\u002Fcode> fornisce una descrizione leggibile. Il tuo codice deve sempre controllare \u003Ccode>retCode\u003C\u002Fcode> prima di processare \u003Ccode>result\u003C\u002Fcode>.\u003C\u002Fp>\n\n\u003Ch3>Esempio base con curl (senza proxy)\u003C\u002Fh3>\n\n\u003Cpre>\u003Ccode>curl -s &apos;https:\u002F\u002Fapi.bybit.com\u002Fv5\u002Fmarket\u002Forderbook?category=spot&amp;symbol=BTCUSDT&amp;limit=50&apos; | jq .\u003C\u002Fcode>\u003C\u002Fpre>\n\n\u003Ch2>Rate limit IP e finestra di ban di 10 minuti\u003C\u002Fh2>\n\n\u003Cp>Bybit applica rate limit per-endpoint su base IP. Quando superi il limite, ricevi un HTTP 403 o un \u003Ccode>retCode\u003C\u002Fcode> di errore. Il problema critico è che Bybit può mettere al bando un IP per circa \u003Cstrong>10 minuti\u003C\u002Fstrong> se i burst sono troppo aggressivi, specialmente su \u003Ccode>\u002Fv5\u002Fmarket\u002Forderbook\u003C\u002Fcode> che ha un limite più alto (~50 req\u002Fs) ma è il più colpito dai bot.\u003C\u002Fp>\n\n\u003Cp>Secondo la documentazione ufficiale sui rate limit di Bybit V5, i limiti sono dinamici e possono cambiare in base al carico. Una strategia di scraping robusta deve:\u003C\u002Fp>\n\n\u003Cul>\n\u003Cli>Rispettare un budget per-endpoint inferiore al limite dichiarato (es. 80% del limite).\u003C\u002Fli>\n\u003Cli>Usare backoff esponenziale sui 403\u002F429.\u003C\u002Fli>\n\u003Cli>Rotare gli IP per distribuire il carico e ridurre il rischio di ban.\u003C\u002Fli>\n\u003C\u002Ful>\n\n\u003Ch2>Geo-restrizioni: blocchi 403 e CloudFront\u003C\u002Fh2>\n\n\u003Cp>Bybit blocca l'accesso da Stati Uniti, Regno Unito e altre regioni regolamentate. Se il tuo IP è in una zona bloccata, ricevi un 403 da CloudFront o una pagina di blocco invece del JSON. Questo è un problema serio per sviluppatori in US\u002FUK che vogliono accedere ai dati di mercato pubblici.\u003C\u002Fp>\n\n\u003Cp>I proxy residenziali ProxyHat risolvono questo problema instradando le richieste tramite IP ISP di paesi consentiti (es. Germania, Singapore, Giappone). Usando il geo-targeting nel username con il formato \u003Ccode>-country-XX\u003C\u002Fcode>, puoi forzare l'uscita da un paese specifico:\u003C\u002Fp>\n\n\u003Cpre>\u003Ccode>curl -x http:\u002F\u002Fuser-country-DE:pass@gate.proxyhat.com:8080 \\\n  &apos;https:\u002F\u002Fapi.bybit.com\u002Fv5\u002Fmarket\u002Ftickers?category=spot&apos;\u003C\u002Fcode>\u003C\u002Fpre>\n\n\u003Cp>Consulta la pagina delle \u003Ca href=\"\u002Fit\u002Flocations\">locazioni ProxyHat\u003C\u002Fa> per la lista completa di paesi supportati.\u003C\u002Fp>\n\n\u003Ch2>Setup ProxyHat: proxy raw vs SDK\u003C\u002Fh2>\n\n\u003Cp>ProxyHat espone un gateway HTTP su \u003Ccode>gate.proxyhat.com:8080\u003C\u002Fcode> e SOCKS5 su \u003Ccode>:1080\u003C\u002Fcode>. Le opzioni di rotazione e geo-targeting vanno nel username. Ecco i formati:\u003C\u002Fp>\n\n\u003Cul>\n\u003Cli>\u003Cstrong>Rotazione per-request:\u003C\u002Fstrong> \u003Ccode>http:\u002F\u002FUSERNAME:PASSWORD@gate.proxyhat.com:8080\u003C\u002Fcode>\u003C\u002Fli>\n\u003Cli>\u003Cstrong>Geo-targeting paese:\u003C\u002Fstrong> \u003Ccode>http:\u002F\u002FUSERNAME-country-DE:PASSWORD@gate.proxyhat.com:8080\u003C\u002Fcode>\u003C\u002Fli>\n\u003Cli>Sticky session: \u003Ccode>http:\u002F\u002FUSERNAME-sid-abc123:PASSWORD@gate.proxyhat.com:8080\u003C\u002Fcode>\u003C\u002Fli>\n\u003Cli>SOCKS5: \u003Ccode>socks5:\u002F\u002FUSERNAME:PASSWORD@gate.proxyhat.com:1080\u003C\u002Fcode>\u003C\u002Fli>\n\u003C\u002Ful>\n\n\u003Cp>Per dettagli completi, consulta la \u003Ca href=\"https:\u002F\u002Fdocs.proxyhat.com\u002F\" rel=\"noopener noreferrer\">documentazione ProxyHat\u003C\u002Fa>.\u003C\u002Fp>\n\n\u003Ch2>Esempio Node.js (axios): rotazione IP su lista di symbol\u003C\u002Fh2>\n\n\u003Cp>Questo esempio usa il proxy raw di ProxyHat per scrapeare i ticker di una lista di symbol, con rotazione IP per-request, retry con backoff e budget di rate.\u003C\u002Fp>\n\n\u003Cpre>\u003Ccode>const axios = require(&apos;axios&apos;);\n\nconst PROXY_USER = &apos;user&apos;;\nconst PROXY_PASS = &apos;pass&apos;;\nconst PROXY_HOST = &apos;gate.proxyhat.com&apos;;\nconst PROXY_PORT = 8080;\n\nconst symbols = [&apos;BTCUSDT&apos;, &apos;ETHUSDT&apos;, &apos;SOLUSDT&apos;, &apos;XRPUSDT&apos;, &apos;DOGEUSDT&apos;];\nconst BASE_URL = &apos;https:\u002F\u002Fapi.bybit.com&apos;;\n\n\u002F\u002F Genera un session ID unico per rotazione per-request\nfunction randomSession() {\n  return Math.random().toString(36).substring(2, 12);\n}\n\nasync function fetchTicker(symbol, attempt = 1) {\n  const sessionId = randomSession();\n  const proxyUrl = `http:\u002F\u002F${PROXY_USER}-country-DE-sid-${sessionId}:${PROXY_PASS}@${PROXY_HOST}:${PROXY_PORT}`;\n\n  try {\n    const res = await axios.get(`${BASE_URL}\u002Fv5\u002Fmarket\u002Ftickers`, {\n      params: { category: &apos;spot&apos;, symbol },\n      proxy: { host: PROXY_HOST, port: PROXY_PORT, auth: { username: `${PROXY_USER}-country-DE-sid-${sessionId}`, password: PROXY_PASS } },\n      timeout: 10000,\n    });\n\n    if (res.data.retCode !== 0) {\n      throw new Error(`Bybit error ${res.data.retCode}: ${res.data.retMsg}`);\n    }\n    return res.data.result;\n  } catch (err) {\n    if (attempt &lt; 4) {\n      const backoff = Math.pow(2, attempt) * 500;\n      console.error(`Retry ${symbol} in ${backoff}ms: ${err.message}`);\n      await new Promise(r =&gt; setTimeout(r, backoff));\n      return fetchTicker(symbol, attempt + 1);\n    }\n    throw err;\n  }\n}\n\nasync function main() {\n  const results = [];\n  \u002F\u002F Rate budget: 8 req\u002Fs (sotto il limite ~10 req\u002Fs)\n  for (const sym of symbols) {\n    const data = await fetchTicker(sym);\n    results.push(data);\n    await new Promise(r =&gt; setTimeout(r, 125)); \u002F\u002F 125ms = 8 req\u002Fs\n  }\n  console.log(JSON.stringify(results, null, 2));\n}\n\nmain().catch(console.error);\u003C\u002Fcode>\u003C\u002Fpre>\n\n\u003Ch3>Versione con ProxyHat SDK (Node.js)\u003C\u002Fh3>\n\n\u003Cpre>\u003Ccode>const { ProxyHatClient } = require(&apos;@proxyhat\u002Fsdk&apos;);\nconst axios = require(&apos;axios&apos;);\n\nconst ph = new ProxyHatClient({\n  username: &apos;user&apos;,\n  password: &apos;pass&apos;,\n  country: &apos;DE&apos;,\n  rotate: true, \u002F\u002F rotazione per-request\n});\n\nasync function fetchTickerSDK(symbol, attempt = 1) {\n  const proxyConfig = await ph.getProxyConfig(); \u002F\u002F {host, port, auth}\n\n  try {\n    const res = await axios.get(&apos;https:\u002F\u002Fapi.bybit.com\u002Fv5\u002Fmarket\u002Ftickers&apos;, {\n      params: { category: &apos;spot&apos;, symbol },\n      proxy: { host: proxyConfig.host, port: proxyConfig.port, auth: proxyConfig.auth },\n      timeout: 10000,\n    });\n\n    if (res.data.retCode !== 0) {\n      throw new Error(`Bybit ${res.data.retCode}: ${res.data.retMsg}`);\n    }\n    return res.data.result;\n  } catch (err) {\n    if (attempt &lt; 4) {\n      await new Promise(r =&gt; setTimeout(r, Math.pow(2, attempt) * 500));\n      return fetchTickerSDK(symbol, attempt + 1);\n    }\n    throw err;\n  }\n}\n\nasync function main() {\n  const symbols = [&apos;BTCUSDT&apos;, &apos;ETHUSDT&apos;, &apos;SOLUSDT&apos;];\n  for (const s of symbols) {\n    const r = await fetchTickerSDK(s);\n    console.log(s, r.list[0].lastPrice);\n    await new Promise(r =&gt; setTimeout(r, 125));\n  }\n}\n\nmain();\u003C\u002Fcode>\u003C\u002Fpre>\n\n\u003Ch2>Esempio Python: orderbook con proxy rotanti\u003C\u002Fh2>\n\n\u003Cpre>\u003Ccode>import requests\nimport time\nimport random\nimport string\n\nPROXY_USER = &apos;user&apos;\nPROXY_PASS = &apos;pass&apos;\nPROXY_HOST = &apos;gate.proxyhat.com&apos;\nPROXY_PORT = 8080\nBASE_URL = &apos;https:\u002F\u002Fapi.bybit.com&apos;\n\ndef random_session():\n    return &apos;&apos;.join(random.choices(string.ascii_lowercase + string.digits, k=10))\n\ndef fetch_orderbook(symbol, category=&apos;linear&apos;, limit=50, attempt=1):\n    session_id = random_session()\n    proxy_url = f&apos;http:\u002F\u002F{PROXY_USER}-country-DE-sid-{session_id}:{PROXY_PASS}@{PROXY_HOST}:{PROXY_PORT}&apos;\n    proxies = {&apos;http&apos;: proxy_url, &apos;https&apos;: proxy_url}\n\n    try:\n        res = requests.get(\n            f&apos;{BASE_URL}\u002Fv5\u002Fmarket\u002Forderbook&apos;,\n            params={&apos;category&apos;: category, &apos;symbol&apos;: symbol, &apos;limit&apos;: limit},\n            proxies=proxies,\n            timeout=10,\n        )\n        res.raise_for_status()\n        data = res.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 Exception as e:\n        if attempt &lt; 4:\n            backoff = 2 ** attempt * 0.5\n            print(f&apos;Retry {symbol} in {backoff}s: {e}&apos;)\n            time.sleep(backoff)\n            return fetch_orderbook(symbol, category, limit, attempt + 1)\n        raise\n\ndef main():\n    symbols = [&apos;BTCUSDT&apos;, &apos;ETHUSDT&apos;, &apos;SOLUSDT&apos;]\n    for sym in symbols:\n        ob = fetch_orderbook(sym)\n        print(f&apos;{sym}: bid={ob[&quot;b&quot;][0][0]}, ask={ob[&quot;a&quot;][0][0]}&apos;)\n        time.sleep(0.05)  # 20 req\u002Fs budget, sotto il limite ~50\n\nif __name__ == &apos;__main__&apos;:\n    main()\u003C\u002Fcode>\u003C\u002Fpre>\n\n\u003Ch3>Versione Python con ProxyHat SDK\u003C\u002Fh3>\n\n\u003Cpre>\u003Ccode>from proxyhat import ProxyHatClient\nimport requests\nimport time\n\nph = ProxyHatClient(username=&apos;user&apos;, password=&apos;pass&apos;, country=&apos;DE&apos;, rotate=True)\n\ndef fetch_orderbook_sdk(symbol, category=&apos;linear&apos;, limit=50, attempt=1):\n    proxy_cfg = ph.get_proxy_config()  # {&apos;host&apos;:..., &apos;port&apos;:..., &apos;auth&apos;:...}\n    proxy_url = f&quot;http:\u002F\u002F{proxy_cfg[&apos;auth&apos;][&apos;username&apos;]}:{proxy_cfg[&apos;auth&apos;][&apos;password&apos;]}@{proxy_cfg[&apos;host&apos;]}:{proxy_cfg[&apos;port&apos;]}&quot;\n    proxies = {&apos;http&apos;: proxy_url, &apos;https&apos;: proxy_url}\n\n    try:\n        res = requests.get(\n            &apos;https:\u002F\u002Fapi.bybit.com\u002Fv5\u002Fmarket\u002Forderbook&apos;,\n            params={&apos;category&apos;: category, &apos;symbol&apos;: symbol, &apos;limit&apos;: limit},\n            proxies=proxies,\n            timeout=10,\n        )\n        data = res.json()\n        if data[&apos;retCode&apos;] != 0:\n            raise Exception(f&quot;Bybit {data[&apos;retCode&apos;]}: {data[&apos;retMsg&apos;]}&quot;)\n        return data[&apos;result&apos;]\n    except Exception as e:\n        if attempt &lt; 4:\n            time.sleep(2 ** attempt * 0.5)\n            return fetch_orderbook_sdk(symbol, category, limit, attempt + 1)\n        raise\n\nfor sym in [&apos;BTCUSDT&apos;, &apos;ETHUSDT&apos;]:\n    ob = fetch_orderbook_sdk(sym)\n    print(sym, ob[&apos;b&apos;][0][0], ob[&apos;a&apos;][0][0])\n    time.sleep(0.05)\u003C\u002Fcode>\u003C\u002Fpre>\n\n\u003Ch2>Sticky session per paginazione kline\u003C\u002Fh2>\n\n\u003Cp>Quando scarichi dati kline storici in pagine successive, conviene mantenere lo stesso IP per tutta la sessione per evitare di saltare intervalli a causa di rotazioni. Usa il flag \u003Ccode>-sid-abc123\u003C\u002Fcode> nel username ProxyHat.\u003C\u002Fp>\n\n\u003Cpre>\u003Ccode>import requests\nimport time\n\nPROXY_USER = &apos;user&apos;\nPROXY_PASS = &apos;pass&apos;\nSESSION_ID = &apos;kline-btc-001&apos;\n\nproxy_url = f&apos;http:\u002F\u002F{PROXY_USER}-country-DE-sid-{SESSION_ID}:{PROXY_PASS}@gate.proxyhat.com:8080&apos;\nproxies = {&apos;http&apos;: proxy_url, &apos;https&apos;: proxy_url}\n\ndef fetch_kline(symbol, interval=&apos;60&apos;, start=None, end=None, limit=200):\n    params = {&apos;category&apos;: &apos;linear&apos;, &apos;symbol&apos;: symbol, &apos;interval&apos;: interval, &apos;limit&apos;: limit}\n    if start:\n        params[&apos;start&apos;] = start\n    if end:\n        params[&apos;end&apos;] = end\n\n    res = requests.get(\n        &apos;https:\u002F\u002Fapi.bybit.com\u002Fv5\u002Fmarket\u002Fkline&apos;,\n        params=params,\n        proxies=proxies,\n        timeout=10,\n    )\n    data = res.json()\n    if data[&apos;retCode&apos;] != 0:\n        raise Exception(f&quot;Bybit {data[&apos;retCode&apos;]}: {data[&apos;retMsg&apos;]}&quot;)\n    return data[&apos;result&apos;]\n\ndef scrape_all_klines(symbol, interval=&apos;60&apos;, total_candles=1000):\n    all_candles = []\n    batch = 200\n    end = None\n\n    while len(all_candles) &lt; total_candles:\n        result = fetch_kline(symbol, interval=interval, end=end, limit=batch)\n        candles = result[&apos;list&apos;]\n        if not candles:\n            break\n        all_candles.extend(candles)\n        # Usa il timestamp più vecchio come nuovo &apos;end&apos;\n        end = int(candles[-1][0]) - 1\n        time.sleep(0.1)  # 10 req\u002Fs budget\n\n    return all_candles\n\ncandles = scrape_all_klines(&apos;BTCUSDT&apos;, interval=&apos;60&apos;, total_candles=1000)\nprint(f&apos;Recuperate {len(candles)} candele&apos;)\u003C\u002Fcode>\u003C\u002Fpre>\n\n\u003Ch2>REST snapshot vs WebSocket orderbook.50\u003C\u002Fh2>\n\n\u003Cp>L'endpoint REST \u003Ccode>\u002Fv5\u002Fmarket\u002Forderbook\u003C\u002Fcode> fornisce uno snapshot istantaneo, ma per dati live ad alta frequenza conviene usare il WebSocket pubblico di Bybit con il topic \u003Ccode>orderbook.50.{symbol}\u003C\u002Fcode>, che invia aggiornamenti incrementali a ~50ms di latenza.\u003C\u002Fp>\n\n\u003Ctable>\n\u003Cthead>\n\u003Ctr>\u003Cth>Aspetto\u003C\u002Fth>\u003Cth>REST orderbook\u003C\u002Fth>\u003Cth>WebSocket orderbook.50\u003C\u002Fth>\u003C\u002Ftr>\n\u003C\u002Fthead>\n\u003Ctbody>\n\u003Ctr>\u003Ctd>Latenza\u003C\u002Ftd>\u003Ctd>~100-300ms per richiesta\u003C\u002Ftd>\u003Ctd>~50ms push\u003C\u002Ftd>\u003C\u002Ftr>\n\u003Ctr>\u003Ctd>Rate limit\u003C\u002Ftd>\u003Ctd>~50 req\u002Fs per IP\u003C\u002Ftd>\u003Ctd>1 connessione, push continuo\u003C\u002Ftd>\u003C\u002Ftr>\n\u003Ctr>\u003Ctd>Uso tipico\u003C\u002Ftd>\u003Ctd>Snapshot periodici, backfill\u003C\u002Ftd>\u003Ctd>Feed live per bot HFT\u003C\u002Ftd>\u003C\u002Ftr>\n\u003Ctr>\u003Ctd>Proxy necessario?\u003C\u002Ftd>\u003Ctd>Sì, per geo-sbypass\u003C\u002Ftd>\u003Ctd>Sì, anche WS passa per proxy\u003C\u002Ftd>\u003C\u002Ftr>\n\u003C\u002Ftbody>\n\u003C\u002Ftable>\n\n\u003Cp>Per il WebSocket, puoi configurare il proxy a livello di client (es. \u003Ccode>HttpsProxyAgent\u003C\u002Fcode> in Node.js o \u003Ccode>websockets\u003C\u002Fcode> con proxy in Python). Il gateway ProxyHat supporta connessioni WebSocket tunneling via HTTP CONNECT.\u003C\u002Fp>\n\n\u003Ch2>Errori comuni e edge case\u003C\u002Fh2>\n\n\u003Cul>\n\u003Cli>\u003Cstrong>Non controllare retCode:\u003C\u002Fstrong> una risposta HTTP 200 con \u003Ccode>retCode != 0\u003C\u002Fcode> è comunque un errore.\u003C\u002Fli>\n\u003Cli>Burst su orderbook: anche se il limite è ~50 req\u002Fs, burst continui possono innescare ban di 10 minuti.\u003C\u002Fli>\n\u003Cli>Geo-blocco silenzioso: CloudFront può restituire 403 senza un corpo JSON leggibile. Controlla il Content-Type.\u003C\u002Fli>\n\u003Cli>Parametro category mancante: senza \u003Ccode>category\u003C\u002Fcode>, l'API restituisce errore. Ogni endpoint lo richiede.\u003C\u002Fli>\n\u003Cli>Timestamp in ms: Bybit usa timestamp in millisecondi, non secondi. Per paginazione kline, usa ms.\u003C\u002Fli>\n\u003C\u002Ful>\n\n\u003Ch2>Configurazione ProxyHat e link utili\u003C\u002Fh2>\n\n\u003Cp>Per iniziare con ProxyHat, consulta la pagina dei \u003Ca href=\"\u002Fit\u002Fpricing\">prezzi\u003C\u002Fa> e i casi d'uso per il \u003Ca href=\"\u002Fit\u002Fuse-cases\u002Fweb-scraping\">web scraping\u003C\u002Fa> e il \u003Ca href=\"\u002Fit\u002Fuse-cases\u002Fserp-tracking\">SERP tracking\u003C\u002Fa>. Per la lista dei paesi supportati per il geo-targeting, visita \u003Ca href=\"\u002Fit\u002Flocations\">locazioni\u003C\u002Fa>.\u003C\u002Fp>\n\n\u003Ch2>Punti chiave (Key Takeaways)\u003C\u002Fh2>\n\n\u003Cul>\n\u003Cli>La V5 Market API di Bybit usa un envelope \u003Ccode>retCode\u002FretMsg\u003C\u002Fcode>: controlla sempre \u003Ccode>retCode == 0\u003C\u002Fcode> prima di processare \u003Ccode>result\u003C\u002Fcode>.\u003C\u002Fli>\n\u003Cli>I rate limit sono per-endpoint e per-IP: l'orderbook ha il limite più alto (~50 req\u002Fs) ma i burst possono causare ban di ~10 minuti.\u003C\u002Fli>\n\u003Cli>Bybit blocca US\u002FUK e altre regioni via CloudFront: i proxy residenziali ProxyHat con geo-targeting \u003Ccode>-country-XX\u003C\u002Fcode> ripristinano l'accesso.\u003C\u002Fli>\n\u003Cli>Usa sticky session (\u003Ccode>-sid-abc123\u003C\u002Fcode>) per operazioni che richiedono stato (paginazione kline) e rotazione per-request per scraping distribuito.\u003C\u002Fli>\n\u003Cli>Per dati live ad alta frequenza, preferisci il WebSocket \u003Ccode>orderbook.50\u003C\u002Fcode> al REST polling.\u003C\u002Fli>\n\u003Cli>Mantieni un budget di rate dell'80% del limite dichiarato e usa backoff esponenziale sui 403\u002F429.\u003C\u002Fli>\n\u003C\u002Ful>","Dati di Mercato Crypto con Proxy Rotanti (Bybit V5) | ProxyHat","Guida per sviluppatori su come scrapeare la Bybit V5 Market API con proxy rotanti. Esempi Node.js e Python, rate limit, geo-bypass e SDK ProxyHat.","\u002Fit\u002Fblog\u002Fscrape-bybit-v5-market-api-proxy",null,"Dati di Mercato Crypto con Proxy Rotanti | ProxyHat","https:\u002F\u002Fstatic.proxyhat.com\u002Fstorage\u002Fblog-covers\u002Fit\u002Fscrape-bybit-v5-market-api-proxy-og.webp",[18,21,24,27,30],{"question":19,"answer":20},"Come si scrapearla la Bybit V5 Market API con proxy rotanti?","Si inviano richieste agli endpoint pubblici \u002Fv5\u002Fmarket\u002F (orderbook, tickers, kline, recent-trade) tramite un gateway proxy rotante come ProxyHat, che assegna un IP residenziale diverso per ogni richiesta o sessione. Il proxy va configurato nel client HTTP usando l'URL http:\u002F\u002FUSERNAME:PASSWORD@gate.proxyhat.com:8080, con geo-targeting via -country-XX per evitare blocchi regionali.",{"question":22,"answer":23},"Perché i proxy rotanti importano per il scraping della Bybit V5 Market API?","Bybit applica rate limit rigorosi per IP e ban di circa 10 minuti per burst eccessivi. Senza rotazione, un singolo IP viene rapidamente bloccato, interrompendo la raccolta dati. I proxy rotanti distribuiscono le richieste su centinaia di IP residenziali, riducendo il carico per-IP sotto la soglia di rate limit e mantenendo throughput elevato.",{"question":25,"answer":26},"Quale tipo di proxy funziona meglio per scrapearla Bybit V5 Market API?","I proxy residenziali sono i più efficaci perché usano IP ISP reali, meno inclini a blocchi CloudFront e filtri anti-bot rispetto ai datacenter. Per il geo-sbypass (US\u002FUK), il geo-targeting paese (-country-DE) è essenziale. I proxy datacenter possono funzionare per carichi leggeri ma hanno tassi di blocco più alti su Bybit.",{"question":28,"answer":29},"Come evitare i blocchi nello scraping della Bybit V5 Market API?","Mantieni un budget di rate sotto il limite dichiarato (es. 80%), usa backoff esponenziale sui 403\u002F429, ruota gli IP per-request con ProxyHat, implementa sticky session per operazioni con stato, e monitora il campo retCode per rilevare errori di rate limit prima che diventino ban. Evita burst continui su \u002Fv5\u002Fmarket\u002Forderbook, l'endpoint più sensibile.",{"question":31,"answer":32},"Qual è la differenza tra REST orderbook e WebSocket orderbook.50?","L'endpoint REST \u002Fv5\u002Fmarket\u002Forderbook fornisce snapshot su richiesta con latenza ~100-300ms, ideale per backfill e polling periodico. Il WebSocket orderbook.50 invia aggiornamenti incrementali push a ~50ms, ideale per bot live e HFT. Per dati real-time, il WebSocket è superiore; per snapshot storici, il REST è più semplice.",false,"2026-08-03T16:09:16+00:00","2026-10-04T01:29:51+00:00","https:\u002F\u002Fstatic.proxyhat.com\u002Fstorage\u002Fblog-covers\u002Fit\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\u002Fit\u002Fscrape-bybit-v5-market-api-proxy-card.webp",12,{"name":41,"slug":42,"bio":43,"avatar_url":14,"website_url":14,"social_links":14},"ProxyHat Team","proxyhat-team","The ProxyHat editorial team covers proxies, web scraping, and data extraction.",[45],{"id":46,"slug":47,"name":48,"description":14,"meta_title":49,"meta_description":50,"parent_id":14},4,"developer-guides","Guide per sviluppatori","Guida agli sviluppatori | ProxyHat Blog","Istruzioni di codice e guide SDK per integrare i proxy nelle applicazioni.",[],{"de":53,"fr":54,"pt":55,"ru":56,"zh":57,"pl":58,"ko":59,"it":13,"es":60,"en":61,"ja":62,"x-default":61},"\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","\u002Fru\u002Fblog\u002Fkak-skrejpit-bybit-v5-market-api","\u002Fcn\u002Fblog\u002Fscrape-bybit-v5-market-api-proxy","\u002Fpl\u002Fblog\u002Fjak-scrapowac-bybit-v5-api-proxy","\u002Fko\u002Fblog\u002Fbybit-v5-market-api-proxy-scraping","\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":53,"fr":54,"pt":55,"ru":56,"zh":57,"pl":58,"ko":59,"it":13,"es":60,"en":61,"ja":62,"tr":64},"\u002Ftr\u002Fblog\u002Fbybit-v5-market-api-dondurulen-proxy",87,[67,83,99,115],{"id":68,"slug":69,"title":70,"excerpt":71,"featured_image_url":72,"featured_image_alt":73,"card_image_url":74,"og_image_url":75,"published_at":76,"updated_at":76,"content_updated_at":77,"reading_time_minutes":39,"is_featured":33,"indexable":4,"views":78,"author":79,"categories":80,"tags":82},176,"guida-got-scraping-nodejs-proxy","Guida a got-scraping in Node.js: proxy residenziali e header generator","Una guida pratica per sviluppatori Node.js su got-scraping, il client HTTP di Apify basato su got, con header generator coerenti, proxy residenziali su gate.proxyhat.com:8080 e pattern di produzione per scraping a scala.","https:\u002F\u002Fstatic.proxyhat.com\u002Fstorage\u002Fblog-covers\u002Fit\u002Fguida-got-scraping-nodejs-proxy-master.webp","got-scraping in Node.js: A Developer's Guide with Residential Proxies","https:\u002F\u002Fstatic.proxyhat.com\u002Fstorage\u002Fblog-covers\u002Fit\u002Fguida-got-scraping-nodejs-proxy-card.webp","https:\u002F\u002Fstatic.proxyhat.com\u002Fstorage\u002Fblog-covers\u002Fit\u002Fguida-got-scraping-nodejs-proxy-og.webp","2026-08-04T16:05:06+00:00","2026-10-03T08:29:58+00:00",121,{"name":41,"slug":42,"bio":43,"avatar_url":14,"website_url":14,"social_links":14},[81],{"id":46,"slug":47,"name":48,"description":14,"meta_title":49,"meta_description":50,"parent_id":14},[],{"id":84,"slug":85,"title":86,"excerpt":87,"featured_image_url":88,"featured_image_alt":89,"card_image_url":90,"og_image_url":91,"published_at":92,"updated_at":92,"content_updated_at":93,"reading_time_minutes":39,"is_featured":33,"indexable":33,"views":94,"author":95,"categories":96,"tags":98},175,"proxy-rotanti-in-colly-guida","Proxy Rotanti in Colly: Guida Pratica per Go Developer","Scopri come integrare proxy rotanti in Colly con un approccio idiomatico: RoundRobinProxySwitcher, sessioni sticky, geo-targeting e pattern di produzione per scraping ad alto throughput in Go.","https:\u002F\u002Fstatic.proxyhat.com\u002Fstorage\u002Fblog-covers\u002Fit\u002Fproxy-rotanti-in-colly-guida-master.webp","Rotating Proxies in Colly: A Framework-Idiomatic Guide for Go Developers","https:\u002F\u002Fstatic.proxyhat.com\u002Fstorage\u002Fblog-covers\u002Fit\u002Fproxy-rotanti-in-colly-guida-card.webp","https:\u002F\u002Fstatic.proxyhat.com\u002Fstorage\u002Fblog-covers\u002Fit\u002Fproxy-rotanti-in-colly-guida-og.webp","2026-08-04T10:05:34+00:00","2026-10-03T08:29:56+00:00",71,{"name":41,"slug":42,"bio":43,"avatar_url":14,"website_url":14,"social_links":14},[97],{"id":46,"slug":47,"name":48,"description":14,"meta_title":49,"meta_description":50,"parent_id":14},[],{"id":100,"slug":101,"title":102,"excerpt":103,"featured_image_url":104,"featured_image_alt":105,"card_image_url":106,"og_image_url":107,"published_at":108,"updated_at":108,"content_updated_at":109,"reading_time_minutes":39,"is_featured":33,"indexable":33,"views":110,"author":111,"categories":112,"tags":114},194,"scraping-binance-rest-api-con-proxy","Come fare scraping della Binance REST API con proxy: guida per sviluppatori","Guida pratica per raccogliere dati di mercato pubblici da Binance tramite proxy rotanti: endpoint, pesi, rate limit, esempi in Python e Node.js con il SDK ProxyHat.","https:\u002F\u002Fstatic.proxyhat.com\u002Fstorage\u002Fblog-covers\u002Fit\u002Fscraping-binance-rest-api-con-proxy-master.webp","How to Scrape the Binance REST API with Proxies: A Developer Guide","https:\u002F\u002Fstatic.proxyhat.com\u002Fstorage\u002Fblog-covers\u002Fit\u002Fscraping-binance-rest-api-con-proxy-card.webp","https:\u002F\u002Fstatic.proxyhat.com\u002Fstorage\u002Fblog-covers\u002Fit\u002Fscraping-binance-rest-api-con-proxy-og.webp","2026-08-03T10:04:04+00:00","2026-10-03T08:29:51+00:00",82,{"name":41,"slug":42,"bio":43,"avatar_url":14,"website_url":14,"social_links":14},[113],{"id":46,"slug":47,"name":48,"description":14,"meta_title":49,"meta_description":50,"parent_id":14},[],{"id":116,"slug":117,"title":118,"excerpt":119,"featured_image_url":120,"featured_image_alt":121,"card_image_url":122,"og_image_url":123,"published_at":124,"updated_at":124,"content_updated_at":125,"reading_time_minutes":39,"is_featured":33,"indexable":33,"views":126,"author":127,"categories":128,"tags":130},172,"usare-proxy-in-swift-urlsession-1","Usare proxy in Swift con URLSession: guida pratica per iOS e macOS","Una guida code-first per configurare proxy residenziali in Swift tramite URLSession, con esempi su HTTP\u002FSOCKS5, autenticazione, geo-targeting, async\u002Fawait e best practice di produzione.","https:\u002F\u002Fstatic.proxyhat.com\u002Fstorage\u002Fblog-covers\u002Fit\u002Fusare-proxy-in-swift-urlsession-1-master.webp","Using Proxies in Swift: A Code-First Guide to URLSession, SOCKS5 & Residential IPs","https:\u002F\u002Fstatic.proxyhat.com\u002Fstorage\u002Fblog-covers\u002Fit\u002Fusare-proxy-in-swift-urlsession-1-card.webp","https:\u002F\u002Fstatic.proxyhat.com\u002Fstorage\u002Fblog-covers\u002Fit\u002Fusare-proxy-in-swift-urlsession-1-og.webp","2026-07-26T16:03:44+00:00","2026-10-03T23:53:00+00:00",230,{"name":41,"slug":42,"bio":43,"avatar_url":14,"website_url":14,"social_links":14},[129],{"id":46,"slug":47,"name":48,"description":14,"meta_title":49,"meta_description":50,"parent_id":14},[],[]]