كيفية استخراج بيانات Bybit V5 Market API باستخدام بروكسيات دوارة

دليل مطورين شامل لاستخراج بيانات السوق من Bybit V5 API مع بروكسيات دوارة: نقاط النهاية، حدود المعدل، القيود الجغرافية، وأمثلة كود قابلة للتشغيل في Node.js وPython.

How to Scrape the Bybit V5 Market API with Rotating Proxies
En este artículo

إذا كنت تطوّر بوت تداول أو تجمع بيانات سوق التشفير، فمن المرجح أنك واجهت مشكلة حظر IP عند محاولة استخراج بيانات من Bybit V5 Market API. منصة Bybit تفرض قيودًا صارمة على المعدل وتقييدات جغرافية تجعل جمع البيانات على نطاق واسع أمرًا صعبًا دون بنية بروكسي مناسبة. في هذا الدليل، نشرح كيفية استخراج بيانات Bybit V5 Market API باستخدام بروكسيات دوارة عبر نقاط نهاية محددة، مع أمثلة كود قابلة للتشغيل في Node.js وPython باستخدام ProxyHat.

تنبيه قانوني: هذه المقالة تغطي نقاط نهاية البيانات العامة فقط (orderbook, tickers, kline, recent-trading). تأكد دائمًا من مراجعة شروط خدمة Bybit و سياسة الخصوصية قبل جمع أي بيانات. لا تستخدم نقاط نهاية المصادقة أو بيانات المستخدم دون إذن صريح.

نظرة عامة على Bybit V5 Market API ونقاط النهاية

تستضيف Bybit واجهة V5 الموحدة على api.bybit.com. نقاط نهاية البيانات العامة تحت مسار /v5/market/ لا تتطلب مصادقة وتُرجع بيانات السوق في الوقت الفعلي أو شبه الفعلي. إليك النقاط الأربع الرئيسية التي نهتم بها:

نقطة النهاية الطريقة الغرض المعاملات الأساسية
/v5/market/orderbook GET لقطة دفتر الطلبات category, symbol, limit
/v5/market/tickers GET أسعار/حجم جميع الرموز أو رمز واحد category, symbol (اختياري)
/v5/market/kline GET بيانات الشموع اليابانية (OHLCV) category, symbol, interval, start, end
/v5/market/recent-trade GET أحدث الصفقات المنفذة category, symbol, limit

المعامل category هو محوري في V5 — يقبل القيم spot (الفوري), linear (العقود الخطية), inverse (العقود العكسية), و option (الخيارات). لكل فئة مساحة أسماء رموز خاصة بها، لذا BTCUSDT في spot يختلف عن BTCUSDT في linear.

مغلف الاستجابة: retCode و retMsg

تُرجع جميع نقاط نهاية V5 JSON بمغلف موحد:

{
  "retCode": 0,
  "retMsg": "OK",
  "result": {
    "category": "spot",
    "symbol": "BTCUSDT",
    "list": [...]
  },
  "time": 1700000000000
}

عندما يكون retCode = 0، الطلب ناجح. أي قيمة غير صفرية تشير إلى خطأ — راجع توثيق أخطاء Bybit V5 لقائمة الرموز. القيم الشائعة تشمل 10001 (معامل غير صالح) و 10010 (تجاوز حد المعدل). يجب على الكود الخاص بك التحقق من retCode قبل معالجة result.

حدود المعدل وحظر IP في Bybit

تطبق Bybit حدود معدل لكل IP على كل نقطة نهاية. وفقًا لـ توثيق حدود المعدل في Bybit V5، فإن نقطة نهاية دفتر الطلبات /v5/market/orderbook لديها حد أقصى حوالي 200 طلب في الثانية لكل IP، لكن هذا الرقم يختلف حسب الفئة. نقاط نهاية kline و tickers لها حدود منخفضة بشكل عام.

عندما تتجاوز الحد، يستجيب الخادم بـ HTTP 403 Forbidden مع retMsg يشير إلى تجاوز حد المعدل. الأسوأ من ذلك، Bybit تفرض نافذة حظر تبلغ تقريبًا 10 دقائق على IPs التي تستمر في تجاوز الحدود. خلال هذه النافذة، يتم رفض جميع الطلبات من ذلك IP — وليس فقط نقطة النهاية التي تم تجاوزها.

هذا يعني أن اندفاعًا قصيرًا على api.bybit.com/v5/market/orderbook لجمع دفاتر طلبات 50 رمزًا يمكن أن يوقف مجموعة البيانات بأكملها لمدة 10 دقائق. الحل هو توزيع الطلبات عبر عناوين IP متعددة باستخدام بروكسيات دوارة.

القيود الجغرافية وحظر CloudFront

Bybit تقيد الوصول من مناطق معينة، بما في ذلك الولايات المتحدة والمملكة المتحدة ودول أخرى. الطلبات من IPs في هذه المناطق تتلقى HTTP 403 مع رسالة حظر CloudFront أو صفحة خطأ جغرافية. هذا يمثل مشكلة للمطورين الذين يعملون من هذه المناطق ويحتاجون إلى الوصول إلى بيانات السوق العامة.

البروكسيات السكنية تحل هذه المشكلة عن طريق توجيه حركة المرور عبر IPs سكنية حقيقية في دول مسموحة. مع ProxyHat، يمكنك تحديد الدولة في اسم المستخدم باستخدام تنسيق user-country-XX لضمان أن الطلبات تخرج من IP في دولة مسموحة مثل اليابان أو سنغافورة.

إعداد ProxyHat: البروكسي الخام مقابل SDK

ProxyHat يوفر بوابة HTTP على gate.proxyhat.com:8080 و SOCKS5 على gate.proxyhat.com:1080. يمكنك استخدام البروكسي الخام مباشرة في أي عميل HTTP، أو استخدام ProxyHat SDK للإدارة المتقدمة للجلسات. إليك مقارنة سريعة:

النهج المزايا العيوب
البروكسي الخام (URL) بسيط، يعمل مع أي مكتبة HTTP إدارة الجلسات يدوية
ProxyHat SDK تدوير تلقائي، جلسات لاصقة، إعادة المحاولة يتطلب تثبيت حزمة

مثال 1: طلب دفتر الطلبات باستخدام curl مع بروكسي خام

# بروكسي HTTP خام مع تحديد الدولة (اليابان)
curl -x http://user-country-JP:YOUR_PASSWORD@gate.proxyhat.com:8080 \
  "https://api.bybit.com/v5/market/orderbook?category=spot&symbol=BTCUSDT&limit=50"
# بروكسي SOCKS5 مع جلسة لاصقة
curl -x socks5://user-country-JP-session-abc123:YOUR_PASSWORD@gate.proxyhat.com:1080 \
  "https://api.bybit.com/v5/market/orderbook?category=linear&symbol=ETHUSDT&limit=100"

مثال 2: Node.js (axios) — تدوير IP عبر قائمة رموز باستخدام البروكسي الخام

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

const PROXY_USER = 'user';
const PROXY_PASS = 'YOUR_PASSWORD';
const PROXY_HOST = 'gate.proxyhat.com';
const PROXY_PORT = 8080;

const symbols = ['BTCUSDT', 'ETHUSDT', 'SOLUSDT', 'XRPUSDT', 'DOGEUSDT'];
const categories = ['spot', 'linear'];

async function fetchOrderbook(symbol, category, sessionTag) {
  const proxyUrl = `http://${PROXY_USER}-country-JP-session-${sessionTag}:${PROXY_PASS}@${PROXY_HOST}:${PROXY_PORT}`;
  const agent = new HttpsProxyAgent(proxyUrl);

  try {
    const resp = await axios.get('https://api.bybit.com/v5/market/orderbook', {
      params: { category, symbol, limit: 50 },
      httpsAgent: agent,
      timeout: 10000,
    });

    if (resp.data.retCode !== 0) {
      throw new Error(`Bybit retCode ${resp.data.retCode}: ${resp.data.retMsg}`);
    }

    return { symbol, category, bids: resp.data.result.bids, asks: resp.data.result.asks };
  } catch (err) {
    console.error(`[FAIL] ${category}/${symbol}: ${err.message}`);
    return null;
  }
}

async function main() {
  const tasks = symbols.map((sym, i) =>
    fetchOrderbook(sym, 'spot', `sess-${i}-${Date.now()}`)
  );
  const results = await Promise.allSettled(tasks);
  const ok = results.filter(r => r.status === 'fulfilled' && r.value !== null);
  console.log(`نجاح: ${ok.length}/${symbols.length}`);
}

main();

مثال 3: Node.js (axios) — نفس العملية باستخدام ProxyHat SDK

const axios = require('axios');
const { ProxyHatClient } = require('@proxyhat/sdk');

const client = new ProxyHatClient({
  username: 'user',
  password: 'YOUR_PASSWORD',
  country: 'JP',
  rotation: 'per-request',
  maxRetries: 3,
  backoffMs: 2000,
});

const symbols = ['BTCUSDT', 'ETHUSDT', 'SOLUSDT', 'XRPUSDT', 'DOGEUSDT'];

async function fetchOrderbookSDK(symbol, category) {
  const proxyAgent = await client.getAgent(); // IP جديد لكل طلب

  try {
    const resp = await axios.get('https://api.bybit.com/v5/market/orderbook', {
      params: { category, symbol, limit: 50 },
      httpsAgent: proxyAgent,
      timeout: 10000,
    });

    if (resp.data.retCode !== 0) {
      throw new Error(`retCode ${resp.data.retCode}: ${resp.data.retMsg}`);
    }
    return resp.data.result;
  } catch (err) {
    // SDK يتعامل مع إعادة المحاولة تلقائيًا مع IP جديد
    console.error(`[FAIL] ${category}/${symbol}: ${err.message}`);
    return null;
  }
}

async function main() {
  const results = await Promise.allSettled(
    symbols.map(s => fetchOrderbookSDK(s, 'spot'))
  );
  console.log(`اكتمل: ${results.filter(r => r.status === 'fulfilled').length}/${symbols.length}`);
}

main();

مثال 4: Python — جمع بيانات kline مع جلسات لاصقة وترقيم الصفحات

import requests
import time
from urllib.parse import urlencode

PROXY_USER = 'user'
PROXY_PASS = 'YOUR_PASSWORD'
PROXY_HOST = 'gate.proxyhat.com'
PROXY_PORT = 8080
BASE_URL = 'https://api.bybit.com/v5/market/kline'

def get_proxy(session_id, country='JP'):
    """بناء URL بروكسي مع جلسة لاصقة للترقيم."""
    username = f'{PROXY_USER}-country-{country}-session-{session_id}'
    proxy_url = f'http://{username}:{PROXY_PASS}@{PROXY_HOST}:{PROXY_PORT}'
    return {'http': proxy_url, 'https': proxy_url}

def fetch_kline_page(symbol, category, interval, start, end, session_id):
    """جلب صفحة واحدة من بيانات kline مع بروكسي لاصق."""
    params = {
        'category': category,
        'symbol': symbol,
        'interval': interval,  # 1, 5, 15, 30, 60, 240, D, W, M
        'start': start,
        'end': end,
        'limit': 200,  # الحد الأقصى للصفحة
    }

    proxies = get_proxy(session_id)

    for attempt in range(3):
        try:
            resp = requests.get(BASE_URL, params=params, proxies=proxies, timeout=10)
            if resp.status_code == 403:
                print(f'403 محظور، إعادة المحاولة {attempt + 1}/3')
                time.sleep(2 ** attempt)
                continue

            data = resp.json()
            if data['retCode'] != 0:
                raise Exception(f"retCode {data['retCode']}: {data['retMsg']}")

            return data['result']['list']
        except requests.RequestException as e:
            print(f'خطأ شبكة: {e}')
            time.sleep(2 ** attempt)

    return None

def fetch_all_klines(symbol, category, interval, start_ms, end_ms):
    """جمع كل بيانات kline عبر ترقيم الصفحات بنفس الجلسة اللاصقة."""
    session_id = f'kline-{symbol}-{int(time.time())}'
    all_candles = []
    cursor = start_ms

    while cursor < end_ms:
        page_end = min(cursor + 200 * 60 * 1000 * int(interval), end_ms)
        candles = fetch_kline_page(symbol, category, interval, cursor, page_end, session_id)

        if not candles:
            break

        all_candles.extend(candles)
        # التقدم إلى آخر شمعة في الصفحة
        last_ts = int(candles[-1][0])
        cursor = last_ts + 1
        time.sleep(0.5)  # احترام حد المعدل

    return all_candles

# مثال: جمع بيانات BTCUSDT spot لمدة ساعة
candles = fetch_all_klines('BTCUSDT', 'spot', '1', 1700000000000, 1700003600000)
print(f'تم جمع {len(candles)} شمعة')

مثال 5: Python — ProxyHat SDK مع ميزانية معدل لكل نقطة نهاية

import time
import logging
from proxyhat import ProxyHatClient
import requests

logging.basicConfig(level=logging.INFO, format='%(asctime)s %(levelname)s %(message)s')

class BybitMarketScraper:
    def __init__(self, country='JP'):
        self.client = ProxyHatClient(
            username='user',
            password='YOUR_PASSWORD',
            country=country,
            rotation='per-request',
            max_retries=3,
            backoff_ms=2000,
        )
        # ميزانية المعدل لكل نقطة نهاية (طلب/ثانية)
        self.rate_budget = {
            'orderbook': 50,   # حد آمن تحت 200/ثانية
            'tickers': 10,
            'kline': 5,
            'recent-trade': 20,
        }
        self.last_request = {ep: 0 for ep in self.rate_budget}

    def _respect_rate(self, endpoint):
        min_interval = 1.0 / self.rate_budget[endpoint]
        elapsed = time.time() - self.last_request[endpoint]
        if elapsed < min_interval:
            time.sleep(min_interval - elapsed)
        self.last_request[endpoint] = time.time()

    def fetch(self, endpoint, params):
        self._respect_rate(endpoint)
        proxy = self.client.get_proxy_dict()  # {'http': ..., 'https': ...}
        url = f'https://api.bybit.com/v5/market/{endpoint}'

        for attempt in range(3):
            try:
                resp = requests.get(url, params=params, proxies=proxy, timeout=10)
                if resp.status_code == 403:
                    logging.warning(f'403 من Bybit، تدوير IP وإعادة المحاولة')
                    proxy = self.client.get_proxy_dict(force_new_ip=True)
                    time.sleep(2 ** attempt)
                    continue

                data = resp.json()
                if data['retCode'] != 0:
                    logging.error(f'retCode {data["retCode"]}: {data["retMsg"]}')
                    if data['retCode'] == 10010:  # تجاوز حد المعدل
                        time.sleep(60)  # انتظار طويل
                    return None
                return data['result']
            except Exception as e:
                logging.error(f'استثناء: {e}')
                time.sleep(2 ** attempt)
        return None

# الاستخدام
scraper = BybitMarketScraper(country='JP')
result = scraper.fetch('orderbook', {'category': 'spot', 'symbol': 'BTCUSDT', 'limit': 50})
if result:
    print(f'أفضل سعر شراء: {result["bids"][0] if result["bids"] else "N/A"}')

مثال 6: Python — recent-trade مع بروكسي SOCKS5 خام

import requests

# استخدام SOCKS5 على المنفذ 1080
proxy_url = 'socks5://user-country-SG-session-trades-001:YOUR_PASSWORD@gate.proxyhat.com:1080'
proxies = {'http': proxy_url, 'https': proxy_url}

resp = requests.get(
    'https://api.bybit.com/v5/market/recent-trade',
    params={'category': 'linear', 'symbol': 'BTCUSDT', 'limit': 50},
    proxies=proxies,
    timeout=10,
)

data = resp.json()
if data['retCode'] == 0:
    trades = data['result']['list']
    print(f'تم استرجاع {len(trades)} صفقة')
    for t in trades[:5]:
        print(f'  السعر: {t["price"]} | الحجم: {t["size"]} | الوقت: {t["time"]}')
else:
    print(f'خطأ: {data["retMsg"]}')

REST مقابل WebSocket: لقطات مقابل بث مباشر

للبيانات اللحظية، توفر Bybit قناة WebSocket عامة orderbook.50.{symbol} و orderbook.100.{symbol} التي تدفع تحديثات دفتر الطلبات في الوقت الفعلي. هذا أكثر كفاءة من استطلاع REST /v5/market/orderbook بشكل متكرر.

المعيار REST /v5/market/orderbook WebSocket orderbook.50
زمن الوصول ~50-100ms لكل طلب ~10-30ms للتحديثات
استهلاك النطاق عالي (طلب كامل لكل تحديث) منخفض (تحديثات تدريجية)
حد المعدل ~200 طلب/ثانية لكل IP لا يوجد حد معدل REST
الحاجة لبروكسي نعم للتدوير نعم للاتصال الأولي فقط

للحصول على تفاصيل WebSocket، راجع توثيق WebSocket العام في Bybit V5. القناة العامة متاحة على wss://stream.bybit.com/v5/public/spot للفوري و wss://stream.bybit.com/v5/public/linear للعقود الخطية.

أخطاء شديدة وحالات حافة

1. تجاهل retCode والاعتماد على HTTP 200 فقط

Bybit قد تُرجع HTTP 200 مع retCode غير صفر. إذا تحقق الكود فقط من resp.ok، فسيعالج بيانات خطأ كأنها بيانات صحيحة.

2. عدم احترام نافذة الحظر البالغة 10 دقائق

عند تلقي 403، بعض المطورين يعيدون المحاولة فورًا بنفس IP — وهذا يطيل فترة الحظر. الصحيح هو التدوير إلى IP جديد والانتظار على الأقل 60 ثانية قبل إعادة المحاولة.

3. استخدام دفتر طلبات بعمق 200 لكل رمز

عمق limit=200 يستهلك مزيدًا من النطاق ويضغط على حد المعدل. معظم استراتيجيات التداول تحتاج فقط limit=50 أو حتى limit=10.

4. خلط الفئات

BTCUSDT في spot ليس نفس BTCUSDT في linear. تأكد دائمًا من تمرير category الصحيحة.

إعداد ProxyHat والروابط الداخلية

للبدء مع ProxyHat، سجل الدخول إلى dashboard.proxyhat.com للحصول على بيانات اعتمادك. تحقق من صفحة الأسعار لخطط البروكسي السكنية والمتنقلة. للمزيد حول حالات استخدام استخراج البيانات، راجع صفحة استخراج الويب و تتبع نتائج البحث. لدعم الدول المدعومة، راجع صفحة المواقع. للتوثيق الفني الكامل، راجع docs.proxyhat.com.

النقاط الرئيسية

  • تحقق من retCode دائمًا: HTTP 200 لا يعني النجاح في Bybit V5 — تحقق من retCode === 0.
  • احترم حدود المعدل: /v5/market/orderbook يسمح بحوالي 200 طلب/ثانية لكل IP، لكن الحظر يستمر ~10 دقائق عند التجاوز.
  • استخدم البروكسيات السكنية: تجاوز القيود الجغرافية باستخدام -country-JP أو -country-SG في اسم المستخدم.
  • الجلسات اللاصقة للترقيم: استخدم -session-abc123 لضمان نفس IP عبر صفحات kline متعددة.
  • ميزانية المعدل لكل نقطة نهاية: لا تتعامل مع جميع النقاط بنفس السرعة — kline أبطأ من orderbook.
  • فكر في WebSocket: للبيانات اللحظية، orderbook.50 أكثر كفاءة من استطلاع REST.

للحصول على أفضل النتائج، ابدأ بمعدل منخفض (10 طلب/ثانية لكل IP) وارفعه تدريجيًا مع مراقبة نسبة 403. استخدم ProxyHat SDK للتدوير التلقائي وإعادة المحاولة بدلاً من بناء منطق مخصص.

Preguntas frecuentes

ما هو استخراج بيانات Bybit V5 Market API باستخدام بروكسيات دوارة؟

هو عملية جمع بيانات السوق العامة (دفتر الطلبات، الأسعار، الشموع اليابانية، الصفقات) من نقاط نهاية Bybit V5 الموحدة تحت /v5/market/ باستخدام بروكسيات دوارة لتوزيع الطلبات عبر عناوين IP متعددة. هذا يساعد في تجاوز حدود المعدل لكل IP والقيود الجغرافية التي تفرضها Bybit، مع الحفاظ على استمرارية جمع البيانات دون حظر.

لماذا يهم استخراج بيانات Bybit V5 Market API مستخدمي البروكسي؟

لأن Bybit تفرض حدود معدل صارمة لكل IP (حوالي 200 طلب/ثانية لدفتر الطلبات) وتفرض نافذة حظر تبلغ ~10 دقائق عند التجاوز. كما تمنع الوصول من مناطق مثل الولايات المتحدة والمملكة المتحدة. البروكسيات الدوارة — خاصة السكنية مع تحديد الدولة — تتيح توزيع الحمل عبر IPs متعددة وتجاوز القيود الجغرافية، مما يضمن استمرارية جمع البيانات.

أي نوع بروكسي يعمل بشكل أفضل لاستخراج بيانات Bybit V5 Market API؟

البروكسيات السكنية هي الأفضل لأنها تستخدم IPs سكنية حقيقية من مزودي إنترنت فعليين، مما يجعلها تبدو كزيارات شرعية. مع ProxyHat، يمكنك تحديد الدولة في اسم المستخدم (مثل user-country-JP) لضمان الوصول من دولة مسموحة. البروكسيات السكنية تتجاوز حظر CloudFront الجغرافي بشكل أفضل من بروكسيات مراكز البيانات التي قد يتم اكتشافها وحظرها بسرعة.

كيف تتجنب الحظر عند تنفيذ استخراج بيانات Bybit V5 Market API؟

لتجنب الحظر: (1) استخدم بروكسيات دوارة لتوزيع الطلبات عبر IPs متعددة. (2) احترم حدود المعدل لكل نقطة نهاية — استخدم ميزانية منخفضة مثل 50 طلب/ثانية لدفتر الطلبات. (3) عند تلقي 403، بدّل IP فورًا وانتظر 60 ثانية على الأقل. (4) استخدم جلسات لاصقة (-session-abc123) لترقيم صفحات kline. (5) تحقق دائمًا من retCode في الاستجابة وليس فقط HTTP status. (6) فكر في WebSocket للبيانات اللحظية بدلاً من استطلاع REST.

¿Listo para empezar?

Proxies residenciales, ISP y móviles en más de 148 países. Creá una cuenta gratis.

Crear cuenta gratis
← Volver al Blog