[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"blog-post-ko-binance-rest-api-proxy-scraping":3},{"success":4,"payload":5,"related":57,"errors":150},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":24,"allow_follow":4,"published_at":25,"updated_at":25,"content_updated_at":26,"featured_image_url":27,"featured_image_alt":28,"card_image_url":29,"reading_time_minutes":30,"author":31,"categories":35,"tags":42,"alternates":43,"locale_paths":49,"views":56},194,"binance-rest-api-proxy-scraping","암호화폐 거래소 API의 가중치 기반 속도 제한: 프록시로 시장 데이터 수집하기 (바이낸스 사례)","바이낸스 REST API의 가중치 기반 속도 제한을 우회하기 위해 ProxyHat 주거 프록시를 사용해 klines, depth, ticker 데이터를 대규모로 수집하는 개발자 가이드입니다.","\u003Ch2>바이낸스 REST API 프록시 스크래핑 개요\u003C\u002Fh2>\n\u003Cp>바이낸스 REST API는 풍부한 시장 데이터를 제공하지만, 가중치 기반 속도 제한(weight-based rate limit)으로 인해 대규모 데이터 수집이 어렵습니다. 단일 IP로 \u003Ccode>\u002Fapi\u002Fv3\u002Fdepth\u003C\u002Fcode>를 폴링하면 몇 분 안에 분당 약 6,000의 가중치 예산이 소진되어 HTTP 429 응답이 반환되고, 반복 시 HTTP 418로 IP가 차단될 수 있습니다. 이 가이드에서는 바이낸스 REST API 프록시 스크래핑을 안전하게 수행하기 위해 ProxyHat 주거 프록시를 활용하여 가중치를 여러 IP에 분산시키고, geo 타겟팅으로 바이낸스닷컴과 바이낸스 US 지역 분할(HTTP 451)을 우회하는 방법을 다룹니다.\u003C\u002Fp>\n\u003Cblockquote>\n\u003Cp>\u003Cstrong>면책 고지:\u003C\u002Fstrong> 본 가이드는 \u003Cem>공개 시장 데이터(public market data)\u003C\u002Fem> 수집만을 다룹니다. 바이낸스 API 이용약관(Terms of Use)을 준수하고, 가중치 제한을 존중하며, 약관에서 공식 API 접근을 요구하는 경우 해당 경로를 우선 사용하십시오. 자세한 내용은 \u003Ca href=\"https:\u002F\u002Fwww.binance.com\u002Fen\u002Fterms\" rel=\"noopener noreferrer\">Binance Terms of Use\u003C\u002Fa>를 참조하세요.\u003C\u002Fp>\n\u003C\u002Fblockquote>\n\n\u003Ch2>왜 이 문제가 발생하는가: 바이낸스 가중치 기반 속도 제한\u003C\u002Fh2>\n\u003Cp>바이낸스 REST API는 단순히 요청 수가 아니라 \u003Cstrong>가중치(weight)\u003C\u002Fstrong> 단위로 속도 제한을 관리합니다. 각 엔드포인트는 요청당 소비 가중치가 다르며, 응답 헤더 \u003Ccode>X-MBX-USED-WEIGHT-1M\u003C\u002Fcode>을 통해 현재 1분간 사용된 가중치를 확인할 수 있습니다. 자세한 사양은 \u003Ca href=\"https:\u002F\u002Fbinance-docs.github.io\u002Fapidocs\u002Fspot\u002Fen\u002F#limits\" rel=\"noopener noreferrer\">Binance API Limits 공식 문서\u003C\u002Fa>에 정의되어 있습니다.\u003C\u002Fp>\n\u003Cp>주요 동작 방식은 다음과 같습니다:\u003C\u002Fp>\n\u003Cul>\n\u003Cli>\u003Cstrong>분당 약 6,000 가중치\u003C\u002Fstrong> — IP당 기본 가중치 예산 (바이낸스는 이 값을 동적으로 조정할 수 있음).\u003C\u002Fli>\n\u003Cli>\u003Cstrong>HTTP 429\u003C\u002Fstrong> — 가중치 예산 초과 시 반환. \u003Ccode>Retry-After\u003C\u002Fcode> 헤더로 대기 시간 안내.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>HTTP 418\u003C\u002Fstrong> — 429 후에도 계속 요청하면 IP가 자동 차단(ban). 차단은 점진적으로 길어집니다(2분 → 1일 등).\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Cp>예를 들어 \u003Ccode>\u002Fapi\u002Fv3\u002Fdepth\u003C\u002Fcode>는 \u003Ccode>limit=1000\u003C\u002Fcode> 설정 시 가중치 10을 소비합니다. 분당 6,000 가중치 예산으로는 600회만 호출 가능하며, 1초 간격으로 폴링해도 약 10분이면 예산이 소진됩니다. 여러 심볼의 오더북을 동시에 수집하면 예산은 훨씬 빨리 고갈됩니다.\u003C\u002Fp>\n\n\u003Ch2>핵심 공개 시장 데이터 엔드포인트 매핑\u003C\u002Fh2>\n\u003Cp>다음 표는 바이낸스 REST API의 주요 공개 엔드포인트와 요청당 가중치를 정리한 것입니다. 가중치는 바이낸스 공식 문서 기준이며, 파라미터에 따라 달라질 수 있습니다.\u003C\u002Fp>\n\u003Ctable>\n\u003Cthead>\n\u003Ctr>\u003Cth>엔드포인트\u003C\u002Fth>\u003Cth>설명\u003C\u002Fth>\u003Cth>주요 파라미터\u003C\u002Fth>\u003Cth>요청당 가중치\u003C\u002Fth>\u003C\u002Ftr>\n\u003C\u002Fthead>\n\u003Ctbody>\n\u003Ctr>\u003Ctd>\u003Ccode>GET \u002Fapi\u002Fv3\u002Fklines\u003C\u002Fcode>\u003C\u002Ftd>\u003Ctd>캔들스틱(OHLCV) 데이터\u003C\u002Ftd>\u003Ctd>\u003Ccode>symbol\u003C\u002Fcode>, \u003Ccode>interval\u003C\u002Fcode>, \u003Ccode>limit\u003C\u002Fcode> (최대 1000)\u003C\u002Ftd>\u003Ctd>1–2\u003C\u002Ftd>\u003C\u002Ftr>\n\u003Ctr>\u003Ctd>\u003Ccode>GET \u002Fapi\u002Fv3\u002Fdepth\u003C\u002Fcode>\u003C\u002Ftd>\u003Ctd>오더북(호가창)\u003C\u002Ftd>\u003Ctd>\u003Ccode>symbol\u003C\u002Fcode>, \u003Ccode>limit\u003C\u002Fcode> (5\u002F10\u002F20\u002F50\u002F100\u002F500\u002F1000)\u003C\u002Ftd>\u003Ctd>1–10 (limit=1000 시 10)\u003C\u002Ftd>\u003C\u002Ftr>\n\u003Ctr>\u003Ctd>\u003Ccode>GET \u002Fapi\u002Fv3\u002Fticker\u002F24hr\u003C\u002Fcode>\u003C\u002Ftd>\u003Ctd>24시간 티커 통계\u003C\u002Ftd>\u003Ctd>\u003Ccode>symbol\u003C\u002Fcode> (생략 시 전체 심볼)\u003C\u002Ftd>\u003Ctd>1 (단일 심볼), 40 (전체 심볼)\u003C\u002Ftd>\u003C\u002Ftr>\n\u003Ctr>\u003Ctd>\u003Ccode>GET \u002Fapi\u002Fv3\u002Fticker\u002Fprice\u003C\u002Fcode>\u003C\u002Ftd>\u003Ctd>현재 가격\u003C\u002Ftd>\u003Ctd>\u003Ccode>symbol\u003C\u002Fcode> (생략 시 전체 심볼)\u003C\u002Ftd>\u003Ctd>1–2\u003C\u002Ftd>\u003C\u002Ftr>\n\u003C\u002Ftbody>\n\u003C\u002Ftable>\n\u003Cp>모든 응답에는 \u003Ccode>X-MBX-USED-WEIGHT-1M\u003C\u002Fcode> 헤더가 포함되어 있으므로, 클라이언트는 실시간으로 가중치 소비를 추적할 수 있습니다. 이 값을 모니터링하고 동적으로 요청 속도를 조절하는 것이 차단을 방지하는 핵심입니다.\u003C\u002Fp>\n\n\u003Ch2>ProxyHat 주거 프록시로 가중치 분산하기\u003C\u002Fh2>\n\u003Cp>ProxyHat \u003Ca href=\"\u002Fko\u002Fproxy\u002Fresidential\">주거 프록시\u003C\u002Fa>를 사용하면 각 요청마다 다른 IP를 할당받아 가중치를 분산시킬 수 있습니다. 바이낸스의 속도 제한은 IP 기반이므로, N개의 IP를 사용하면 이론적으로 분당 6,000 × N 가중치까지 처리할 수 있습니다.\u003C\u002Fp>\n\u003Cp>또한 바이낸스닷컴(Binance.com)은 미국 사용자에게 HTTP 451(법적 이유로 콘텐츠 사용 불가)을 반환합니다. ProxyHat의 \u003Ccode>-country-US\u003C\u002Fcode> 사용자 이름 플래그로 미국 IP를 타겟팅하면 바이낸스 US가 아닌 글로벌 바이낸스닷컴 엔드포인트에 접근할 수 있으며, 반대로 다른 국가 IP를 사용하면 지역 제한을 우회할 수 있습니다. \u003Ca href=\"\u002Fko\u002Flocations\">ProxyHat 프록시 위치\u003C\u002Fa> 페이지에서 사용 가능한 국가를 확인하세요.\u003C\u002Fp>\n\n\u003Ch3>ProxyHat 연결 파라미터\u003C\u002Fh3>\n\u003Ctable>\n\u003Cthead>\n\u003Ctr>\u003Cth>프로토콜\u003C\u002Fth>\u003Cth>게이트웨이\u003C\u002Fth>\u003Cth>포트\u003C\u002Fth>\u003Cth>URL 형식\u003C\u002Fth>\u003C\u002Ftr>\n\u003C\u002Fthead>\n\u003Ctbody>\n\u003Ctr>\u003Ctd>HTTP\u003C\u002Ftd>\u003Ctd>\u003Ccode>gate.proxyhat.com\u003C\u002Fcode>\u003C\u002Ftd>\u003Ctd>\u003Ccode>8080\u003C\u002Fcode>\u003C\u002Ftd>\u003Ctd>\u003Ccode>http:\u002F\u002FUSERNAME:PASSWORD@gate.proxyhat.com:8080\u003C\u002Fcode>\u003C\u002Ftd>\u003C\u002Ftr>\n\u003Ctr>\u003Ctd>SOCKS5\u003C\u002Ftd>\u003Ctd>\u003Ccode>gate.proxyhat.com\u003C\u002Fcode>\u003C\u002Ftd>\u003Ctd>\u003Ccode>1080\u003C\u002Fcode>\u003C\u002Ftd>\u003Ctd>\u003Ccode>socks5:\u002F\u002FUSERNAME:PASSWORD@gate.proxyhat.com:1080\u003C\u002Fcode>\u003C\u002Ftd>\u003C\u002Ftr>\n\u003C\u002Ftbody>\n\u003C\u002Ftable>\n\u003Cp>사용자 이름에 국가 및 세션 플래그를 추가할 수 있습니다:\u003C\u002Fp>\n\u003Cul>\n\u003Cli>\u003Ccode>user-country-US:pass\u003C\u002Fcode> — 미국 IP 사용\u003C\u002Fli>\n\u003Cli>\u003Ccode>user-country-DE-region-state_of_berlin-city-berlin:pass\u003C\u002Fcode> — 독일 베를린 IP 사용\u003C\u002Fli>\n\u003Cli>\u003Ccode>user-sid-abc123:pass\u003C\u002Fcode> — 고정 세션(스티키 IP)\u003C\u002Fli>\n\u003C\u002Ful>\n\n\u003Ch2>Python: 요청별 IP 로테이션으로 klines 수집\u003C\u002Fh2>\n\u003Cp>다음 예제는 \u003Ccode>requests\u003C\u002Fcode> 라이브러리와 ProxyHat 게이트웨이를 사용해 요청마다 새로운 주거 IP를 할당받아 바이낸스 klines 엔드포인트를 호출합니다. 가중치 추적, 지수 백오프 재시도, 429\u002F418 처리를 포함합니다.\u003C\u002Fp>\n\u003Cpre>\u003Ccode>import requests\nimport time\nimport logging\nfrom urllib.parse import urlencode\n\nlogging.basicConfig(level=logging.INFO, format=&quot;%(asctime)s [%(levelname)s] %(message)s&quot;)\nlogger = logging.getLogger(__name__)\n\nBINANCE_BASE = &quot;https:\u002F\u002Fapi.binance.com&quot;\nPROXYHAT_GATEWAY = &quot;gate.proxyhat.com&quot;\nPROXYHAT_PORT = 8080\nPROXYHAT_USER = &quot;your_username&quot;\nPROXYHAT_PASS = &quot;your_password&quot;\n\n# ProxyHat는 사용자 이름 플래그 없이 기본 로테이션(요청마다 새 IP)\ndef get_proxy_url(country=None, session_id=None):\n    username = PROXYHAT_USER\n    if country:\n        username += f&quot;-country-{country}&quot;\n    if session_id:\n        username += f&quot;-sid-{session_id}&quot;\n    return f&quot;http:\u002F\u002F{username}:{PROXYHAT_PASS}@{PROXYHAT_GATEWAY}:{PROXYHAT_PORT}&quot;\n\ndef fetch_klines(symbol, interval, limit=1000, max_retries=5):\n    &quot;&quot;&quot;바이낸스 klines를 ProxyHat 주거 프록시로 수집 (요청별 IP 로테이션)&quot;&quot;&quot;\n    params = {&quot;symbol&quot;: symbol, &quot;interval&quot;: interval, &quot;limit&quot;: limit}\n    url = f&quot;{BINANCE_BASE}\u002Fapi\u002Fv3\u002Fklines?{urlencode(params)}&quot;\n\n    for attempt in range(max_retries):\n        proxy_url = get_proxy_url()  # 매 요청마다 새 IP\n        proxies = {&quot;http&quot;: proxy_url, &quot;https&quot;: proxy_url}\n\n        try:\n            resp = requests.get(url, proxies=proxies, timeout=15)\n            used_weight = resp.headers.get(&quot;X-MBX-USED-WEIGHT-1M&quot;, &quot;unknown&quot;)\n            logger.info(f&quot;{symbol} {interval} | HTTP {resp.status_code} | weight-1m={used_weight}&quot;)\n\n            if resp.status_code == 200:\n                return resp.json()\n            elif resp.status_code == 429:\n                retry_after = int(resp.headers.get(&quot;Retry-After&quot;, 10))\n                logger.warning(f&quot;429 rate limited. Waiting {retry_after}s...&quot;)\n                time.sleep(retry_after)\n                continue\n            elif resp.status_code == 418:\n                logger.error(&quot;418 IP banned. Backing off 120s and rotating IP.&quot;)\n                time.sleep(120)\n                continue\n            else:\n                logger.error(f&quot;Unexpected status: {resp.status_code}&quot;)\n                resp.raise_for_status()\n\n        except requests.exceptions.RequestException as e:\n            backoff = min(2 ** attempt, 60)\n            logger.warning(f&quot;Request failed (attempt {attempt+1}): {e}. Retrying in {backoff}s...&quot;)\n            time.sleep(backoff)\n\n    raise RuntimeError(f&quot;Failed to fetch klines for {symbol} after {max_retries} retries&quot;)\n\n# 사용 예\ndata = fetch_klines(&quot;BTCUSDT&quot;, &quot;1m&quot;, limit=1000)\nprint(f&quot;Got {len(data)} candles&quot;)\n\u003C\u002Fcode>\u003C\u002Fpre>\n\n\u003Ch2>Python: httpx + ProxyHat SDK 스타일로 오더북 폴링\u003C\u002Fh2>\n\u003Cp>\u003Ccode>httpx\u003C\u002Fcode>를 사용하면 비동기 컨셉션으로 여러 심볼의 오더북을 동시에 수집할 수 있습니다. 다음 예제는 가중치 인식 스로틀링과 컨셉션 제한을 포함합니다.\u003C\u002Fp>\n\u003Cpre>\u003Ccode>import httpx\nimport asyncio\nimport logging\nimport time\n\nlogging.basicConfig(level=logging.INFO)\nlogger = logging.getLogger(__name__)\n\nBINANCE_BASE = &quot;https:\u002F\u002Fapi.binance.com&quot;\nPROXYHAT_USER = &quot;your_username&quot;\nPROXYHAT_PASS = &quot;your_password&quot;\n\nMAX_CONCURRENT = 10  # 동시 요청 수 제한\nWEIGHT_BUDGET_PER_MIN = 5500  # 안전 마진 500\n\n# 전역 가중치 추적\nused_weight_1m = 0\nweight_reset_time = time.time() + 60\n\ndef build_proxy_url(country=None):\n    user = PROXYHAT_USER\n    if country:\n        user += f&quot;-country-{country}&quot;\n    return f&quot;http:\u002F\u002F{user}:{PROXYHAT_PASS}@gate.proxyhat.com:8080&quot;\n\nasync def fetch_depth(client, symbol, limit=100):\n    &quot;&quot;&quot;오더북 수집 — limit=100은 가중치 1&quot;&quot;&quot;\n    global used_weight_1m, weight_reset_time\n\n    # 가중치 예산 체크\n    now = time.time()\n    if now &gt; weight_reset_time:\n        used_weight_1m = 0\n        weight_reset_time = now + 60\n    if used_weight_1m &gt;= WEIGHT_BUDGET_PER_MIN:\n        sleep_time = weight_reset_time - now\n        logger.info(f&quot;Weight budget reached. Sleeping {sleep_time:.1f}s...&quot;)\n        await asyncio.sleep(max(sleep_time, 1))\n\n    url = f&quot;{BINANCE_BASE}\u002Fapi\u002Fv3\u002Fdepth?symbol={symbol}&amp;limit={limit}&quot;\n    proxy = build_proxy_url()  # 요청별 IP 로테이션\n\n    try:\n        resp = await client.get(url, proxy=proxy, timeout=15)\n        weight = int(resp.headers.get(&quot;X-MBX-USED-WEIGHT-1M&quot;, 0))\n        used_weight_1m = max(used_weight_1m, weight)\n        logger.info(f&quot;{symbol} depth | HTTP {resp.status_code} | weight={weight}&quot;)\n        if resp.status_code == 200:\n            return {&quot;symbol&quot;: symbol, &quot;bids&quot;: resp.json()[&quot;bids&quot;][:10], &quot;asks&quot;: resp.json()[&quot;asks&quot;][:10]}\n        elif resp.status_code == 429:\n            retry_after = int(resp.headers.get(&quot;Retry-After&quot;, 10))\n            await asyncio.sleep(retry_after)\n    except Exception as e:\n        logger.error(f&quot;{symbol}: {e}&quot;)\n    return None\n\nasync def poll_multiple_symbols(symbols, limit=100):\n    &quot;&quot;&quot;여러 심볼의 오더북을 동시 폴링&quot;&quot;&quot;\n    semaphore = asyncio.Semaphore(MAX_CONCURRENT)\n\n    async def bounded_fetch(client, sym):\n        async with semaphore:\n            return await fetch_depth(client, sym, limit)\n\n    async with httpx.AsyncClient() as client:\n        tasks = [bounded_fetch(client, sym) for sym in symbols]\n        results = await asyncio.gather(*tasks, return_exceptions=True)\n        return [r for r in results if r is not None and not isinstance(r, Exception)]\n\n# 사용 예\nsymbols = [&quot;BTCUSDT&quot;, &quot;ETHUSDT&quot;, &quot;BNBUSDT&quot;, &quot;SOLUSDT&quot;, &quot;XRPUSDT&quot;]\nresults = asyncio.run(poll_multiple_symbols(symbols))\nprint(f&quot;Collected depth for {len(results)} symbols&quot;)\n\u003C\u002Fcode>\u003C\u002Fpre>\n\n\u003Ch2>Python: 스티키 세션으로 klines 백필 (페이지네이션)\u003C\u002Fh2>\n\u003Cp>과거 klines를 대량으로 백필할 때는 페이지네이션이 필요합니다. 동일한 IP로 연속 요청을 보내면 가중치가 누적되어 빠르게 차단되므로, 페이지 단위로 IP를 로테이션하거나 스티키 세션을 사용하는 것이 좋습니다. 다음 예제는 \u003Ccode>-sid-\u003C\u002Fcode> 플래그로 특정 페이지 범위 동안 같은 IP를 유지하면서 백필합니다.\u003C\u002Fp>\n\u003Cpre>\u003Ccode>import requests\nimport time\nimport logging\n\nlogging.basicConfig(level=logging.INFO)\nlogger = logging.getLogger(__name__)\n\nBINANCE_BASE = &quot;https:\u002F\u002Fapi.binance.com&quot;\nPROXYHAT_USER = &quot;your_username&quot;\nPROXYHAT_PASS = &quot;your_password&quot;\n\ndef build_sticky_proxy(session_id, country=None):\n    &quot;&quot;&quot;ProxyHat 스티키 세션 — 같은 session_id = 같은 IP&quot;&quot;&quot;\n    user = PROXYHAT_USER\n    if country:\n        user += f&quot;-country-{country}&quot;\n    user += f&quot;-sid-{session_id}&quot;\n    return f&quot;http:\u002F\u002F{user}:{PROXYHAT_PASS}@gate.proxyhat.com:8080&quot;\n\ndef backfill_klines(symbol, interval, start_time_ms, end_time_ms, batch_size=1000):\n    &quot;&quot;&quot;과거 klines를 페이지네이션으로 백필 — 페이지마다 새 스티키 세션(새 IP)&quot;&quot;&quot;\n    all_candles = []\n    current_start = start_time_ms\n    page = 0\n\n    while current_start &lt; end_time_ms:\n        # 페이지마다 새 세션 ID → 새 IP 할당\n        session_id = f&quot;backfill-{symbol}-{page}&quot;\n        proxy_url = build_sticky_proxy(session_id)\n        proxies = {&quot;http&quot;: proxy_url, &quot;https&quot;: proxy_url}\n\n        params = {\n            &quot;symbol&quot;: symbol,\n            &quot;interval&quot;: interval,\n            &quot;startTime&quot;: current_start,\n            &quot;endTime&quot;: end_time_ms,\n            &quot;limit&quot;: batch_size,\n        }\n        url = f&quot;{BINANCE_BASE}\u002Fapi\u002Fv3\u002Fklines&quot;\n\n        for attempt in range(5):\n            try:\n                resp = requests.get(url, params=params, proxies=proxies, timeout=20)\n                weight = resp.headers.get(&quot;X-MBX-USED-WEIGHT-1M&quot;, &quot;?&quot;)\n                logger.info(f&quot;Page {page} | HTTP {resp.status_code} | weight={weight} | session={session_id}&quot;)\n\n                if resp.status_code == 200:\n                    candles = resp.json()\n                    if not candles:\n                        logger.info(&quot;No more data.&quot;)\n                        return all_candles\n                    all_candles.extend(candles)\n                    # 다음 페이지 시작 시간 = 마지막 캔들 종료 시간 + 1ms\n                    current_start = candles[-1][6] + 1\n                    page += 1\n                    time.sleep(0.2)  # 가중치 완화를 위한 최소 대기\n                    break\n                elif resp.status_code == 429:\n                    retry_after = int(resp.headers.get(&quot;Retry-After&quot;, 10))\n                    logger.warning(f&quot;429 on page {page}. Waiting {retry_after}s...&quot;)\n                    time.sleep(retry_after)\n                    # 새 IP로 세션 교체\n                    session_id = f&quot;backfill-{symbol}-{page}-retry&quot;\n                    proxy_url = build_sticky_proxy(session_id)\n                    proxies = {&quot;http&quot;: proxy_url, &quot;https&quot;: proxy_url}\n                elif resp.status_code == 418:\n                    logger.error(&quot;418 banned. Rotating IP and waiting 120s.&quot;)\n                    time.sleep(120)\n                    session_id = f&quot;backfill-{symbol}-{page}-ban&quot;\n                    proxy_url = build_sticky_proxy(session_id)\n                    proxies = {&quot;http&quot;: proxy_url, &quot;https&quot;: proxy_url}\n                else:\n                    resp.raise_for_status()\n            except requests.RequestException as e:\n                backoff = min(2 ** attempt, 60)\n                logger.warning(f&quot;Error on page {page}: {e}. Backoff {backoff}s.&quot;)\n                time.sleep(backoff)\n        else:\n            logger.error(f&quot;Failed page {page} after retries. Stopping.&quot;)\n            break\n\n    return all_candles\n\n# 사용 예: BTCUSDT 1분봉 2024-01-01 ~ 2024-01-07 백필\nstart = 1704067200000  # 2024-01-01 00:00:00 UTC ms\ncandles = backfill_klines(&quot;BTCUSDT&quot;, &quot;1m&quot;, start, start + 7 * 86400000)\nprint(f&quot;Total candles: {len(candles)}&quot;)\n\u003C\u002Fcode>\u003C\u002Fpre>\n\n\u003Ch2>Node.js: axios로 24시간 티커 수집\u003C\u002Fh2>\n\u003Cp>Node.js 환경에서는 \u003Ccode>axios\u003C\u002Fcode>와 \u003Ccode>https-proxy-agent\u003C\u002Fcode>를 조합해 ProxyHat 프록시를 사용할 수 있습니다. 다음 예제는 전체 심볼의 24시간 티커를 수집하되, 가중치 40이 소모되는 전체 심볼 조회 대신 개별 심볼 조회(가중치 1)를 병렬로 수행합니다.\u003C\u002Fp>\n\u003Cpre>\u003Ccode>const axios = require(&apos;axios&apos;);\nconst { HttpsProxyAgent } = require(&apos;https-proxy-agent&apos;);\nconst pLimit = require(&apos;p-limit&apos;);\n\nconst BINANCE_BASE = &apos;https:\u002F\u002Fapi.binance.com&apos;;\nconst PROXYHAT_USER = &apos;your_username&apos;;\nconst PROXYHAT_PASS = &apos;your_password&apos;;\nconst GATEWAY = &apos;gate.proxyhat.com&apos;;\nconst PORT = 8080;\n\n\u002F\u002F ProxyHat 프록시 URL 생성 (요청별 로테이션)\nfunction buildProxyUrl(country = null) {\n  let user = PROXYHAT_USER;\n  if (country) user += `-country-${country}`;\n  return `http:\u002F\u002F${user}:${PROXYHAT_PASS}@${GATEWAY}:${PORT}`;\n}\n\n\u002F\u002F 지수 백오프 재시도 래퍼\nasync function fetchWithRetry(url, proxyUrl, maxRetries = 5) {\n  for (let attempt = 0; attempt &lt; maxRetries; attempt++) {\n    try {\n      const agent = new HttpsProxyAgent(proxyUrl);\n      const resp = await axios.get(url, {\n        httpsAgent: agent,\n        timeout: 15000,\n        headers: { &apos;User-Agent&apos;: &apos;MarketDataCollector\u002F1.0&apos; },\n      });\n      const weight = resp.headers[&apos;x-mbx-used-weight-1m&apos;] || &apos;unknown&apos;;\n      console.log(`HTTP ${resp.status} | weight-1m=${weight}`);\n      return resp.data;\n    } catch (err) {\n      const status = err.response?.status;\n      if (status === 429) {\n        const retryAfter = parseInt(err.response.headers[&apos;retry-after&apos;] || &apos;10&apos;, 10);\n        console.warn(`429 rate limited. Waiting ${retryAfter}s...`);\n        await new Promise(r =&gt; setTimeout(r, retryAfter * 1000));\n        \u002F\u002F 새 프록시 URL (새 IP)\n        continue;\n      } else if (status === 418) {\n        console.error(&apos;418 IP banned. Waiting 120s...&apos;);\n        await new Promise(r =&gt; setTimeout(r, 120000));\n        continue;\n      }\n      const backoff = Math.min(Math.pow(2, attempt), 60);\n      console.warn(`Attempt ${attempt + 1} failed: ${err.message}. Backoff ${backoff}s.`);\n      await new Promise(r =&gt; setTimeout(r, backoff * 1000));\n    }\n  }\n  throw new Error(`Failed after ${maxRetries} retries`);\n}\n\n\u002F\u002F 여러 심볼의 24hr ticker를 병렬 수집 (가중치 1 per 심볼)\nasync function fetch24hrTickers(symbols) {\n  const limit = pLimit(10); \u002F\u002F 동시 10개 제한\n  const results = await Promise.all(\n    symbols.map(sym =&gt;\n      limit(async () =&gt; {\n        const url = `${BINANCE_BASE}\u002Fapi\u002Fv3\u002Fticker\u002F24hr?symbol=${sym}`;\n        const proxyUrl = buildProxyUrl(); \u002F\u002F 각 요청마다 새 IP\n        try {\n          const data = await fetchWithRetry(url, proxyUrl);\n          return { symbol: sym, lastPrice: data.lastPrice, volume: data.volume };\n        } catch (e) {\n          console.error(`${sym} failed: ${e.message}`);\n          return null;\n        }\n      })\n    )\n  );\n  return results.filter(r =&gt; r !== null);\n}\n\n\u002F\u002F 사용 예\n(async () =&gt; {\n  const symbols = [&apos;BTCUSDT&apos;, &apos;ETHUSDT&apos;, &apos;BNBUSDT&apos;, &apos;SOLUSDT&apos;, &apos;XRPUSDT&apos;,\n                   &apos;ADAUSDT&apos;, &apos;DOGEUSDT&apos;, &apos;AVAXUSDT&apos;, &apos;DOTUSDT&apos;, &apos;LINKUSDT&apos;];\n  const tickers = await fetch24hrTickers(symbols);\n  console.log(`Collected ${tickers.length} tickers`);\n  tickers.forEach(t =&gt; console.log(`${t.symbol}: $${t.lastPrice} (vol: ${t.volume})`));\n})();\n\u003C\u002Fcode>\u003C\u002Fpre>\n\n\u003Ch2>curl: 단일 요청으로 가중치 헤더 확인\u003C\u002Fh2>\n\u003Cp>가장 빠르게 ProxyHat 프록시를 통해 바이낸스 API 응답 헤더를 확인하는 방법입니다. \u003Ccode>-v\u003C\u002Fcode> 플래그로 \u003Ccode>X-MBX-USED-WEIGHT-1M\u003C\u002Fcode> 헤더를 직접 확인할 수 있습니다.\u003C\u002Fp>\n\u003Cpre>\u003Ccode># ProxyHat HTTP 프록시로 klines 호출 + 응답 헤더 확인\ncurl -v --proxy &quot;http:\u002F\u002Fyour_username:your_password@gate.proxyhat.com:8080&quot; \\\n  &quot;https:\u002F\u002Fapi.binance.com\u002Fapi\u002Fv3\u002Fklines?symbol=BTCUSDT&amp;interval=1m&amp;limit=10&quot; \\\n  2&gt;&amp;1 | grep -i &quot;x-mbx-used-weight-1m&quot;\n\n# 미국 IP로 타겟팅\ncurl -v --proxy &quot;http:\u002F\u002Fyour_username-country-US:your_password@gate.proxyhat.com:8080&quot; \\\n  &quot;https:\u002F\u002Fapi.binance.com\u002Fapi\u002Fv3\u002Fticker\u002Fprice?symbol=BTCUSDT&quot;\n\n# SOCKS5 프록시로 오더북 호출\ncurl -v --proxy &quot;socks5:\u002F\u002Fyour_username:your_password@gate.proxyhat.com:1080&quot; \\\n  &quot;https:\u002F\u002Fapi.binance.com\u002Fapi\u002Fv3\u002Fdepth?symbol=BTCUSDT&amp;limit=100&quot;\n\u003C\u002Fcode>\u003C\u002Fpre>\n\n\u003Ch2>WebSocket vs REST: 언제 어떤 것을 사용해야 하는가\u003C\u002Fh2>\n\u003Cp>바이낸스는 \u003Ccode>wss:\u002F\u002Fstream.binance.com:9443\u003C\u002Fcode>을 통해 WebSocket 스트림을 제공합니다. REST 폴링과 WebSocket의 선택 기준은 다음과 같습니다.\u003C\u002Fp>\n\u003Ctable>\n\u003Cthead>\n\u003Ctr>\u003Cth>기준\u003C\u002Fth>\u003Cth>REST 폴링\u003C\u002Fth>\u003Cth>WebSocket 스트림\u003C\u002Fth>\u003C\u002Ftr>\n\u003C\u002Fthead>\n\u003Ctbody>\n\u003Ctr>\u003Ctd>적합 시나리오\u003C\u002Ftd>\u003Ctd>과거 데이터 백필, 간헐 조회, 페이지네이션\u003C\u002Ftd>\u003Ctd>실시간 오더북, 실시간 가격, 지속 스트리밍\u003C\u002Ftd>\u003C\u002Ftr>\n\u003Ctr>\u003Ctd>가중치 소비\u003C\u002Ftd>\u003Ctd>요청마다 가중치 소모\u003C\u002Ftd>\u003Ctd>연결당 가중치 소모 없음 (연결 제한 별도)\u003C\u002Ftd>\u003C\u002Ftr>\n\u003Ctr>\u003Ctd>지연\u003C\u002Ftd>\u003Ctd>요청당 100–500ms\u003C\u002Ftd>\u003Ctd>실시간 (10–50ms)\u003C\u002Ftd>\u003C\u002Ftr>\n\u003Ctr>\u003Ctd>IP 차단 위험\u003C\u002Ftd>\u003Ctd>높음 (가중치 기반)\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>실시간 오더북이 필요하다면 \u003Ccode>wss:\u002F\u002Fstream.binance.com:9443\u002Fws\u002Fbtcusdt@depth\u003C\u002Fcode> 스트림을 사용하는 것이 REST 폴링보다 효율적입니다. 하지만 과거 데이터 백필이나 간헐적 스냅샷 수집에는 REST API가 적합하며, 이때 ProxyHat 프록시로 가중치를 분산하는 것이 핵심입니다. WebSocket 연결에도 프록시가 필요한 경우 SOCKS5(\u003Ccode>gate.proxyhat.com:1080\u003C\u002Fcode>)를 사용할 수 있습니다.\u003C\u002Fp>\n\n\u003Ch2>흔한 실수와 엣지 케이스\u003C\u002Fh2>\n\u003Cul>\n\u003Cli>X-MBX-USED-WEIGHT-1M 무시: 응답 헤더를 추적하지 않으면 429를 예상 없이 맞게 됩니다. 모든 요청에서 이 헤더를 로깅하세요.\u003C\u002Fli>\n\u003Cli>limit=1000 depth 남용: 가중치 10을 소모합니다. limit=100(가중치 1)으로 충분한 경우가 많습니다.\u003C\u002Fli>\n\u003Cli>전체 심볼 24hr ticker 호출: \u003Ccode>\u002Fapi\u002Fv3\u002Fticker\u002F24hr\u003C\u002Fcode>를 심볼 없이 호출하면 가중치 40이 소모됩니다. 필요한 심볼만 개별 조회(가중치 1)하는 것이 효율적입니다.\u003C\u002Fli>\n\u003Cli>동일 IP로 연속 429 후 재시도: 429 후 같은 IP로 계속 요청하면 418로 에스컬레이션됩니다. 반드시 IP를 로테이션하고 \u003Ccode>Retry-After\u003C\u002Fcode> 대기 시간을 준수하세요.\u003C\u002Fli>\n\u003Cli>HTTP 451 (지역 제한): 바이낸스닷컴이 특정 지역 IP를 차단할 때 반환됩니다. \u003Ccode>-country-US\u003C\u002Fcode> 또는 다른 국가 플래그로 우회하세요.\u003C\u002Fli>\n\u003Cli>재시도 없는 단일 실패: 네트워크 타임아웃, 프록시 연결 실패 등은 일시적일 수 있습니다. 지수 백오프 재시도를 기본으로 구현하세요.\u003C\u002Fli>\n\u003C\u002Ful>\n\n\u003Ch2>ProxyHat 설정 및 내부 링크\u003C\u002Fh2>\n\u003Cp>ProxyHat 주거 프록시를 사용하면 바이낸스 REST API 스크래핑 시 가중치를 여러 IP에 분산시킬 수 있습니다. \u003Ca href=\"\u002Fko\u002Fpricing\">ProxyHat 요금제\u003C\u002Fa>에서 주거\u002F데이터센터\u002F모바일 프록시 옵션을 확인하고, \u003Ca href=\"\u002Fko\u002Fuse-cases\u002Fweb-scraping\">웹 스크래핑 사용 사례\u003C\u002Fa> 페이지에서 다른 스크래핑 시나리오를 참조하세요. SERP 추적과 관련된 작업은 \u003Ca href=\"\u002Fko\u002Fuse-cases\u002Fserp-tracking\">SERP 추적 사용 사례\u003C\u002Fa>를 확인하시고, ProxyHat SDK 및 API 문법은 \u003Ca href=\"https:\u002F\u002Fdocs.proxyhat.com\u002F\" rel=\"noopener noreferrer\">ProxyHat 공식 문서\u003C\u002Fa>를 참조하세요.\u003C\u002Fp>\n\n\u003Ch2>핵심 요약\u003C\u002Fh2>\n\u003Cblockquote>\n\u003Cul>\n\u003Cli>바이낸스 REST API는 IP당 분당 약 6,000 가중치 제한을 가지며, 초과 시 429 → 418로 에스컬레이션됩니다.\u003C\u002Fli>\n\u003Cli>\u003Ccode>X-MBX-USED-WEIGHT-1M\u003C\u002Fcode> 헤더를 실시간 추적하여 동적으로 요청 속도를 조절하세요.\u003C\u002Fli>\n\u003Cli>ProxyHat 주거 프록시(\u003Ccode>gate.proxyhat.com:8080\u003C\u002Fcode>)로 요청별 IP 로테이션을 사용하면 가중치를 여러 IP에 분산할 수 있습니다.\u003C\u002Fli>\n\u003Cli>과거 데이터 백필에는 스티키 세션(\u003Ccode>-sid-\u003C\u002Fcode>), 실시간 데이터에는 WebSocket 스트림이 적합합니다.\u003C\u002Fli>\n\u003Cli>\u003Ccode>-country-US\u003C\u002Fcode> 플래그로 바이낸스닷컴 지역 제한(HTTP 451)을 우회할 수 있습니다.\u003C\u002Fli>\n\u003Cli>지수 백오프 재시도, 컨셉션 제한, 가중치 인식 스로틀링을 프로덕션 코드에 기본으로 포함하세요.\u003C\u002Fli>\n\u003C\u002Ful>\n\u003C\u002Fblockquote>","거래소 API 가중치 제한과 프록시 데이터 수집 (바이낸스) | ProxyHat","바이낸스 REST API 프록시 스크래핑: 가중치 제한, 429\u002F418 차단 우회, ProxyHat 주거 프록시로 klines·depth·ticker 대규모 수집 방법을 코드와 함께 설명합니다.","\u002Fko\u002Fblog\u002Fbinance-rest-api-proxy-scraping",null,"암호화폐 거래소 API 가중치 제한 가이드 | ProxyHat","https:\u002F\u002Fstatic.proxyhat.com\u002Fstorage\u002Fblog-covers\u002Fko\u002Fbinance-rest-api-proxy-scraping-og.webp",[18,21],{"question":19,"answer":20},"프록시 사용자에게 바이낸스 REST API 스크래핑이 중요한 이유는 무엇인가요?","바이낸스는 IP 기반 가중치 제한을 사용하므로, 단일 IP로 대규모 데이터를 수집하면 빠르게 429 또는 418 응답을 받게 됩니다. 프록시를 사용해 IP를 로테이션하면 가중치를 분산시켜 차단 없이 지속적인 데이터 수집이 가능하며, 지역 제한(HTTP 451)도 우회할 수 있습니다.",{"question":22,"answer":23},"바이낸스 REST API 스크래핑 시 차단을 피하려면 어떻게 해야 하나요?","세 가지 핵심 전략이 있습니다: X-MBX-USED-WEIGHT-1M 헤더를 모니터링하여 가중치 예산에 가까워지면 자동으로 속도를 줄이세요. 429 응답 시 Retry-After 헤더를 준수하고 즉시 IP를 로테이션하세요. 동시 요청 수를 제한하고 지수 백오프 재시도를 구현하세요. 또한 limit 파라미터를 최소화하여 가중치 소모를 줄이는 것이 중요합니다.",false,"2026-08-03T10:04:04+00:00","2026-10-04T01:29:50+00:00","https:\u002F\u002Fstatic.proxyhat.com\u002Fstorage\u002Fblog-covers\u002Fko\u002Fbinance-rest-api-proxy-scraping-master.webp","How to Scrape the Binance REST API with Proxies: A Developer Guide","https:\u002F\u002Fstatic.proxyhat.com\u002Fstorage\u002Fblog-covers\u002Fko\u002Fbinance-rest-api-proxy-scraping-card.webp",12,{"name":32,"slug":33,"bio":34,"avatar_url":14,"website_url":14,"social_links":14},"ProxyHat Team","proxyhat-team","The ProxyHat editorial team covers proxies, web scraping, and data extraction.",[36],{"id":37,"slug":38,"name":39,"description":14,"meta_title":40,"meta_description":41,"parent_id":14},4,"gaebaljja-gaideu","개발자 가이드","개발자 가이드 | ProxyHat 블로그","프록시를 애플리케이션에 통합하기 위한 코드 튜토리얼 및 SDK 가이드.",[],{"fr":44,"en":45,"pt":46,"ko":13,"ru":47,"zh":48,"x-default":45},"\u002Ffr\u002Fblog\u002Fcomment-scraper-api-rest-binance-proxies","\u002Fblog\u002Fscrape-binance-rest-api-proxies","\u002Fpt\u002Fblog\u002Fcomo-raspar-api-binance-proxies","\u002Fru\u002Fblog\u002Fkak-skrejpit-binance-rest-api-proksi","\u002Fcn\u002Fblog\u002Fbinance-rest-api-proxy-scraping-guide",{"tr":50,"fr":44,"en":45,"pl":51,"ja":52,"pt":46,"ko":13,"es":53,"ru":47,"zh":48,"it":54,"de":55},"\u002Ftr\u002Fblog\u002Fbinance-rest-api-proxy-tarama","\u002Fpl\u002Fblog\u002Fjak-scrapowac-rest-api-binance-proxy","\u002Fja\u002Fblog\u002Fbinance-api-scraping-proxy","\u002Fes\u002Fblog\u002Fscrapear-api-binance-proxies","\u002Fit\u002Fblog\u002Fscraping-binance-rest-api-con-proxy","\u002Fde\u002Fblog\u002Fbinance-rest-api-mit-proxies-scrapen",81,[58,91,118,134],{"id":59,"slug":60,"title":61,"excerpt":62,"featured_image_url":63,"featured_image_alt":64,"card_image_url":65,"og_image_url":66,"published_at":67,"updated_at":68,"content_updated_at":69,"reading_time_minutes":70,"is_featured":24,"indexable":4,"views":70,"author":71,"categories":72,"tags":74},210,"ai-agent-proxy-seoljeong","AI 에이전트 프록시 설정: browser-use·Crawl4AI·MCP","클라우드 VM의 에이전트는 데이터센터 IP로 접속합니다. browser-use, Crawl4AI, MCP 서버에서 지금 작동하는 프록시 설정을 sticky와 로테이션 선택 표, 피해야 할 비용 함정과 함께 정리했습니다.","https:\u002F\u002Fstatic.proxyhat.com\u002Fstorage\u002Fblog-covers\u002Fko\u002Fai-agent-proxy-seoljeong-master.webp","Proxy Setup for AI Agents: browser-use, Crawl4AI and an MCP Server","https:\u002F\u002Fstatic.proxyhat.com\u002Fstorage\u002Fblog-covers\u002Fko\u002Fai-agent-proxy-seoljeong-card.webp","https:\u002F\u002Fstatic.proxyhat.com\u002Fstorage\u002Fblog-covers\u002Fko\u002Fai-agent-proxy-seoljeong-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":32,"slug":33,"bio":34,"avatar_url":14,"website_url":14,"social_links":14},[73],{"id":37,"slug":38,"name":39,"description":14,"meta_title":40,"meta_description":41,"parent_id":14},[75,79,83,87],{"id":76,"slug":77,"name":78},1,"web-scraping","웹 스크래핑",{"id":80,"slug":81,"name":82},2,"residential-proxies","주거용 프록시",{"id":84,"slug":85,"name":86},9,"python","Python",{"id":88,"slug":89,"name":90},22,"playwright","Playwright",{"id":92,"slug":93,"title":94,"excerpt":95,"featured_image_url":96,"featured_image_alt":97,"card_image_url":98,"og_image_url":99,"published_at":100,"updated_at":101,"content_updated_at":69,"reading_time_minutes":70,"is_featured":24,"indexable":4,"views":102,"author":103,"categories":104,"tags":106},206,"camoufox-residential-proxy-python-gaideu","Camoufox와 레지덴셜 프록시: 코드로 보는 Python 가이드","C++ 레벨에서 패치한 Firefox인 Camoufox를 레지덴셜 프록시 뒤에서 돌리는 방법. 최신 Python API, geoip에 스티키 세션이 필요한 이유, 핑거프린트 일관성 체크리스트, 그리고 Patchright나 nodriver가 더 맞는 경우를 정리했습니다.","https:\u002F\u002Fstatic.proxyhat.com\u002Fstorage\u002Fblog-covers\u002Fko\u002Fcamoufox-residential-proxy-python-gaideu-master.webp","Camoufox with Residential Proxies: A Code-First Python Guide","https:\u002F\u002Fstatic.proxyhat.com\u002Fstorage\u002Fblog-covers\u002Fko\u002Fcamoufox-residential-proxy-python-gaideu-card.webp","https:\u002F\u002Fstatic.proxyhat.com\u002Fstorage\u002Fblog-covers\u002Fko\u002Fcamoufox-residential-proxy-python-gaideu-og.webp","2026-10-13T09:00:00+00:00","2026-10-13T09:00:22+00:00",29,{"name":32,"slug":33,"bio":34,"avatar_url":14,"website_url":14,"social_links":14},[105],{"id":37,"slug":38,"name":39,"description":14,"meta_title":40,"meta_description":41,"parent_id":14},[107,108,109,113,114],{"id":76,"slug":77,"name":78},{"id":80,"slug":81,"name":82},{"id":110,"slug":111,"name":112},6,"anti-detection","안티 탐지",{"id":84,"slug":85,"name":86},{"id":115,"slug":116,"name":117},21,"headless-browser","헤드리스 브라우저",{"id":119,"slug":120,"title":121,"excerpt":122,"featured_image_url":123,"featured_image_alt":124,"card_image_url":125,"og_image_url":126,"published_at":127,"updated_at":127,"content_updated_at":128,"reading_time_minutes":30,"is_featured":24,"indexable":4,"views":129,"author":130,"categories":131,"tags":133},176,"got-scraping-nodejs-proxy-guide-1","Node.js에서 got-scraping과 주거 프록시로 웹 스크래핑하기","got-scraping의 헤더 생성기와 HTTP\u002F2 지원을 활용해 차단을 우회하는 방법, ProxyHat 주거 프록시 라우팅, 그리고 Crawlee 통합까지 다루는 실전 가이드입니다.","https:\u002F\u002Fstatic.proxyhat.com\u002Fstorage\u002Fblog-covers\u002Fko\u002Fgot-scraping-nodejs-proxy-guide-1-master.webp","got-scraping in Node.js: A Developer's Guide with Residential Proxies","https:\u002F\u002Fstatic.proxyhat.com\u002Fstorage\u002Fblog-covers\u002Fko\u002Fgot-scraping-nodejs-proxy-guide-1-card.webp","https:\u002F\u002Fstatic.proxyhat.com\u002Fstorage\u002Fblog-covers\u002Fko\u002Fgot-scraping-nodejs-proxy-guide-1-og.webp","2026-08-04T16:05:06+00:00","2026-10-03T08:29:58+00:00",120,{"name":32,"slug":33,"bio":34,"avatar_url":14,"website_url":14,"social_links":14},[132],{"id":37,"slug":38,"name":39,"description":14,"meta_title":40,"meta_description":41,"parent_id":14},[],{"id":135,"slug":136,"title":137,"excerpt":138,"featured_image_url":139,"featured_image_alt":140,"card_image_url":141,"og_image_url":142,"published_at":143,"updated_at":143,"content_updated_at":144,"reading_time_minutes":30,"is_featured":24,"indexable":24,"views":145,"author":146,"categories":147,"tags":149},175,"colly-rotating-proxy-guide","Colly에서 로테이션 프록시 사용하기: Go 웹 스크래핑 완전 가이드","Go의 Colly 프레임워크에서 RoundRobinProxySwitcher와 SetProxyFunc를 활용해 ProxyHat 주거 프록시를 로테이션하는 방법을 코드 예제와 함께 다룹니다. 프로덕션 패턴, 재시도, 분산 스크래핑까지.","https:\u002F\u002Fstatic.proxyhat.com\u002Fstorage\u002Fblog-covers\u002Fko\u002Fcolly-rotating-proxy-guide-master.webp","Rotating Proxies in Colly: A Framework-Idiomatic Guide for Go Developers","https:\u002F\u002Fstatic.proxyhat.com\u002Fstorage\u002Fblog-covers\u002Fko\u002Fcolly-rotating-proxy-guide-card.webp","https:\u002F\u002Fstatic.proxyhat.com\u002Fstorage\u002Fblog-covers\u002Fko\u002Fcolly-rotating-proxy-guide-og.webp","2026-08-04T10:05:34+00:00","2026-10-03T23:53:00+00:00",71,{"name":32,"slug":33,"bio":34,"avatar_url":14,"website_url":14,"social_links":14},[148],{"id":37,"slug":38,"name":39,"description":14,"meta_title":40,"meta_description":41,"parent_id":14},[],[]]