Как скрейпить Binance REST API через прокси: руководство для разработчиков

Практическое руководство по сбору публичных рыночных данных Binance REST API через вращающиеся резидентные прокси: эндпоинты, весовые лимиты, ротация IP, код на Python и Node.js.

How to Scrape the Binance REST API with Proxies: A Developer Guide
В этой статье

Как скрейпить Binance REST API через прокси: быстрый ответ

Чтобы скрейпить Binance REST API через прокси, нужно направлять запросы к публичным эндпоинтам api.binance.com через вращающиеся резидентные прокси gate.proxyhat.com:8080, распределяя весовые лимиты по нескольким IP-адресам. Binance использует весовую систему ограничения скорости — около 6000 единиц веса в минуту на IP. Ротация IP через прокси позволяет собирать данные свечей (klines), книги ордеров (depth) и тикеров в масштабе, недоступном с одного адреса.

Дисклеймер: Данная статья охватывает только публичные рыночные данные Binance (эндпоинты /api/v3/ без аутентификации). Уважайте Условия использования Binance и весовые лимиты API. Если ваши задачи требуют официального доступа, используйте официальную документацию Binance API и при необходимости запрашивайте повышенные лимиты через поддержку.

Технический контекст: эндпоинты, веса и лимиты

Binance REST API для спот-торговли работает на домене api.binance.com и предоставляет публичные эндпоинты рыночных данных без аутентификации. Каждый запрос имеет вес — единицу нагрузки, которая вычитается из минутного бюджета IP-адреса. Заголовок ответа X-MBX-USED-WEIGHT-1M показывает текущий израсходованный вес за последнюю минуту.

Ключевые эндпоинты публичных рыночных данных

ЭндпоинтНазначениеВес (зависит от параметров)
/api/v3/klinesСвечи (OHLCV) по интервалам1 (limit ≤ 100), 2 (limit > 100)
/api/v3/depthКнига ордеров (bid/ask)1–20 (зависит от limit)
/api/v3/ticker/24hr24-часовая статистика1 (1 символ), 80 (все)
/api/v3/ticker/priceТекущая цена1 (1 символ), 2 (все)

Весовая система лимитов и блокировки

Binance применяет весовое ограничение скорости — примерно 6000 единиц веса в минуту на IP-адрес для спот-API. Превышение приводит к следующим ответам:

  • HTTP 429 — превышен лимит скорости. Запросы нужно приостановить. Заголовок Retry-After указывает время ожидания в секундах.
  • HTTP 418 — IP автоматически заблокирован после многократных нарушений 429. Бан длится от 2 минут до нескольких дней.
  • HTTP 451 — регион недоступен (географическое ограничение, актуально для Binance.com в США).

Тесный поллинг /api/v3/depth с limit=1000 (вес 5) исчерпает бюджет 6000 за ~1200 запросов — примерно 20 запросов в секунду исчерпают лимит за 5 минут. С limit=5000 (вес 20) бюджет уйдёт за 300 запросов — менее чем за 2 минуты при 3 запросах/сек. Подробнее см. в официальной документации Binance Spot API и MDN: HTTP 429 Too Many Requests.

Почему прокси необходимы для скрейпинга Binance

С одного IP-адреса вы упрётесь в лимит 6000 веса/мин. Для quant-разработчиков и инженеров криптоданных, собирающих исторические свечи по десяткам торговых пар или поллинг книги ордеров с высокой частотой, этого недостаточно. Вращающиеся резидентные прокси распределяют вес по пулу IP-адресов — каждый IP получает свой бюджет 6000/мин.

Дополнительно, Binance разделяет binance.com (глобальный) и binance.us (США). Запросы к глобальному API из США могут получить HTTP 451. Геотаргетинг ProxyHat через параметр -country-US в имени пользователя позволяет направлять запросы через IP нужной страны.

Практическая реализация: код и примеры

1. Базовый запрос через ProxyHat (curl, HTTP)

Простейший способ — направить запрос через HTTP-прокси ProxyHat с геотаргетингом на США:

# Получение свечей BTCUSDT через прокси с IP в США
curl -x "http://user-country-US:pass@gate.proxyhat.com:8080" \
  "https://api.binance.com/api/v3/klines?symbol=BTCUSDT&interval=1m&limit=100"

# Проверка израсходованного веса
curl -s -o /dev/null -D - -x "http://user-country-US:pass@gate.proxyhat.com:8080" \
  "https://api.binance.com/api/v3/ticker/price?symbol=BTCUSDT" \
  | grep -i "x-mbx-used-weight-1m"

2. Python requests: ротация IP через ProxyHat SDK-паттерн

Инкапсулируем логику ProxyHat в класс-обёртку (SDK-паттерн) с отслеживанием веса, retry с экспоненциальной задержкой и автоматической ротацией IP:

import requests
import time
import logging
from urllib.parse import urlencode

logging.basicConfig(level=logging.INFO, format="%(asctime)s %(levelname)s %(message)s")
logger = logging.getLogger("binance_scraper")

class ProxyHatBinanceClient:
    """SDK-обёртка для скрейпинга Binance через ротацию IP ProxyHat."""

    BASE_URL = "https://api.binance.com"
    GATE = "gate.proxyhat.com:8080"
    MAX_WEIGHT_PER_MIN = 5500  # буфер 500 ниже лимита 6000

    def __init__(self, username: str, password: str, country: str = None):
        self.username = username
        self.password = password
        self.country = country
        self.used_weight = 0
        self.session = requests.Session()

    def _proxy_url(self, session_id: str = None) -> str:
        """Формирует URL прокси с опциональной гео-привязкой и сессией."""
        user = self.username
        if self.country:
            user += f"-country-{self.country}"
        if session_id:
            user += f"-session-{session_id}"
        return f"http://{user}:{self.password}@{self.GATE}"

    def _request(self, path: str, params: dict = None, session_id: str = None) -> dict:
        """Выполняет запрос с retry, отслеживанием веса и ротацией IP."""
        url = f"{self.BASE_URL}{path}"
        proxies = {"http": self._proxy_url(session_id), "https": self._proxy_url(session_id)}

        for attempt in range(5):
            # Throttle: если вес близок к лимиту — ждём
            if self.used_weight >= self.MAX_WEIGHT_PER_MIN:
                logger.info("Weight limit reached (%d), cooling down 60s", self.used_weight)
                time.sleep(60)
                self.used_weight = 0

            try:
                resp = self.session.get(url, params=params, proxies=proxies, timeout=15)
                # Обновляем отслеживание веса
                weight_header = resp.headers.get("X-MBX-USED-WEIGHT-1M")
                if weight_header:
                    self.used_weight = int(weight_header)
                    logger.debug("Used weight: %s", weight_header)

                if resp.status_code == 429:
                    retry_after = int(resp.headers.get("Retry-After", 10))
                    logger.warning("429 rate limited, waiting %ds", retry_after)
                    time.sleep(retry_after)
                    continue

                if resp.status_code == 418:
                    logger.error("418 IP banned! Waiting 120s before retry")
                    time.sleep(120)
                    continue

                resp.raise_for_status()
                return resp.json()

            except requests.RequestException as e:
                wait = 2 ** attempt
                logger.warning("Attempt %d failed: %s, retrying in %ds", attempt + 1, e, wait)
                time.sleep(wait)

        raise RuntimeError(f"Failed after 5 attempts: {path}")

    def get_klines(self, symbol: str, interval: str = "1m", limit: int = 100) -> list:
        return self._request("/api/v3/klines", {
            "symbol": symbol, "interval": interval, "limit": limit
        })

    def get_depth(self, symbol: str, limit: int = 100) -> dict:
        return self._request("/api/v3/depth", {
            "symbol": symbol, "limit": limit
        })

    def get_ticker_24hr(self, symbol: str = None) -> dict | list:
        params = {"symbol": symbol} if symbol else {}
        return self._request("/api/v3/ticker/24hr", params or None)

    def get_price(self, symbol: str = None) -> dict | list:
        params = {"symbol": symbol} if symbol else {}
        return self._request("/api/v3/ticker/price", params or None)


# Использование
client = ProxyHatBinanceClient(username="user", password="pass", country="US")

# Ротация IP — каждый запрос идёт через новый IP
for sym in ["BTCUSDT", "ETHUSDT", "BNBUSDT"]:
    klines = client.get_klines(sym, interval="5m", limit=100)
    logger.info("%s: got %d candles", sym, len(klines))

3. Python httpx: асинхронная ротация с контролем параллелизма

Для высокопроизводительного сбора данных используйте httpx с asyncio и семафором для ограничения параллелизма:

import httpx
import asyncio
import logging

logging.basicConfig(level=logging.INFO, format="%(asctime)s %(levelname)s %(message)s")
logger = logging.getLogger("async_binance")

GATE = "gate.proxyhat.com:8080"
BASE = "https://api.binance.com"
MAX_CONCURRENT = 10

async def fetch_klines(client: httpx.AsyncClient, symbol: str, interval: str, limit: int):
    """Получение klines через асинхронный клиент с прокси."""
    params = {"symbol": symbol, "interval": interval, "limit": limit}
    try:
        resp = await client.get(f"{BASE}/api/v3/klines", params=params, timeout=15)
        weight = resp.headers.get("x-mbx-used-weight-1m", "?")
        logger.info("%s: %d candles, weight=%s", symbol, len(resp.json()), weight)
        return resp.json()
    except httpx.HTTPStatusError as e:
        if e.response.status_code == 429:
            retry_after = int(e.response.headers.get("retry-after", 10))
            logger.warning("%s: 429, waiting %ds", symbol, retry_after)
            await asyncio.sleep(retry_after)
        raise

async def main():
    symbols = ["BTCUSDT", "ETHUSDT", "BNBUSDT", "SOLUSDT", "XRPUSDT"]
    proxy_url = "http://user-country-US:pass@gate.proxyhat.com:8080"

    semaphore = asyncio.Semaphore(MAX_CONCURRENT)

    async with httpx.AsyncClient(
        proxy=proxy_url,
        limits=httpx.Limits(max_connections=20, max_keepalive_connections=10),
    ) as client:
        async def bounded_fetch(sym):
            async with semaphore:
                return await fetch_klines(client, sym, "1m", 100)

        results = await asyncio.gather(
            *[bounded_fetch(s) for s in symbols], return_exceptions=True
        )

    for sym, res in zip(symbols, results):
        if isinstance(res, Exception):
            logger.error("%s failed: %s", sym, res)
        else:
            logger.info("%s: %d data points", sym, len(res))

asyncio.run(main())

4. Python: sticky-сессия для бэкфилла исторических klines

Для пагинации исторических данных используйте sticky-сессию (-session-abc123), чтобы все запросы шли через один IP. Это позволяет использовать непрерывный весовой бюджет одного IP и избегать рассинхронизации:

import requests
import time
import logging

logging.basicConfig(level=logging.INFO, format="%(asctime)s %(levelname)s %(message)s")
logger = logging.getLogger("klines_backfill")

def backfill_klines(symbol: str, interval: str, start_time: int, end_time: int):
    """Бэкфилл исторических свечей через sticky-сессию ProxyHat.

    Args:
        symbol: Торговая пара, напр. 'BTCUSDT'
        interval: Интервал свечей, напр. '1m', '1h', '1d'
        start_time: Unix timestamp (ms) начала периода
        end_time: Unix timestamp (ms) конца периода
    """
    GATE = "gate.proxyhat.com:8080"
    SESSION_ID = f"backfill-{symbol}-{interval}"
    proxy_url = f"http://user-session-{SESSION_ID}:pass@{GATE}"
    proxies = {"http": proxy_url, "https": proxy_url}

    all_klines = []
    current_start = start_time
    max_per_request = 1000  # Binance максимум для klines
    used_weight = 0

    session = requests.Session()

    while current_start < end_time:
        # Weight-aware throttle
        if used_weight >= 5500:
            logger.info("Weight %d, cooling down 60s", used_weight)
            time.sleep(60)
            used_weight = 0

        params = {
            "symbol": symbol,
            "interval": interval,
            "startTime": current_start,
            "endTime": end_time,
            "limit": max_per_request,
        }

        for attempt in range(5):
            try:
                resp = session.get(
                    "https://api.binance.com/api/v3/klines",
                    params=params, proxies=proxies, timeout=15
                )

                weight_h = resp.headers.get("X-MBX-USED-WEIGHT-1M")
                if weight_h:
                    used_weight = int(weight_h)

                if resp.status_code == 429:
                    wait = int(resp.headers.get("Retry-After", 10))
                    logger.warning("429, waiting %ds", wait)
                    time.sleep(wait)
                    continue

                resp.raise_for_status()
                batch = resp.json()

                if not batch:
                    logger.info("No more data, stopping")
                    return all_klines

                all_klines.extend(batch)
                # Сдвигаем startTime на время последней свечи + 1ms
                current_start = batch[-1][6] + 1  # index 6 = closeTime
                logger.info("Got %d candles (total %d), weight=%s, next=%d",
                            len(batch), len(all_klines), weight_h, current_start)
                break

            except requests.RequestException as e:
                wait = 2 ** attempt
                logger.warning("Retry %d: %s, waiting %ds", attempt + 1, e, wait)
                time.sleep(wait)
        else:
            raise RuntimeError(f"Failed after 5 retries at startTime={current_start}")

        # Небольшая задержка между запросами
        time.sleep(0.1)

    return all_klines

# Бэкфилл BTCUSDT за 1 час (1-минутные свечи = 60 свечей)
data = backfill_klines("BTCUSDT", "1m", 1700000000000, 1700003600000)
logger.info("Total candles collected: %d", len(data))

5. Node.js axios: ротация IP с retry и weight-tracking

Для JavaScript/TypeScript-разработчиков — эквивалент на axios с прокси-агентом:

const axios = require('axios');
const HttpsProxyAgent = require('https-proxy-agent').HttpsProxyAgent;
const logging = require('logging').default;

const logger = logging.getLogger('binance_node');
const GATE = 'gate.proxyhat.com:8080';
const BASE = 'https://api.binance.com';

/**
 * Клиент для скрейпинга Binance через ротацию IP ProxyHat.
 */
class BinanceScraper {
  constructor(username, password, country = null) {
    this.username = username;
    this.password = password;
    this.country = country;
    this.usedWeight = 0;
    this.maxWeightPerMin = 5500;
  }

  getProxyUrl(sessionId = null) {
    let user = this.username;
    if (this.country) user += `-country-${this.country}`;
    if (sessionId) user += `-session-${sessionId}`;
    return `http://${user}:${this.password}@${GATE}`;
  }

  async request(path, params = {}, sessionId = null) {
    const proxyUrl = this.getProxyUrl(sessionId);
    const agent = new HttpsProxyAgent(proxyUrl);
    const url = `${BASE}${path}`;

    for (let attempt = 0; attempt < 5; attempt++) {
      if (this.usedWeight >= this.maxWeightPerMin) {
        logger.info(`Weight ${this.usedWeight}, cooling down 60s`);
        await new Promise(r => setTimeout(r, 60000));
        this.usedWeight = 0;
      }

      try {
        const resp = await axios.get(url, {
          params,
          httpsAgent: agent,
          timeout: 15000,
        });

        const weight = resp.headers['x-mbx-used-weight-1m'];
        if (weight) this.usedWeight = parseInt(weight);

        return resp.data;
      } catch (err) {
        if (err.response) {
          const status = err.response.status;
          if (status === 429) {
            const retryAfter = parseInt(err.response.headers['retry-after'] || '10');
            logger.warn(`429 rate limited, waiting ${retryAfter}s`);
            await new Promise(r => setTimeout(r, retryAfter * 1000));
            continue;
          }
          if (status === 418) {
            logger.error('418 IP banned, waiting 120s');
            await new Promise(r => setTimeout(r, 120000));
            continue;
          }
        }
        const wait = Math.pow(2, attempt) * 1000;
        logger.warn(`Attempt ${attempt + 1} failed: ${err.message}, retry in ${wait}ms`);
        await new Promise(r => setTimeout(r, wait));
      }
    }
    throw new Error(`Failed after 5 attempts: ${path}`);
  }

  async getKlines(symbol, interval = '1m', limit = 100) {
    return this.request('/api/v3/klines', { symbol, interval, limit });
  }

  async getDepth(symbol, limit = 100) {
    return this.request('/api/v3/depth', { symbol, limit });
  }

  async getTicker24hr(symbol = null) {
    const params = symbol ? { symbol } : {};
    return this.request('/api/v3/ticker/24hr', params);
  }
}

// Использование
(async () => {
  const scraper = new BinanceScraper('user', 'pass', 'US');
  const symbols = ['BTCUSDT', 'ETHUSDT', 'BNBUSDT'];

  for (const sym of symbols) {
    const klines = await scraper.getKlines(sym, '5m', 100);
    logger.info(`${sym}: ${klines.length} candles`);
  }
})();

6. SOCKS5 для высокочастотного поллинга depth

Для поллинга книги ордеров с высокой частотой SOCKS5-прокси может обеспечить меньшую задержку:

import requests
import time
import logging

logging.basicConfig(level=logging.INFO, format="%(asctime)s %(levelname)s %(message)s")
logger = logging.getLogger("depth_poller")

def poll_depth(symbol: str, limit: int = 100, interval_sec: float = 0.5):
    """Поллинг книги ордеров через SOCKS5 ProxyHat с ротацией IP."""
    socks_proxy = "socks5://user-country-US:pass@gate.proxyhat.com:1080"
    proxies = {"http": socks_proxy, "https": socks_proxy}
    session = requests.Session()
    used_weight = 0

    while True:
        if used_weight >= 5500:
            logger.info("Weight %d, cooling down", used_weight)
            time.sleep(60)
            used_weight = 0

        try:
            resp = session.get(
                "https://api.binance.com/api/v3/depth",
                params={"symbol": symbol, "limit": limit},
                proxies=proxies, timeout=10
            )
            weight_h = resp.headers.get("X-MBX-USED-WEIGHT-1M")
            if weight_h:
                used_weight = int(weight_h)

            if resp.status_code == 429:
                wait = int(resp.headers.get("Retry-After", 10))
                logger.warning("429, waiting %ds", wait)
                time.sleep(wait)
                continue

            data = resp.json()
            bids_count = len(data.get("bids", []))
            asks_count = len(data.get("asks", []))
            logger.info("%s depth: %d bids / %d asks, weight=%s",
                        symbol, bids_count, asks_count, weight_h)

        except Exception as e:
            logger.error("Error: %s", e)

        time.sleep(interval_sec)

# poll_depth("BTCUSDT", limit=100, interval_sec=0.5)

Когда WebSocket лучше REST-поллинга

Binance предоставляет публичные WebSocket-стримы на wss://stream.binance.com:9443/ws для данных в реальном времени. Для непрерывного мониторинга книги ордеров или свечей WebSocket эффективнее REST-поллинга:

  • REST-поллинг — подходит для периодического сбора, бэкфилла истории, snapshot-ов. Каждый запрос тратит вес.
  • WebSocket — одно соединение, push-обновления без расхода веса. Идеально для real-time orderbook и kline-streams.

Используйте REST через прокси для исторических данных и snapshot-ов, а WebSocket — для live-streaming. Прокси ProxyHat поддерживают как HTTP, так и SOCKS5 для обоих сценариев.

Распространённые ошибки и edge-cases

  • Игнорирование заголовка веса — всегда читайте X-MBX-USED-WEIGHT-1M и throttling'те до исчерпания лимита, а не после.
  • Отсутствие retry-логики для 429/418 — без обработки Retry-After вы получите бан 418.
  • Слишком высокий параллелизм — 100+ одновременных запросов с одного IP исчерпают вес за секунды. Ограничивайте concurrency семафором.
  • Геоблок 451 — если целевой эндпоинт возвращает 451, используйте -country-US или другую страну в имени пользователя ProxyHat.
  • Смешивание сессий — для пагинации klines используйте одну sticky-сессию, чтобы вес накапливался на одном IP предсказуемо.

Настройка ProxyHat и внутренние ссылки

ProxyHat предоставляет резидентные, мобильные и дата-центр прокси с гибким геотаргетингом. Для скрейпинга Binance API рекомендуем резидентные прокси — они выглядят как реальные пользовательские IP и снижают риск блокировок. Конфигурация проста:

  • HTTP-прокси: http://USERNAME:PASSWORD@gate.proxyhat.com:8080
  • SOCKS5-прокси: socks5://USERNAME:PASSWORD@gate.proxyhat.com:1080
  • Геотаргетинг: добавьте -country-US или -country-DE-city-berlin к имени пользователя
  • Sticky-сессия: добавьте -session-abc123 для закрепления IP

Подробнее о тарифах — на странице цен ProxyHat. Доступные локации — на странице локаций прокси. Use-case для веб-скрейпинга — веб-скрейпинг через ProxyHat, для SERP-трекинга — SERP-трекинг. Полная техническая документация — на docs.proxyhat.com.

Ключевые выводы

  • Вес — ключевой ресурс: Binance даёт ~6000 веса/мин на IP. Отслеживайте X-MBX-USED-WEIGHT-1M и throttling'те до лимита.
  • Ротация IP распределяет вес: N IP-адресов = N × 6000 веса/мин. Резидентные прокси ProxyHat через gate.proxyhat.com:8080 — простое решение.
  • Sticky-сессии для пагинации: используйте -session-ID для бэкфилла klines, чтобы вес накапливался предсказуемо.
  • Геотаргетинг решает 451: -country-US обходит геоблок Binance.com в США.
  • WebSocket для real-time: для live-orderbook и kline-streams используйте wss://stream.binance.com, а не REST-поллинг.
  • Retry + backoff обязателен: обработка 429 с Retry-After и экспоненциальная задержка предотвращают бан 418.

FAQ

Что такое скрейпинг Binance REST API через прокси?

Это сбор публичных рыночных данных (свечи, книга ордеров, тикеры) с эндпоинтов api.binance.com/api/v3/ через прокси-серверы, которые распределяют запросы по нескольким IP-адресам. Это позволяет обойти весовое ограничение ~6000 единиц в минуту на один IP и собирать данные в большем масштабе.

Зачем нужны прокси для скрейпинга Binance API?

Binance применяет весовые лимиты на IP. С одного адреса вы ограничены ~6000 веса/мин, а за превышение следует HTTP 429, а затем бан 418. Ротация резидентных прокси через gate.proxyhat.com:8080 распределяет вес по пулу IP, каждый из которых получает свой бюджет. Также геотаргетинг -country-US решает проблему HTTP 451 при доступе из США.

Какой тип прокси лучше для скрейпинга Binance?

Резидентные прокси оптимальны — они используют IP реальных интернет-провайдеров и реже блокируются антибот-системами. Дата-центр прокси быстрее, но чаще распознаются. Для бэкфилла истории с пагинацией используйте sticky-сессии (-session-ID), а для параллельного сбора по множеству символов — ротацию IP без сессии.

Как избежать блокировок при скрейпинге Binance API?

Отслеживайте заголовок X-MBX-USED-WEIGHT-1M и делайте паузу до достижения лимита 6000. Обрабатывайте HTTP 429 с заголовком Retry-After и применяйте экспоненциальную задержку. Ограничивайте параллелизм семафором (10–20 одновременных запросов). Не игнорируйте 429 — многократные нарушения приводят к бану 418 на срок от 2 минут до нескольких дней.

Когда использовать WebSocket вместо REST?

WebSocket (wss://stream.binance.com:9443/ws) эффективнее для непрерывного мониторинга real-time данных — orderbook updates, kline streams. Одно соединение получает push-обновления без расхода веса. REST через прокси оптимален для бэкфилфа истории, snapshot-ов и периодического сбора.

Часто задаваемые вопросы

Что такое скрейпинг Binance REST API через прокси?

Это сбор публичных рыночных данных (свечи, книга ордеров, тикеры) с эндпоинтов api.binance.com/api/v3/ через прокси-серверы, которые распределяют запросы по нескольким IP-адресам. Это позволяет обойти весовое ограничение ~6000 единиц в минуту на один IP и собирать данные в большем масштабе.

Зачем нужны прокси для скрейпинга Binance API?

Binance применяет весовые лимиты на IP. С одного адреса вы ограничены ~6000 веса/мин, а за превышение следует HTTP 429, а затем бан 418. Ротация резидентных прокси через gate.proxyhat.com:8080 распределяет вес по пулу IP, каждый из которых получает свой бюджет. Также геотаргетинг -country-US решает проблему HTTP 451 при доступе из США.

Какой тип прокси лучше для скрейпинга Binance?

Резидентные прокси оптимальны — они используют IP реальных интернет-провайдеров и реже блокируются антибот-системами. Дата-центр прокси быстрее, но чаще распознаются. Для бэкфилла истории с пагинацией используйте sticky-сессии (-session-ID), а для параллельного сбора по множеству символов — ротацию IP без сессии.

Как избежать блокировок при скрейпинге Binance API?

Отслеживайте заголовок X-MBX-USED-WEIGHT-1M и делайте паузу до достижения лимита 6000. Обрабатывайте HTTP 429 с заголовком Retry-After и применяйте экспоненциальную задержку. Ограничивайте параллелизм семафором (10–20 одновременных запросов). Не игнорируйте 429 — многократные нарушения приводят к бану 418 на срок от 2 минут до нескольких дней.

Когда использовать WebSocket вместо REST для Binance?

WebSocket (wss://stream.binance.com:9443/ws) эффективнее для непрерывного мониторинга real-time данных — orderbook updates, kline streams. Одно соединение получает push-обновления без расхода веса. REST через прокси оптимален для бэкфилла истории, snapshot-ов и периодического сбора.

Готовы начать?

Резидентные, ISP и мобильные прокси в 148+ странах. Создайте бесплатный аккаунт.

Создать бесплатный аккаунт
← Вернуться в Блог