كشط موقع ويب ديناميكي
تحمل مواقع الويب الديناميكية المحتوى باستخدام JavaScript بعد التحميل الأولي للصفحة. يوضح هذا الدليل كيفية جمع البيانات من هذه المواقع باستخدام browser endpoint الخاص بـ FourA.
المشكلة
عندما ترسل HTTP request قياسيًا إلى موقع ويب يعتمد بكثافة على JavaScript، فإنك تحصل على هيكل HTML الخارجي وليس المحتوى الفعلي. يتم تحميل البيانات التي تحتاجها (قوائم المنتجات، الأسعار، نتائج البحث) بواسطة JavaScript بعد رندرة الصفحة في المتصفح.
يعد هذا الأمر شائعًا بشكل متزايد مع أطر العمل الحديثة مثل React و Vue و Angular و Next.js.
الحل: browser requests
يفتح browser endpoint الخاص بـ FourA (POST /api/browser/) رابط URL الخاص بك في مثيل متصفح Chrome الذي يقوم بما يلي:
- تحميل الصفحة
- تنفيذ جميع أكواد JavaScript
- الانتظار حتى يتم رندرة المحتوى
- إرجاع كود HTML المرندر بالكامل
الخطوة 1: تحديد ما تحتاجه
قبل إرسال request، قم بزيارة الصفحة المستهدفة في متصفحك واستخدم 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" في الصفحة المرندرة. إذا لم تظهر قبل انتهاء المهلة (timeout)، سيفشل request، مما يعلمك بأن المحتوى لم يتم تحميله.
الخطوة 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: بعض الصفحات تستغرق وقتًا أطول في التحميل - تحقق مما إذا كانت الصفحة تتطلب مصادقة أو cookies (استخدم معامل
cookies)
هل تظهر لك صفحة captcha؟
- بالنسبة لـ single/HTTP requests، انتقل إلى proxy endpoint (
POST /api/proxy/) لتدوير عنوان IP تلقائيًا. - لإضافة تدوير proxy إلى browser requests، استخدم معامل
proxyالخاص بـ browser endpoint بدلاً من تغليفه في proxy endpoint. حيث يقوم proxy endpoint بتغليف single/HTTP requests فقط، وليس browser requests.
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", "proxy": "http://proxy-url:port"}'
الخطوات التالية
- اختيار Endpoint المناسب: متى تستخدم browser مقابل single
- مراقبة أسعار المنافسين: دليل كامل لتتبع الأسعار
- الحماية من البوتات (Anti-Bot Protection): التعامل مع المواقع المحمية