كشط موقع ويب ديناميكي

تقوم مواقع الويب الديناميكية بتحميل المحتوى باستخدام JavaScript بعد التحميل الأولي للصفحة. يوضح هذا الدليل كيفية جمع البيانات من هذه المواقع باستخدام browser endpoint الخاص بـ FourA.

المشكلة

عند إرسال HTTP request قياسي إلى موقع يعتمد بكثافة على JavaScript، فإنك تحصل على هيكل HTML فقط دون المحتوى الفعلي. يتم تحميل البيانات التي تحتاجها (قوائم المنتجات، الأسعار، نتائج البحث) بواسطة JavaScript بعد معالجة الصفحة وعرضها في المتصفح.

أصبح هذا الأمر شائعا بشكل متزايد مع أطر العمل الحديثة مثل React وVue وAngular وNext.js.

الحل: طلبات المتصفح (Browser Requests)

يفتح browser endpoint الخاص بـ FourA‏ (POST /api/browser/) عنوان URL الخاص بك داخل نسخة متصفح Chrome تقوم بما يلي:

  1. تحميل الصفحة
  2. تنفيذ جميع تعليمات JavaScript البرمجية
  3. الانتظار حتى يتم عرض المحتوى بالكامل
  4. إرجاع كود HTML المعروض بالكامل

الخطوة 1: تحديد ما تحتاجه

قبل إجراء الطلب، تفضل بزيارة الصفحة المستهدفة في متصفحك واستخدم DevTools‏ (F12) للعثور على جزء من النص أو عنصر يؤكد اكتمال تحميل المحتوى. على سبيل المثال:

  • اسم منتج يظهر بعد انتهاء JS من معالجة الصفحة وعرضها
  • فئة CSS مثل product-grid داخل HTML المعروض
  • سلسلة نصية مثل "results" لا تظهر إلا عند اكتمال تحميل البيانات

الخطوة 2: إرسال Browser Request

curl -X POST https://eu.api.foura.ai/api/browser/ \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://example.com/products",
    "timeout_ms": 15000,
    "checkText": "product-grid"
  }'

يوجّه الخيار checkText أداة FourA للتحقق من وجود "product-grid" في الصفحة فور اكتمال تحميلها. إذا لم تكن موجودة، يرجع الـ request كفشل مع checkText:product-grid not found، ولا تتم فوترة الـ request الفاشل. لا يجعل checkText أداة FourA تنتظر النص لفترة أطول.

الخطوة 3: تحليل الـ HTML

يتضمن الـ response كود الـ HTML المعروض بالكامل في الحقل body. قم بتحليله باستخدام مكتبتك المفضلة:

Python (BeautifulSoup)

import requests
from bs4 import BeautifulSoup

resp = requests.post("https://eu.api.foura.ai/api/browser/", headers={
    "X-API-Key": "YOUR_API_KEY",
    "Content-Type": "application/json"
}, json={
    "url": "https://example.com/products",
    "timeout_ms": 15000,
    "checkText": "product-grid"
})

html = resp.json()["body"]
soup = BeautifulSoup(html, "html.parser")

for product in soup.select(".product-card"):
    name = product.select_one(".product-name").text.strip()
    price = product.select_one(".product-price").text.strip()
    print(f"{name}: {price}")

Node.js (cheerio)

import * as cheerio from 'cheerio';

const resp = await fetch('https://eu.api.foura.ai/api/browser/', {
  method: 'POST',
  headers: { 'X-API-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json' },
  body: JSON.stringify({
    url: 'https://example.com/products',
    timeout_ms: 15000,
    checkText: 'product-grid'
  })
});

const { body: html } = await resp.json();
const $ = cheerio.load(html);

$('.product-card').each((i, el) => {
  console.log($(el).find('.product-name').text(), $(el).find('.product-price').text());
});

استكشاف الأخطاء وإصلاحها

هل ما زلت تتلقى محتوى فارغًا؟

  • تحقق مما إذا كانت الصفحة تستخدم تصيير JavaScript بالفعل (قارن بين "View Source" وأدوات DevTools)
  • زد قيمة timeout_ms: فبعض الصفحات تستغرق وقتًا أطول في التحميل
  • تحقق مما إذا كانت الصفحة تتطلب مصادقة أو ملفات cookie (استخدم المعامل cookies)

هل تظهر لك صفحة تحقق؟

  • بالنسبة لطلبات HTTP الفردية، انتقل إلى endpoint الخاص بـ proxy وهو (POST /api/proxy/) للتدوير التلقائي لعناوين IP.
  • لتوجيه طلب متصفح عبر proxy، مرر المعامل proxy الخاص بـ endpoint المتصفح. يقتصر endpoint الخاص بـ proxy على تغليف طلبات HTTP الفردية فقط، وليس طلبات المتصفح.

يقبل المعامل proxy معرّف proxy المبهم (opaque proxy ID) الذي تم إرجاعه في استجابة سابقة، ولا يقبل أبدًا عنوان proxy خاصًا بك. نفّذ استدعاء POST /api/proxy/ واحدًا (أو POST /api/auto/) أولاً، ثم اقرأ حقل proxy الذي يعيده، ثم قم بتثبيته:

# Step 1: let FourA find a working exit. The response carries "proxy": "A1B2C3".
curl -X POST "https://eu.api.foura.ai/api/proxy/" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"maxTries": 5, "request": {"method": "GET", "url": "https://example.com/products"}}'

# Step 2: render through that same exit.
curl -X POST "https://eu.api.foura.ai/api/browser/" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"url": "https://example.com/products", "proxy": "A1B2C3", "timeout_ms": 20000}'

يؤدي إرسال عنوان بدلاً من معرف إلى إرجاع 400 Invalid proxy format. النمط الكامل متوفر في Reuse a Proxy Across Requests.

الخطوات التالية

آخر تحديث: 27 سبتمبر 2026