يا جماعة الخير، السلام عليكم ورحمة الله.
بتذكر أيام الجامعة في نابلس، كنت طالب هندسة حاسوب متحمس وبحلم أجمع “تجميعة العمر”، يعني جهاز كمبيوتر بمواصفات خارقة للألعاب والبرمجة. المشكلة، زي ما الكل بعرف، كانت الميزانية على القد. كنت أقضي ساعات كل يوم أفتح مواقع المحلات الإلكترونية واحد ورا الثاني، وأقارن أسعار كرت الشاشة والمعالج والرامات، وأسجل كل إشي على ورقة. عملية مملة وبتضيع وقت كثير، ومرات لما أقرر أشتري قطعة، بلاقي سعرها تغير أو خلصت من المخزون.
هون خطرتلي فكرة: “ليش ما أخلّي الكمبيوتر يعمل هالشغلة عني؟”. أنا مبرمج، والمفروض ألاقي حلول ذكية. ومن هنا بدأت رحلتي مع عالم الـ Web Scraping أو “كشط الويب”. كتبت أول سكربت بسيط بلغة بايثون، كان يدخل على المواقع هاي، يسحب أسعار القطع اللي بدي إياها، ويحفظها في ملف. شعور الإنجاز وقتها كان لا يوصف! كأني امتلكت قوة خارقة. هذا السكربت الصغير فتح عيوني على إمكانيات هائلة، ومن يومها صار الـ Web Scraping جزء أساسي من صندوق أدواتي كمطور.
اليوم، حابب أشارككم خبرتي في هذا المجال، ونمشي خطوة بخطوة لنتعلم كيف نحول أي موقع على الإنترنت إلى مصدر بيانات منظم نقدر نستفيد منه. يلا، جهزوا فنجان القهوة، وشغلوا المحرر، وخلينا نبدأ.
ما هو الـ Web Scraping بالضبط؟
ببساطة، الـ Web Scraping هو عملية برمجية آلية لاستخراج كميات كبيرة من البيانات من صفحات الويب. تخيل أنك عينت روبوت فائق السرعة ليزور المواقع، يقرأ محتواها، وينسخ المعلومات اللي بتهمك (مثل أسعار المنتجات، عناوين الأخبار، أرقام الهواتف، إلخ) ثم ينظمها لك في جدول أو قاعدة بيانات.
هذا الفن مفيد جداً في مجالات لا حصر لها: تحليل المنافسين، تجميع بيانات للبحث العلمي، بناء تطبيقات تعتمد على بيانات من مصادر متعددة، مراقبة الأسعار، والكثير غيرها.
قبل أن نبدأ: الجانب الأخلاقي والقانوني (خطوط حمراء)
قبل ما نكتب أي سطر كود، لازم نحكي عن المسؤولية. الـ Web Scraping سيف ذو حدين، واستخدامه بشكل خاطئ ممكن يسبب مشاكل لك وللموقع اللي بتستخرج منه البيانات. هاي أهم القواعد اللي بمشي عليها دايماً:
- احترم ملف
robots.txt: معظم المواقع عندها ملف اسمهrobots.txt(مثلاًexample.com/robots.txt). هذا الملف هو عبارة عن دليل يخبر العناكب الآلية (زي عنكبوت جوجل وسكربتاتنا) ما هي الصفحات المسموح والممنوع زيارتها. احترامه واجب أخلاقي. - لا تكن ضيفاً ثقيلاً: لما ترسل طلبات كثيرة جداً في وقت قصير، أنت تضع حملاً كبيراً على خادم الموقع (Server)، وممكن تسبب بطء أو حتى توقف للموقع عن العمل. خليك لطيف، وحط فواصل زمنية بين طلباتك.
- اقرأ شروط الاستخدام (Terms of Service): بعض المواقع تمنع صراحةً استخراج البيانات من صفحاتها في شروط الخدمة. تجاهل هذه الشروط قد يعرضك للمساءلة القانونية.
نصيحة من أبو عمر: تعامل مع الموقع الذي تستخرج منه البيانات كما لو كان بيتك. لا تحدث فوضى، لا تستهلك موارده بشكل مفرط، واحترم قواعده. السمعة الطيبة في عالم البرمجة أهم من أي بيانات تجمعها.
صندوق الأدوات: أسلحتنا في هذه المعركة
في بايثون، لدينا مكتبتان أساسيتان هما العمود الفقري لعملية الـ Web Scraping:
1. مكتبة Requests: ساعي البريد
تخيل أنك تريد رسالة من صديق. مكتبة Requests هي ساعي البريد الذي يذهب إلى عنوان صديقك (رابط الموقع) ويحضر لك الرسالة (محتوى صفحة الويب بصيغة HTML). هي مسؤولة فقط عن جلب الصفحة، لا أكثر ولا أقل.
2. مكتبة Beautiful Soup: المترجم الخبير
بعد أن تصلك الرسالة (صفحة الـ HTML)، قد تكون غير مفهومة أو غير منظمة. هنا يأتي دور Beautiful Soup. هذه المكتبة تحلل محتوى الـ HTML المعقد وتجعله سهل التصفح والبحث، كأنها مترجم خبير يقرأ الرسالة ويفصصها لك ليسهل عليك إيجاد المعلومة التي تريدها.
الخطوة الأولى: فهم بنية الهدف (مخطط الموقع)
قبل أن نقتحم أي موقع، يجب أن نفهم بنيته. صفحات الويب مبنية بلغة اسمها HTML (HyperText Markup Language). هذه اللغة تستخدم وسوم (Tags) لتعريف العناصر المختلفة في الصفحة:
<h1>,<h2>… للعناوين الرئيسية والفرعية.<p>للفقرات النصية.<a>للروابط (Links).<div>و<span>لتقسيم وتنظيم المحتوى.<img>للصور.
أفضل صديق لك في هذه المرحلة هو “أدوات المطور” (Developer Tools) في متصفحك (عادةً بالضغط على F12 أو Right-click > Inspect). تسمح لك هذه الأدوات برؤية كود الـ HTML لأي جزء من الصفحة بمجرد التأشير عليه بالماوس. هكذا نعرف “عنوان” المعلومة التي نبحث عنها.
مثال تطبيقي: استخراج الأخبار من موقع إخباري
لنفترض أننا نريد بناء سكربت يقوم باستخراج آخر الأخبار (العنوان، الوصف، والتاريخ) من قسم معين في موقع إخباري افتراضي، وحفظها في ملف CSV.
المرحلة 0: تجهيز البيئة
أولاً، نحتاج لتثبيت المكتبات اللازمة. افتح الطرفية (Terminal) واكتب الأمر التالي:
pip install requests beautifulsoup4
المرحلة 1: جلب الصفحة باستخدام Requests
سنقوم بإرسال طلب HTTP GET إلى رابط الموقع للحصول على محتوى الـ HTML.
import requests
# رابط الصفحة التي نريد استخراج البيانات منها
URL = "https://example-news-site.com/latest-news"
# من الأفضل دائماً إضافة User-Agent ليبدو طلبنا كأنه من متصفح حقيقي
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36"
}
try:
# إرسال الطلب معالجة أي خطأ في الاتصال
response = requests.get(URL, headers=headers, timeout=10)
response.raise_for_status() # هذا السطر يطلق خطأ إذا كان الرد ليس 200 OK
# معالجة الترميز لضمان عرض الحروف العربية بشكل صحيح
response.encoding = 'utf-8'
html_content = response.text
print("تم جلب الصفحة بنجاح!")
except requests.exceptions.RequestException as e:
print(f"حدث خطأ أثناء جلب الصفحة: {e}")
html_content = None
نصيحة من أبو عمر: لا تهمل أبداً الـ
User-Agentومعالجة الأخطاء (try...except). سكربت بدون معالجة أخطاء هو قنبلة موقوتة. ماذا لو انقطع الإنترنت أو كان الموقع لا يعمل؟ سينهار برنامجك. كن مستعداً دائماً للأسوأ.
المرحلة 2: تحليل الصفحة مع Beautiful Soup
الآن بعد أن حصلنا على محتوى الـ HTML، سنمرره إلى Beautiful Soup لتحليله.
from bs4 import BeautifulSoup
if html_content:
soup = BeautifulSoup(html_content, 'html.parser')
# الآن 'soup' هو كائن يمكننا من خلاله البحث في الصفحة
المرحلة 3: تحديد واستخراج العناصر (CSS Selectors)
هنا يأتي دور أدوات المطور (F12). بعد فحص الصفحة، اكتشفنا أن كل خبر موجود داخل وسم <article> له كلاس (class) اسمه news-item. بداخل كل مقال، العنوان موجود في وسم <h3>، والوصف في <p>، والتاريخ في <span> مع كلاس date.
سنستخدم الآن CSS Selectors، وهي طريقة قوية جداً لتحديد العناصر بناءً على الوسم، الكلاس، أو الـ ID.
# soup.select() ترجع قائمة بكل العناصر التي تطابق المحدد
articles = soup.select("article.news-item")
print(f"تم العثور على {len(articles)} مقالاً.")
news_list = []
for article in articles:
try:
# .select_one() يرجع أول عنصر يطابق المحدد
# .text للحصول على النص داخل الوسم مع تنظيفه
title = article.select_one("h3").text.strip()
description = article.select_one("p.summary").text.strip()
date = article.select_one("span.date").text.strip()
news_list.append({
"title": title,
"description": description,
"date": date
})
except AttributeError:
# هذا لمعالجة حالة وجود مقال بنيته مختلفة (مثلاً بدون وصف)
print("تم تخطي مقال بسبب عدم اكتمال بنيته.")
continue
المرحلة 4: حفظ البيانات في ملف CSV
أخيراً، سنقوم بحفظ البيانات التي جمعناها في ملف CSV لسهولة استخدامها لاحقاً في برامج مثل Excel أو لتحليلها برمجياً.
import csv
import time
# ... (الكود السابق يأتي هنا) ...
if news_list:
# اسم الملف الذي سنحفظ فيه البيانات
filename = "news_data.csv"
# نفتح الملف مع تحديد الترميز utf-8-sig ليتوافق مع اللغة العربية في Excel
with open(filename, mode='w', newline='', encoding='utf-8-sig') as file:
# نحدد أسماء الأعمدة
fieldnames = ["title", "description", "date"]
writer = csv.DictWriter(file, fieldnames=fieldnames)
writer.writeheader() # كتابة سطر العناوين
writer.writerows(news_list) # كتابة كل البيانات
print(f"تم حفظ البيانات بنجاح في الملف {filename}")
# إضافة تأخير بسيط احتراماً للموقع إذا كنا سنكرر العملية
time.sleep(5) # انتظر 5 ثواني قبل الطلب التالي
المستوى المتقدم: التعامل مع الصفحات الديناميكية (JavaScript)
ماذا لو كانت البيانات التي نريدها لا تظهر في الـ HTML الأولي؟ العديد من المواقع الحديثة تستخدم JavaScript لتحميل المحتوى بعد تحميل الصفحة (مثلاً عند التمرير لأسفل “Infinite Scroll” أو عند الضغط على زر “عرض المزيد”).
هنا، مكتبة Requests لا تكفي لأنها لا تشغل JavaScript. الحل هو استخدام مكتبة Selenium.
ما هي Selenium؟
Selenium هي أداة تسمح لك بالتحكم في متصفح ويب حقيقي (مثل Chrome أو Firefox) بشكل برمجي. كأنك أعطيت الكود الخاص بك يداً ورأساً ليستطيع أن يفتح المتصفح، يكتب في الحقول، يضغط على الأزرار، وينتظر تحميل المحتوى، ثم يعطيك الـ HTML النهائي للصفحة.
لتثبيتها:
pip install selenium
ستحتاج أيضاً لتحميل ما يسمى بـ WebDriver الخاص بالمتصفح الذي تريد التحكم به (مثلاً ChromeDriver).
مثال سريع لاستخدام Selenium
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager
import time
# Selenium ستقوم بتثبيت وإدارة الـ-WebDriver تلقائياً
service = Service(ChromeDriverManager().install())
driver = webdriver.Chrome(service=service)
URL = "https://example-dynamic-site.com"
driver.get(URL)
# انتظر بضع ثوانٍ للسماح لـ JavaScript بتحميل المحتوى
time.sleep(5)
# يمكنك أيضاً تنفيذ أوامر مثل التمرير لأسفل
# driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
# الآن، احصل على مصدر الصفحة بعد تنفيذ JavaScript
html_content_dynamic = driver.page_source
# أغلق المتصفح
driver.quit()
# الآن يمكنك تمرير html_content_dynamic إلى Beautiful Soup كما فعلنا سابقاً
soup = BeautifulSoup(html_content_dynamic, 'html.parser')
# ... أكمل عملية الاستخراج
نصيحة من أبو عمر: لا تستخدم
Seleniumإلا عند الضرورة القصوى. إنها أبطأ بكثير وتستهلك موارد أكبر منRequests. دائماً ابدأ بـRequests، وإذا وجدت أن المحتوى الذي تريده غير موجود، عندها فقط انتقل إلىSelenium.
الخلاصة: الكلمة الأخيرة 📝
يا جماعة، اليوم تعلمنا أساسيات قوة عظيمة في عالم البرمجة. رحلتنا بدأت من مشكلة بسيطة (مقارنة أسعار) وانتهت ببناء سكربت متكامل قادر على تصفح الويب، فهم بنيته، استخراج بياناته، وحفظها بشكل منظم. تذكروا دائماً أن هذه القوة تأتي مع مسؤولية كبيرة. كونوا مبرمجين أخلاقيين، محترفين، ومحترمين لجهود الآخرين.
الـ Web Scraping هو بحر واسع، وما تعلمناه اليوم هو مجرد البداية. هناك تحديات أخرى ستواجهونها مثل التعامل مع الـ CAPTCHA، وتسجيل الدخول، والـ APIs المخفية. لكن بالأساس الذي بنيناه اليوم، أنتم جاهزون لمواجهة أي تحدٍ. لا تخافوا من التجربة والخطأ، فمنها يأتي التعلم الحقيقي.
يلا، شدوا حيلكم، والعالم الرقمي كله بين يديكم لاستكشافه! بالتوفيق.