دليل بايثون لاستخراج بيانات الويب: من Requests إلى Playwright إلى Apify API (2026)
تعلم استخراج بيانات الويب ببايثون في 2026: استخدم requests وBeautifulSoup للصفحات الثابتة وPlaywright للمواقع الديناميكية ثم شغّل الزحف الإنتاجي عبر Apify API.
بصفتنا شركاء لـ Apify، قد نحصل على عمولة من عمليات الشراء المؤهلة التي تتم من خلال روابطنا، دون أي تكلفة إاضافية عليك. نحن نوصي فقط بالأدوات التي نثق بها.
معظم دروس استخراج البيانات ببايثون تعلمك أداة واحدة فقط وتتركك عاجزا لحظة تغيّر الموقع المستهدف. فقائمة منتجات ثابتة تعمل بشكل رائع مع requests — حتى ينقل الموقع كتالوجه خلف العرض بجافاسكربت. وتحل Playwright هذه المشكلة — حتى تحتاج إلى تشغيل المهمة كل ليلة، وتجاوز الحظر، وإيصال بيانات نظيفة لزميل لا يشغّل بايثون.
يعلمك هذا الدليل السلم الكامل بدلا من ذلك: ثلاثة مستويات يبني كل منها على سابقه. المستوى الأول يستخرج الصفحات الثابتة مع requests وBeautifulSoup. المستوى الثاني يتعامل مع الصفحات المعروضة بجافاسكربت عبر Playwright. المستوى الثالث ينقل المنطق العامل إلى الإنتاج على Apify API، حيث الجدولة والبروكسيات والتخزين مُدارة نيابة عنك. وفي النهاية ستعرف ليس فقط كيف يعمل كل مستوى، بل متى تتخرج من مستوى إلى التالي بالضبط.
كل ما تحتاجه هو بايثون 3.10 أو أحدث مع pip. ثبّت المكتبات أثناء التقدم — فكل قسم يذكر أمر التثبيت الخاص به في سطر واحد.
المستوى الأول: الصفحات الثابتة مع Requests وBeautifulSoup
معظم الصفحات المهمة للاستخراج — فهارس المدونات والتوثيق وقوائم المنتجات البسيطة وخرائط المواقع — ثابتة: إذ يعيد الخادم كامل HTML في استجابة واحدة. ولهذه الصفحات، يبقى HTTP العادي مع محلل HTML أسرع وأرخص حزمة وأسهلها في التنقيح.
ثبّت المكتبتين:
pip install requests beautifulsoup4
يتكون النمط من أربع خطوات: الجلب مع User-Agent مهذب ومهلة زمنية، والفشل بصوت عالٍ عند أخطاء HTTP، وتحليل HTML، واختيار العناصر المطلوبة بمحددات CSS.
import requests
from bs4 import BeautifulSoup
HEADERS = {"User-Agent": "Mozilla/5.0 (compatible; ParseFlowTutorial/1.0)"}
response = requests.get("https://example.com/products", headers=HEADERS, timeout=15)
response.raise_for_status()
soup = BeautifulSoup(response.text, "html.parser")
for card in soup.select("div.product-card"):
title = card.select_one("h2.title").get_text(strip=True)
price = card.select_one("span.price").get_text(strip=True)
link = card.select_one("a").get("href")
print(title, price, link)
سبب نجاح هذا الأسلوب: requests.get ينفذ طلب HTTP مع ترويساتك ويتوقف بعد 15 ثانية بدلا من التعليق إلى الأبد. وتحوّل raise_for_status استجابات 4xx و5xx إلى استثناءات فلا تتسرب بيانات سيئة بصمت إلى المراحل التالية. وتبني BeautifulSoup(response.text, "html.parser") شجرة قابلة للبحث من HTML باستخدام المحلل المدمج في بايثون — دون اعتماديات نظام إضافية. ثم تقبل select وselect_one محددات CSS نفسها التي تعرفها من أوراق الأنماط، وتعيد get_text(strip=True) نصا نظيفا دون فراغات محيطة، وتقرأ get("href") قيمة خاصية.
ثلاث عادات تفصل كاشطات المستوى الأول العاملة عن الهشة. أولا، اضبط دائما User-Agent وصفيا — فهو يعرّف سكربتك في سجلات الخوادم وهو من آداب المهنة. ثانيا، باعد بين طلباتك: فتوقف قصير بين الصفحات يبقيك أدنى بكثير من حدود المعدل في المهام الصغيرة. ثالثا، احفظ نسخة HTML عينة على القرص أثناء التطوير، واكتب محدداتك مقابل النسخة المحفوظة. فإعادة جلب الصفحة الحية مع كل تجربة بطيئة وقد تسبب حظرا عرضيا قبل أن يعمل كودك أصلا.
يصل المستوى الأول إلى سقفه في اليوم الذي يتوقف فيه HTML عن احتواء البيانات. فإذا احتوى response.text على عناصر نائبة فارغة مثل <div id="app"></div> مكان المنتجات، فالمحتوى يُعرض بجافاسكربت بعد التحميل — ولا يمكن لأي جالب HTTP رؤيته. وهذه هي إشارة المستوى الثاني.
المستوى الثاني: الصفحات الديناميكية مع Playwright
مواقع جافاسكربت — متاجر React وخلاصات التمرير اللانهائي ولوحات التحكم وكل ما خلف المرشحات التفاعلية — تبني محتواها في المتصفح بعد وصول HTML الأولي. ولاستخراجها تحتاج إلى متصفح حقيقي، وPlaywright هي أفضل طريقة لقيادته من بايثون: فواجهة واحدة تتحكم في Chromium وFirefox وWebKit، مع انتظار تلقائي يقضي على معظم عدم الاستقرار الذي عانت منه أتمتة المتصفحات القديمة.
ثبتها مع ملف المتصفح:
pip install playwright && playwright install chromium
يطابق النمط المستوى الأول مع متصفح في الوسط: تشغيل Chromium دون واجهة، وفتح صفحة، والتنقل، وانتظار ظهور محدد المحتوى، ثم التقاط HTML المعروض وتحليله بمهارات BeautifulSoup التي تملكها.
from playwright.sync_api import sync_playwright
from bs4 import BeautifulSoup
with sync_playwright() as p:
browser = p.chromium.launch(headless=True)
page = browser.new_page(user_agent="Mozilla/5.0 (compatible; ParseFlowTutorial/1.0)")
page.goto("https://example.com/dynamic-list", wait_until="domcontentloaded")
page.wait_for_selector("div.product-card")
html = page.content()
browser.close()
soup = BeautifulSoup(html, "html.parser")
for card in soup.select("div.product-card"):
title = card.select_one("h2.title").get_text(strip=True)
price = card.select_one("span.price").get_text(strip=True)
print(title, price)
ثلاثة تفاصيل تقوم بالعمل الشاق هنا. wait_until="domcontentloaded" تخبر goto بالعودة فور تحليل هيكل الصفحة بدلا من انتظار كل صورة وأداة تتبع، مما يجعل التشغيل أسرع بوضوح. ثم تتوقف wait_for_selector مؤقتا حتى يوجد عنصر بطاقة نتائج واحد على الأقل في DOM — وهذا السطر الواحد يستبدل التوقفات الثابتة الهشة التي تجعل سكربتات المتصفح الساذجة متقطعة. وتعيد page.content() كامل HTML المعروض بعد تنفيذ جافاسكربت، فتستمر محددات المستوى الأول نفسها في العمل.
تفتح Playwright أيضا تفاعلات لا يستطيع HTTP فعلها أبدا: النقر على أزرار «تحميل المزيد» في حلقة، وملء مربعات البحث، وتمرير الخلاصات اللانهائية حتى تتوقف البطاقات الجديدة عن الظهور، والتقاط استجابات الشبكة مباشرة. لكن لاحظ ما لا يحله المستوى الثاني: فالمتصفح ما زال يعمل على جهازك، وما زلت تدير الحظر وإعادة المحاولة بنفسك، ولا شيء يعمل أثناء نوم حاسوبك المحمول، وتسليم السكربت لزميل يعني تسليمه تعليمات الإعداد أيضا. وعندما يبدأ أي من ذلك بالإيلام، تخرّج إلى المستوى الثالث.
المستوى الثالث: الاستخراج الإنتاجي مع Apify API
يُبقي المستوى الثالث على بايثون لديك لكنه ينقل التنفيذ إلى بنية تحتية مُدارة. فبدلا من صيانة المتصفحات والبروكسيات وقوائم الانتظار ومهام cron، تستدعي ممثلا مُدارا — كاشطة جاهزة مستضافة — عبر Apify API وتقرأ النتائج كبيانات منظمة. ويتقلص سكربتك المحلي إلى عميل نحيف: يبدأ التشغيل وينتظر ثم يجلب مجموعة البيانات.
ثبّت العميل الرسمي:
pip install apify-client
تجد رمز API الخاص بك في لوحة تحكم Apify تحت الإعدادات ثم التكاملات. يشغّل المثال التالي Web Scraper — الممثل العام الذي يعرض الصفحات في متصفح حقيقي، كما يفعل سكربت Playwright الخاص بك — مقابل رابط بداية، ثم يمر على كل سجل مستخرج.
from apify_client import ApifyClient
client = ApifyClient("YOUR_APIFY_API_TOKEN")
run_input = {
"startUrls": [{"url": "https://example.com/products"}],
}
run = client.actor("apify/web-scraper").call(run_input=run_input)
dataset = client.dataset(run["defaultDatasetId"])
for item in dataset.iterate_items():
print(item.get("url"), item.get("title"))
يخاطب client.actor("apify/web-scraper") الممثل بمعرفه في المتجر، وتبدأ .call(run_input=run_input) التشغيل وتنتظر انتهاءه — واستخدم .start() بدلا منها عندما تريد الاستطلاع أو التوازي من كودك الخاص. ويشير run["defaultDatasetId"] إلى مخزن نتائج التشغيل، وتبث iterate_items() كل سجل كقاموس بايثون، فيُدار ترقيم الصفحات والتنزيل نيابة عنك. والحقول نفسها التي اخترتها بـ CSS في المستويين الأول والثاني تصبح إعدادات الاستخراج في مدخلات الممثل — فالنموذج الذهني ينتقل مباشرة.
إذا كان هدفك نصا نظيفا للصفحات لأعباء الذكاء الاصطناعي بدلا من حقول مخصصة لكل موقع، فاستبدل به Website Content Crawler الذي يعيد Markdown أو نصا عاديا جاهزا لخطوط RAG. وفي كلتا الحالتين، قارن صفحات المتجر للممثلين — بما فيها مخططات المدخلات وعينات المخرجات — مع صفحتي التفاصيل لدينا عن Web Scraper وWebsite Content Crawler قبل الالتزام بأحدهما.
ثلاث مزايا إنتاجية تأتي مجانا مع الانتقال وتستحق الفهم. الجدولة تحوّل السكربت المفرد إلى خط أنابيب: ففي لوحة التحكم، يعيد الجدول تشغيل مدخلات الممثل المحفوظة وفق توقيت cron، فتكون مجموعات بيانات صباح الاثنين موجودة ببساطة. إدارة البروكسيات والبصمات مدمجة في المنصة — تدوير سكني وTLS شبيه بالمتصفح ومعالجة CAPTCHA كانت ستكلف أسابيع من العمل لتكرارها محليا. والتخزين المنظم يعني أن كل تشغيل يستقر في مجموعة بيانات يمكنك تصديرها كـ Excel أو CSV أو JSON، أو دفعها للمراحل التالية عبر webhooks والتكاملات دون لمس سكربتك.
متى تتخرج من مستوى إلى التالي
استخدم دليل القرار هذا بأمانة وستتجنب الطرفين معا — المبالغة الهندسية في استخراج صفحة واحدة والتقصير الهندسي في خط أنابيب عمل.
ابق في المستوى الأول عندما تكون البيانات في HTML الخام، والمهمة تعمل أحيانا، وبضع مئات من الصفحات هي العالم كله. ففحص الأسعار الأسبوعي عبر عشرين صفحة منتجات هو مهمة مستوى أول مثالية إلى الأبد.
تخرّج إلى المستوى الثاني عندما يصل HTML فارغا ويُعرض المحتوى بجافاسكربت، أو عندما تحتاج إلى التفاعل مع الصفحة — البحث أو الترشيح أو ترقيم الصفحات أو التمرير. والعلامة ميكانيكية: response.text يفتقد البيانات لكن المتصفح يعرضها. وتوقع أن تعمل سكربتات المستوى الثاني أبطأ بعشر إلى خمسين مرة لكل صفحة من المستوى الأول، وهو مقبول لمئات الصفحات ومؤلم لمئات الآلاف.
تخرّج إلى المستوى الثالث عندما يتحقق شرطان من هذه: يجب أن تعمل المهمة وفق جدول دون تدخل منك، أو أن الحظر وCAPTCHA يلتهمان صباحاتك، أو أن قائمة الأهداف تتجاوز ما يستطيع جهازك مضغه، أو أن شخصا آخر يعتمد على البيانات. فتلك هي اللحظة التي يتوقف فيها الممثلون المُدارون عن كونهم رفاهية ويصبحون أرخص من وقتك — فالرصيد المجاني يغطي تشغيلات تجريبية حقيقية، فتحقق من جودة المخرجات قبل التوسع.
وقاعدة إبهام أخيرة: لا تعيد تنفيذ مستوى أدنى لما يوجد أصلا كممثل مُدار. تحقق من متجر الممثلين قبل كتابة سكربت مستوى ثانٍ لموقع شائع — فالكاشطة المخصصة مع تسجيلات الدخول المُدارة وترقيم الصفحات ومخططات المخرجات تتفوق شبه حتما على مشروع عطلة نهاية أسبوعك.
الخطوات التالية
أصبح لديك الآن السلم الكامل: جلب الصفحات الثابتة وتحليلها، وعرض الصفحات الديناميكية، وتشغيل الزحف الإنتاجي عبر API. ويأخذك دليلان بالخطوتين الطبيعيتين التاليتين من هنا.
أولا، يعيش الاستخراج الإنتاجي أو يموت بتجنب الحظر. اقرأ الاستخراج دون حظر لتتعلم كيف تكتشف المواقع الروبوتات، ومتى تهم البروكسيات السكنية فعلا، وكيفية إيقاع الطلبات مع التراجع الأسي، وكيف يمتص الممثلون المُدارون معظم هذا التعقيد نيابة عنك.
ثانيا، ضع السلم موضع العمل في مشروع حقيقي. يشرح دليل استخراج نتائج البحث بناء متكاملا — إعداد ممثل بحث وتحليل مخرجاته ببايثون وتخزين النتائج للتتبع — وهو ما يمرّن كل مستوى من مستويات هذا الدليل مقابل صفحات نتائج بحث حية.
اختر موقعا مستهدفا صغيرا هذا الأسبوع، واصعد المستويات الثلاثة مقابله، ولاحظ أين يجهد كل مستوى. فهذا الإحساس الملموس بالحدود — الثابت مقابل الديناميكي، والسكربت مقابل المنصة — هو المهارة الحقيقية التي يعلمها هذا الدليل، وهي تنتقل معك إلى كل مشروع استخراج ستلمسه في 2026.
الأسئلة الشائعة
هل أتعلم requests أم أبدأ مباشرة مع Playwright لاستخراج البيانات؟
متى أنقل الكاشطة من السكربتات المحلية إلى Apify؟
أي ممثل في Apify يطابق أمثلة هذا الدليل؟
هل أحتاج إلى بروكسيات لسكربتات المستويين الأول والثاني في هذا الدليل؟
الكاتب: ParseFlow
فريق التحرير في ParseFlow يتألف من خبراء في استخراج بيانات الويب والأتمتة. نحن نختبر ونراجع باستمرار أدوات Apify لضمان تقديم أفضل التوصيات العملية وأكثرها دقة.
اقرأ إرشاداتنا التحريرية ←🛠️ الأدوات المقترحة
أداة سحب الويب العامة
اسحب أي موقع باستخدام متصفح واستخرج بيانات منظمة باستخدام كود JavaScript مخصص. أتمت الاستخراج المجدول وصدّر النتائج إلى Excel أو JSON.
زاحف محتوى المواقع
زاحف مواقع متطور يستخرج محتوى نظيف ومنظم بصيغة Markdown أو JSON أو نص عادي لتطبيقات الذكاء الاصطناعي وLLM. بدون برمجة — شغّل الأداة على السحابة وحمّل بياناتك فورًا.
الوسوم
ParseFlow
استوديو سحب البيانات والأتمتة
سنوات من الخبرة العملية في بناء وصيانة أدوات سحب البيانات. ننشر أدوات حقيقية ومستخدمة فعلياً على متجر Apify تحت علامة Website Harvester — بما في ذلك أداة Articles Extractor — إلى جانب فهرسة ومراجعة نظام Apify الأوسع هنا في ParseFlow.