دليل المطور الشامل لاستخدام got-scraping في Node.js مع البروكسي السكني

تعرف على كيفية دمج got-scraping في Node.js مع البروكسي السكني من ProxyHat: مولد الترويسات، HTTP/2، تدوير الجلسات، وأنماط إنتاج للكشط على نطاق واسع.

got-scraping in Node.js: A Developer's Guide to Headers, HTTP/2 & Residential Proxies

إذا سبق أن حاولت استخدام got-scraping في Node.js لكشط بيانات الويب على نطاق واسع، فمن المرجح أنك واجهت حظر IP أو تحديات CAPTCHA حتى مع ترويسات تبدو صحيحة. المشكلة ليست في الكود فقط — بل في البصمة التي يتركها عميل HTTP العادي على مستوى TLS وتسلسل الترويسات. في هذا الدليل، نغطي كيف يدمج got-scraping مولد ترويسات متماسك، ودعم HTTP/2، وخيارات البروكسي السكني لبناء حملات كشط موثوقة.

تنبيه قانوني: الكشط يخضع لشروط خدمة المواقع المستهدفة وقوانين مثل CFAA الأمريكية و GDPR الأوروبية. احترم ملف robots.txt وحدود المعدل، وفضّل واجهات API الرسمية عند توفرها. هذا الدليل للأغراض التعليمية ويغطي البيانات العامة فقط.

لماذا تُحجب طلبات got و axios العادية في got-scraping في Node.js

عندما ترسل طلب HTTP باستخدام got أو axios مباشرةً، يبدو الطلب مختلفًا عن طلب المتصفح الحقيقي بعدة طرق:

  • تسلسل الترويسات (Header Order): المتصفحات ترسل الترويسات بترتيب محدد ومتماسك. عملاء HTTP العشوائيون يخلطون هذا الترتيب، مما يكشفهم لأنظمة مكافحة البوت.
  • ترويسات sec-ch-ua: متصفحات Chromium ترسل ترويسات sec-ch-ua التي تصف إصدار المتصفح ونظام التشغيل. غيابها أو عدم تطابقها مع User-Agent يرفع درجة الشك.
  • Accept-Language المنطقي: متصفح حقيقي يرسل Accept-Language متوافقًا مع لغة النظام ومنطقة IP. ترويسة عشوائية مثل en-US من IP روسي تُعتبر إشارة حمراء.
  • بصمة TLS (JA3/JA4): حتى لو بدت الترويسات صحيحة، فإن بصمة TLS لعميل Node.js تختلف عن بصمة Chrome الحقيقي. أنظمة مثل Cloudflare تحلل هذه البصمة.

هذه المشكلة موثقة بشكل واسع. مكتبة got-scraping الرسمية من Apify صُممت خصيصًا لمعالجة هذه الفجوات. كما يشرح توثيق MDN لترويسات HTTP أن المتصفحات الحديثة تتفق على مجموعة ترويسات متماسكة، وأي انحراف يُلاحظ فورًا.

كيف يعمل got-scraping: مولد الترويسات و HTTP/2

الحزمة got-scraping مبنية فوق got وتضيف طبقتين أساسيتين:

مولد الترويسات (Header Generator)

المكتبة تستخدم header-generator من Apify لإنتاج مجموعات ترويسات متماسكة. هذا يعني أن User-Agent و sec-ch-ua و Accept و Accept-Language و sec-ch-ua-platform تتطابق جميعها مع متصفح ونظام تشغيل حقيقي. على سبيل المثال، إذا اختار المولد Chrome 120 على Windows 11، فإن كل ترويسة تعكس ذلك بدقة.

دعم HTTP/2

المتصفحات الحديثة تستخدم HTTP/2 افتراضيًا. got-scraping يدعم HTTP/2 عبر خيار http2: true، مما يجعل بصمة الاتصال أقرب إلى متصفح حقيقي. هذا مهم لأن بعض أنظمة مكافحة البوت تتحقق من إصدار بروتوكول الاتصال.

المكتبةمولد ترويسات متماسكHTTP/2إدارة البروكسيمناسب للكشط
axiosلامحدوديدويضعيف
gotلانعميدويمتوسط
got-scrapingنعم (مدمج)نعمproxyUrlممتاز
puppeteerتلقيني (متصفح حقيقي)نعممدمجممتاز لكن أبطأ

الواجهة البرمجية: got.extend و useHeaderGenerator و headerGeneratorOptions

الاستخدام المثالي لـ got-scraping يعتمد على got.extend() لإنشاء نسخة مخصصة بكل الخيارات الافتراضية. إليك المفاهيم الأساسية:

  • useHeaderGenerator: true — يفعّل مولد الترويسات المدمج.
  • headerGeneratorOptions — يتحكم في المتصفحات والأجهزة وأنظمة التشغيل المُحاكاة: browsers (chrome, firefox, safari)، devices (desktop, mobile)، operatingSystems (windows, macos, linux, android, ios).
  • proxyUrl — يقبل بروكسي HTTP/HTTPS أو SOCKS5 لكل طلب أو على مستوى النسخة.
const { gotScraping } = require('got-scraping');

// إنشاء نسخة مخصصة مع مولد الترويسات
const scraper = gotScraping.extend({
  useHeaderGenerator: true,
  headerGeneratorOptions: {
    browsers: ['chrome', 'firefox'],
    devices: ['desktop'],
    operatingSystems: ['windows', 'macos'],
  },
  http2: true,
  timeout: { request: 30000 },
  retry: { limit: 3 },
});

(async () => {
  const res = await scraper('https://httpbin.org/headers');
  console.log(JSON.parse(res.body));
})();

هذا المثال ينتج ترويسات متماسكة في كل طلب. لاحظ كيف تختار المكتبة مزيجًا منطقيًا (مثل Chrome على Windows) وتولّد كل الترويسات المتوافقة معه.

التوجيه عبر البروكسي السكني مع ProxyHat

حتى مع ترويسات متماسكة و HTTP/2، يبقى عنوان IP هو العامل الحاسم. إذا كانت كل طلباتك تأتي من نفس IP لمركز بيانات، فإن أنظمة مكافحة البوت تحدده بسرعة. هنا يأتي دور البروكسي السكني.

البروكسي السكني يوجّه طلباتك عبر عناوين IP مخصصة لأجهزة منزلية حقيقية (ISP-level)، مما يجعل الطلب يبدو كأنه من مستخدم عادي. هذا مهم لأن:

  • عناوين مراكز البيانات مُصنّفة في قوائم حظر معروفة (ASN databases).
  • عناوين ISP السكنية لها سمات جغرافية حقيقية تتطابق مع Accept-Language.
  • معدل النجاح يمكن أن يرتفع من 50% مع بروكسي مركز بيانات إلى أكثر من 95% مع بروكسي سكني جيد.

مع مواقع ProxyHat، يمكنك استهداف دول ومدن محددة. للكشف عن تتبع نتائج محركات البحث (SERP)، استهدف الدولة المطابقة لسوقك.

البروكسي السكني عبر HTTP (المنفذ 8080)

const { gotScraping } = require('got-scraping');

const scraper = gotScraping.extend({
  useHeaderGenerator: true,
  http2: true,
});

(async () => {
  const res = await scraper({
    url: 'https://httpbin.org/ip',
    proxyUrl: 'http://user-country-US:PASSWORD@gate.proxyhat.com:8080',
  });
  console.log(res.body);
})();

البروكسي السكني عبر SOCKS5 (المنفذ 1080)

const res = await scraper({
  url: 'https://httpbin.org/ip',
  proxyUrl: 'socks5://user-country-DE:PASSWORD@gate.proxyhat.com:1080',
});

استخدم SOCKS5 عندما تحتاج دعمًا أوسع للبروتوكولات أو عندما يفرضه الموقع المستهدف. HTTP يكفي لمعظم حالات الكشط وهو أبسط في الإعداد.

مثال Node.js عملي: تدوير الجلسات مع إعادة المحاولة

الآن لنبني مثالًا كاملًا يدوّر الجلسات السكنية لكل طلب، مع خطافات إعادة المحاولة وتبديل البروكسي عند الفشل:

const { gotScraping } = require('got-scraping');
const crypto = require('crypto');

// بيانات اعتماد ProxyHat
const PROXYHAT_USER = 'YOUR_USERNAME';
const PROXYHAT_PASS = 'YOUR_PASSWORD';

// دالة لتوليد اسم مستخدم لكل طلب مع جلسة فريدة ودولة محددة
function buildProxyUrl(country = 'US') {
  const sessionId = crypto.randomBytes(6).toString('hex');
  const username = `${PROXYHAT_USER}-country-${country}-session-${sessionId}`;
  return `http://${username}:${PROXYHAT_PASS}@gate.proxyhat.com:8080`;
}

// إنشاء نسخة got-scraping مع مولد الترويسات
const scraper = gotScraping.extend({
  useHeaderGenerator: true,
  headerGeneratorOptions: {
    browsers: ['chrome'],
    devices: ['desktop'],
    operatingSystems: ['windows', 'macos'],
  },
  http2: true,
  timeout: { request: 20000 },
  retry: {
    limit: 3,
    statusCodes: [403, 429, 500, 502, 503],
    calculateDelay: ({ computedValue }) => computedValue * 2,
  },
  hooks: {
    beforeRequest: [
      (options) => {
        // تعيين بروكسي جديد لكل طلب
        options.proxyUrl = buildProxyUrl('US');
        return options;
      },
    ],
    beforeRetry: [
      (options, error, retryCount) => {
        // تبديل البروكسي عند إعادة المحاولة
        options.proxyUrl = buildProxyUrl('US');
        console.log(`إعادة المحاولة #${retryCount} — تبديل البروكسي بعد: ${error?.code}`);
      },
    ],
  },
});

(async () => {
  const targets = [
    'https://httpbin.org/ip',
    'https://httpbin.org/headers',
    'https://httpbin.org/user-agent',
  ];

  for (const url of targets) {
    try {
      const res = await scraper(url);
      console.log(`✓ ${url} → ${res.statusCode}`);
      console.log(res.body.substring(0, 200));
    } catch (err) {
      console.error(`✗ ${url} → ${err.message}`);
    }
  }
})();

النقاط الرئيسية في هذا المثال:

  • كل طلب يحصل على جلسة فريدة (session-xxxxxx)، مما يعني IP سكني مختلف.
  • خطاف beforeRequest يضمن تعيين البروكسي قبل كل طلب.
  • خطاف beforeRetry يبدّل البروكسي عند الفشل بدلاً من إعادة استخدام نفس IP المحظور.
  • retry.statusCodes يشمل 403 و 429 — أكواد الحظر الشائعة.

أنماط الإنتاج: التزامن المحدود وملفات تعريف الارتباط و Crawlee

التزامن المحدود مع p-limit

إطلاق 1000 طلب متزامن سيستنزف الموارد ويثير الشكوك. استخدم p-limit للتحكم في التزامن:

const pLimit = require('p-limit');

const limit = pLimit(10); // 10 طلبات متزامنة كحد أقصى

const urls = Array.from({ length: 100 }, (_, i) =>
  `https://httpbin.org/anything?page=${i}`
);

(async () => {
  const results = await Promise.all(
    urls.map((url) =>
      limit(() => scraper(url).then(
        (r) => ({ url, status: r.statusCode, ok: true }),
        (e) => ({ url, error: e.message, ok: false })
      ))
    )
  );

  const succeeded = results.filter((r) => r.ok).length;
  console.log(`نجح ${succeeded}/${results.length} طلب`);
})();

بمعدل 10 طلبات متزامنة، يمكنك معالجة آلاف الصفحات في الدقيقة دون إثارة أنظمة مكافحة البوت. اضبط الرقم حسب قدرة الموقع المستهدف و باقة ProxyHat الخاصة بك.

ملفات تعريف الارتباط (Cookie Jar)

بعض المواقع تتطلب جلسة متسلسلة (نفس الكوكيز) عبر عدة طلبات. got-scraping يدعم tough-cookie عبر خيار cookieJar:

const { CookieJar } = require('tough-cookie');

const jar = new CookieJar();

// تسجيل الدخول أولاً مع نفس الجلسة
const sessionScraper = gotScraping.extend({
  useHeaderGenerator: true,
  cookieJar: jar,
  proxyUrl: 'http://user-country-US-session-login01:PASSWORD@gate.proxyhat.com:8080',
});

(async () => {
  // طلب 1: الحصول على CSRF token
  await sessionScraper('https://example.com/login');
  // طلب 2: إرسال بيانات الدخول (نفس الكوكيز + نفس IP)
  const res = await sessionScraper.post('https://example.com/login', {
    json: { username: 'test', password: 'test' },
  });
  console.log(res.statusCode);
})();

استخدم session-xxx ثابتًا في اسم المستخدم للحفاظ على نفس IP طوال الجلسة. هذا ضروري للتدفقات متعددة الطلبات مثل تسجيل الدخول أو إضافة منتجات إلى سلة.

الانتقال إلى Crawlee's CheerioCrawler

عندما تكبر حملة الكشط، يصبح التنسيق اليدوي معقدًا. Crawlee من Apify يوفر إطار عمل كامل يدمج got-scraping بشكل أصلي:

const { CheerioCrawler } = require('crawlee');

const crawler = new CheerioCrawler({
  requestHandler: async ({ $, request }) => {
    const title = $('title').text();
    console.log(`${request.url} → ${title}`);
  },
  proxyConfiguration: {
    proxyUrls: [
      'http://user-country-US-session-1:PASSWORD@gate.proxyhat.com:8080',
      'http://user-country-US-session-2:PASSWORD@gate.proxyhat.com:8080',
      'http://user-country-US-session-3:PASSWORD@gate.proxyhat.com:8080',
    ],
  },
  maxRequestsPerMinute: 60,
  maxConcurrency: 5,
  useHeaderGenerator: true,
});

(async () => {
  await crawler.run(['https://example.com/page-1', 'https://example.com/page-2']);
})();

Crawlee يدير تلقائيًا: قوائم الانتظار، إعادة المحاولة، تدوير البروكسي، والتحكم في المعدل. هذا هو المستوى التالي من النضج لمشاريع كشط الويب الإنتاجية.

متى تحتاج متصفح headless والاعتبارات الأخلاقية

متى لا يكفي got-scraping

هناك حالات لا يكفي فيها عميل HTTP مهما كانت الترويسات واقعية:

  • التقديم الديناميكي (CSR): مواقع React/Vue/Angular التي تُحمّل المحتوى عبر JavaScript بعد تحميل الصفحة. got-scraping لا ينفّذ JS.
  • تحديات JavaScript التفاعلية: أنظمة مثل Cloudflare Turnstile أو Akamai Bot Manager التي تتطلب تنفيذ JS معقد.
  • التحقق من بصمة Canvas/WebGL: بعض المواقع تتحقق من بصمة المتصفح على مستوى الرسم.

في هذه الحالات، انتقل إلى Playwright أو Puppeteer مع بروكسي سكني. استخدم headless: false أو مكتبات مثل rebrowser-patches لتقليل بصمة الأتمتة. ابدأ دائمًا بـ got-scraping لأنه أسرع بكثير — متصفح headless يستهلك 200-500 MB من الذاكرة لكل صفحة، بينما got-scraping يحتاج أقل من 5 MB.

الاعتبارات الأخلاقية والقانونية

الكشط أداة قوية، لكنها تحمل مسؤولية:

  • احترم robots.txt: تحقق من /robots.txt قبل الكشط. حتى لو لم يكن ملزمًا قانونيًا في كل ولاية، فهو إشارة واضحة لنية الموقع.
  • حدود المعدل: لا ترسل أكثر من 1-2 طلب في الثانية لكل موقع ما لم يكن لديك سبب وجيه. هذا يحترم موارد الخادم.
  • البيانات العامة فقط: لا تتخطى مصادقة أو تصل لبيانات خاصة. قانون CFAA الأمريكي يجرّم الوصول غير المصرح به لأنظمة الكمبيوتر.
  • GDPR: إذا كنت تجمع بيانات شخصية من مستخدمين أوروبيين، فقد تنطبق متطلبات حماية البيانات.
  • واجهات API أولاً: إذا كان الموقع يوفر API رسميًا (حتى مدفوع)، استخدمه. أرخص وأسرع وأكثر موثوقية من الكشط.

راجع توثيق ProxyHat لمعرفة المزيد عن إعداد البروكسي السكني وأفضل الممارسات.

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

  • got-scraping يحل مشكلة الترويسات غير المتماسكة عبر مولد ترويسات مدمج ينتج مجموعات متصفح واقعية.
  • HTTP/2 يقلل من بصمة الاتصال ويجعل الطلب يبدو أقرب لمتصفح حقيقي.
  • البروكسي السكني ضروري بمجرد أن تبدو الترويسات و TLS واقعية — عنوان IP لمركز البيانات يكشف الطلب فورًا.
  • استخدم خطاف beforeRetry لتبديل البروكسي عند الفشل، و session-xxx للحفاظ على نفس IP للجلسات متعددة الطلبات.
  • p-limit للتحكم في التزامن، cookieJar لجلسات الكوكيز، و Crawlee لتنسيق الحملات الكبيرة.
  • انتقل إلى headless browser فقط عند الحاجة لتنفيذ JavaScript — فهو أبطأ بـ 40-100 مرة من got-scraping.
  • احترم robots.txt وحدود المعدل والقوانين المحلية. فضّل واجهات API الرسمية دائمًا.

جاهز للبدء؟ اطلع على أسعار ProxyHat أو استكشف المواقع المتاحة لبدء حملة الكشط التالية.

¿Listo para empezar?

Accede a más de 50M de IPs residenciales en más de 148 países con filtrado impulsado por IA.

Ver preciosProxies residenciales
← Volver al Blog