التعامل مع ترقيم الصفحات والمحتوى الديناميكي
اتباع روابط الصفحة التالية واستخدام Playwright للصفحات المُنشأة بواسطة JavaScript
التعامل مع ترقيم الصفحات والمحتوى الديناميكي درس مجاني في AI Agents على CoddyKit. هذا هو الدرس 3 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في AI Agents، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة AI Agents 4 دروس في المجموع.
مشكلة ترقيم الصفحات
معظم مواقع الويب الحقيقية لا تعرض جميع بياناتها في صفحة واحدة. تُقسَّم النتائج على عدة صفحات لتقليل الحمل. يجب على الوكيل اكتشاف ترقيم الصفحات واتباعه لجمع مجموعات البيانات كاملة.
هناك نمطان شائعان لترقيم الصفحات: روابط الصفحة التالية وأنماط عناوين URL لأرقام الصفحات.
اكتشاف روابط الصفحة التالية
تحتوي مواقع كثيرة على زر «التالي» أو رابط على شكل سهم. اعثروا على وسم الرابط الذي يحتوي على rel='next' أو على نص مثل «التالي»، واستخرجوا قيمة href منه، ثم اتبعوه داخل حلقة حتى لا يعود موجودًا.
from bs4 import BeautifulSoup
import httpx
def scrape_all_pages(start_url: str) -> list:
results = []
url = start_url
while url:
response = httpx.get(url, timeout=10.0)
soup = BeautifulSoup(response.text, 'html.parser')
# Collect data from this page
for item in soup.select('.result-item'):
results.append(item.text.strip())
# Find the next page link
next_link = soup.find('a', rel='next') or soup.find('a', string='Next')
url = next_link.get('href') if next_link else None
return resultsأنماط عناوين URL لأرقام الصفحات
تستخدم كثير من واجهات API والمواقع أنماطًا متوقعة لعناوين URL: /results?page=1 و/results?page=2 وغير ذلك. يمكن للوكيل التكرار عليها مباشرةً من دون تحليل DOM للبحث عن رابط الصفحة التالية.
import httpx
def scrape_paginated_api(base_url: str, max_pages: int = 10) -> list:
all_items = []
for page in range(1, max_pages + 1):
response = httpx.get(
base_url,
params={'page': page, 'per_page': 50},
timeout=10.0
)
response.raise_for_status()
data = response.json()
items = data.get('results', [])
if not items:
break # No more data
all_items.extend(items)
print(f'Page {page}: fetched {len(items)} items')
return all_itemsترقيم الصفحات القائم على المؤشر
تستخدم واجهات API الحديثة مثل GitHub وSlack وTwitter ترقيم الصفحات القائم على المؤشر. تتضمن كل استجابة رمز مؤشر للصفحة التالية. مرّروا المؤشر في الطلب التالي حتى يغيب أو تصبح قيمته null.
import httpx
def fetch_with_cursor(url: str, headers: dict) -> list:
all_data = []
cursor = None
while True:
params = {'cursor': cursor} if cursor else {}
response = httpx.get(url, headers=headers, params=params, timeout=10.0)
response.raise_for_status()
data = response.json()
all_data.extend(data.get('items', []))
cursor = data.get('next_cursor') # None when done
if not cursor:
break
return all_dataالمحتوى الثابت مقابل الديناميكي
تُحمّل بعض الصفحات المحتوى باستخدام JavaScript بعد تسليم HTML الأولي. لا يتلقى عميل HTTP العادي سوى القشرة الفارغة، إذ تُحقن البيانات الفعلية بواسطة JS في المتصفح.
بالنسبة إلى هذه الصفحات، تشغّل أدوات مثل Playwright محرك متصفح حقيقي وتنتظر تنفيذ JavaScript قبل استخراج المحتوى.
تثبيت Playwright واستيراده
ثبّتوا Playwright باستخدام pip install playwright، ثم شغّلوا playwright install chromium لتنزيل المتصفح. استخدموا async_playwright() في مسارات عمل الوكلاء غير المتزامنة.
# Installation (run in terminal):
# pip install playwright
# playwright install chromium
from playwright.async_api import async_playwright
import asyncio
async def fetch_dynamic(url: str) -> str:
async with async_playwright() as p:
browser = await p.chromium.launch(headless=True)
page = await browser.new_page()
await page.goto(url)
html = await page.content() # Full rendered HTML
await browser.close()
return html
# html = asyncio.run(fetch_dynamic('https://example.com'))انتظار تحميل المحتوى الديناميكي
غالبًا ما تحمّل صفحات JavaScript البيانات بشكل غير متزامن. اطلبوا من Playwright الانتظار حتى يظهر عنصر محدد قبل استخراج المحتوى، لضمان وجود البيانات التي تحتاجون إليها فعلًا في DOM.
from playwright.async_api import async_playwright
async def scrape_dynamic_table(url: str) -> list:
async with async_playwright() as p:
browser = await p.chromium.launch(headless=True)
page = await browser.new_page()
await page.goto(url)
# Wait for the table to appear in the DOM
await page.wait_for_selector('table.results', timeout=10000)
html = await page.content()
await browser.close()
from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'html.parser')
return [td.text for td in soup.select('table.results td')]النقر والتفاعل مع الصفحات
يمكن لـPlaywright محاكاة تفاعلات المستخدم، مثل النقر وملء النماذج والتمرير وإدخال لوحة المفاتيح. يتيح ذلك للوكيل التنقل عبر عمليات تسجيل الدخول والقوائم المنسدلة وصفحات التمرير اللانهائي.
from playwright.async_api import async_playwright
async def click_load_more(url: str) -> str:
async with async_playwright() as p:
browser = await p.chromium.launch(headless=True)
page = await browser.new_page()
await page.goto(url)
# Click the 'Load More' button
load_more = page.locator('button:text("Load More")')
if await load_more.count() > 0:
await load_more.click()
await page.wait_for_timeout(2000) # wait 2s for content
html = await page.content()
await browser.close()
return htmlالتعامل مع التمرير اللانهائي
تحمّل بعض المواقع مزيدًا من المحتوى أثناء التمرير إلى الأسفل. يمكن لـPlaywright محاكاة التمرير لتحفيز عمليات التحميل هذه. كرّروا التمرير وتحققوا في كل مرة مما إذا كان محتوى جديد قد ظهر.
from playwright.async_api import async_playwright
async def scrape_infinite_scroll(url: str, scroll_count: int = 5) -> str:
async with async_playwright() as p:
browser = await p.chromium.launch(headless=True)
page = await browser.new_page()
await page.goto(url)
for _ in range(scroll_count):
await page.evaluate('window.scrollTo(0, document.body.scrollHeight)')
await page.wait_for_timeout(1500) # wait for new content
html = await page.content()
await browser.close()
return htmlالجمع بين Playwright وBeautifulSoup
بعد أن يعرض Playwright الصفحة ويعيد HTML الكامل، مرّروه إلى BeautifulSoup لتسهيل استخراج البيانات. يجمع ذلك بين نقاط قوة المكتبتين.
from playwright.async_api import async_playwright
from bs4 import BeautifulSoup
async def extract_js_rendered_data(url: str) -> list:
async with async_playwright() as p:
browser = await p.chromium.launch(headless=True)
page = await browser.new_page()
await page.goto(url)
await page.wait_for_selector('.product-card')
html = await page.content()
await browser.close()
soup = BeautifulSoup(html, 'html.parser')
products = []
for card in soup.select('.product-card'):
products.append({
'name': card.select_one('.name').text.strip(),
'price': card.select_one('.price').text.strip()
})
return productsاختيار الأداة المناسبة
لا تحتاج كل صفحة إلى Playwright. استخدموا أبسط نهج ينجح:
- HTML ثابت: httpx + BeautifulSoup (سريع، ومن دون تكلفة تشغيل متصفح)
- واجهة JSON برمجية مع ترقيم الصفحات: httpx مع معاملات الصفحة/المؤشر
- محتوى معروض بواسطة JS: Playwright async (أبطأ، لكنه أكثر قوة)
ابدؤوا دائمًا بالنهج الثابت، ولا تلجؤوا إلى Playwright إلا عند الحاجة.
اختبار المعرفة: ترقيم الصفحات والمحتوى الديناميكي
اختبروا فهمكم للتعامل مع ترقيم الصفحات والمحتوى الديناميكي.
مراجعة: ترقيم الصفحات والمحتوى الديناميكي
أصبح بإمكان وكلائكم الآن التعامل مع مختلف أشكال محتوى الويب:
- اتباع روابط الصفحة التالية أو التكرار عبر معاملات الصفحة في عناوين URL
- استخدام رموز المؤشر لترقيم الصفحات في واجهات API الحديثة
- استخدام
async_playwright()للصفحات المعروضة بواسطة JavaScript - انتظار العناصر باستخدام
page.wait_for_selector() - الجمع بين Playwright وBeautifulSoup لتسهيل استخراج البيانات
ابدؤوا دائمًا بأبسط نهج، وانتقلوا إلى Playwright فقط عندما لا يكفي النهج الثابت.
الأسئلة الشائعة
هل درس «التعامل مع ترقيم الصفحات والمحتوى الديناميكي» مجاني؟
نعم — نص درس «التعامل مع ترقيم الصفحات والمحتوى الديناميكي» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة AI Agents، انتقل إلى CoddyKit PRO. تتضمن دورة AI Agents 4 دروس في المجموع.
ماذا ستتعلم في «التعامل مع ترقيم الصفحات والمحتوى الديناميكي»؟
اتباع روابط الصفحة التالية واستخدام Playwright للصفحات المُنشأة بواسطة JavaScript تتمرن على AI Agents مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.
هل أحتاج إلى خبرة سابقة لأبدأ AI Agents؟
لا تُشترط خبرة سابقة. AI Agents على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 3 من أصل 4.
كم من الوقت يستغرق درس «التعامل مع ترقيم الصفحات والمحتوى الديناميكي»؟
معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.
هل يمكنني كتابة وتشغيل أكواد في درس AI Agents هذا؟
نعم. كل درس في AI Agents يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.
جميع الدروس في هذه الدورة
- عملاء HTTP للوكلاء: httpx وrequests
- تحليل HTML باستخدام BeautifulSoup
- التعامل مع ترقيم الصفحات والمحتوى الديناميكي
- ممارسات الاستخلاص المسؤولة