طَبِّقْهاتعلّم المبدأ، وطبّقه بيدكمقرر 244 · علم البيانات للويب
الدرس 4 · الوحدة 2: استخراج البيانات من مصادر الويب

من HTML إلى بيانات: جداول الويب

كيف نحرّر البيانات المحبوسة في صفحات HTML إلى جداول نحلّلها؟ ⏱ نحو 40 دقيقة.

بعد هذا الدرس ستستطيع أن:
  • تحلّل HTML بـ BeautifulSoup.
  • تختار العناصر بالأصناف select/select_one.
  • تبني DataFrame من جدول HTML.
  • تحوّل النصّ المستخرج إلى أرقام، وتراعي الإذن.

١الصفحة مليئة ببيانات

كثير من بيانات الويب محبوسٌ داخل صفحات HTML: جداول الأسعار، نتائج المباريات، إحصاءات لوحات التحكم. استخراجها يسمّى الكشط Web Scraping. أداتنا BeautifulSoup: تحلّل HTML إلى شجرة نبحث فيها بالوسوم والأصناف ثم نبني منها جدولًا.

٢قراءة عناصر متفرّقة

نحلّل HTML بـ BeautifulSoup(html, "html.parser")، ثم نختار العناصر: select يجد كل المطابق، وselect_one أوّله، و.text النصّ داخله:

main.py
from bs4 import BeautifulSoup html = """<ul>  <li class="prod"><span class="name">سماعة</span><span class="price">120</span></li>  <li class="prod"><span class="name">كاميرا</span><span class="price">210</span></li></ul>""" soup = BeautifulSoup(html, "html.parser")for item in soup.select(".prod"):    name = item.select_one(".name").text    price = int(item.select_one(".price").text)    print(name, "=", price, "ريال")
Shell×
>>> %Run main.py
سماعة = 120 ريال
كاميرا = 210 ريال
>>>

نعتمد على الأصناف (class) لا على ترتيب العناصر؛ فالترتيب يتغيّر مع تحديث الصفحة، والصنف أثبت.

٣من جدول HTML إلى DataFrame

الجدول حالة شائعة: نمرّ على صفوف <tr> ونجمع خلاياها، ثم نسلّمها إلى Pandas:

main.py
from bs4 import BeautifulSoupimport pandas as pd html = """<table>  <tr><th>page</th><th>views</th><th>avg_time</th></tr>  <tr><td>home</td><td>1200</td><td>12</td></tr>  <tr><td>products</td><td>860</td><td>45</td></tr>  <tr><td>checkout</td><td>210</td><td>90</td></tr></table>""" soup = BeautifulSoup(html, "html.parser")rows = soup.select("tr")header = [th.text for th in rows[0].select("th")]data = [[td.text for td in r.select("td")] for r in rows[1:]] df = pd.DataFrame(data, columns=header)df["views"] = df["views"].astype(int)       # النصّ إلى رقمprint(df)print("إجمالي المشاهدات:", df["views"].sum())
Shell×
>>> %Run main.py
page views avg_time
0 home 1200 12
1 products 860 45
2 checkout 210 90
إجمالي المشاهدات: 2270
>>>

لاحظ astype(int): كل ما يُستخرج من HTML نصّ، فنحوّل الأعمدة الرقمية صراحةً قبل الحساب.

توقّع وتحقّق

مكتبة تحليل HTML في بايثون:

select_one يعيد:

كل ما يُستخرج من HTML نوعه:

قبل كشط موقع يجب:

الخلاصة

تحدٍّ برمجي: اكشط جدولًا

متوسط

حلّل جدول HTML التالي بـ BeautifulSoup، وابنِ منه إطارًا، ثم اطبع عدد المدن ومجموع المبيعات.

المطلوب:
  • استخرج صفوف الجدول وابنِ DataFrame بعمودي city وsales.
  • اطبع عدد المدن ثم مجموع sales (بعد تحويله لرقم).

ابدأ من هذا الكود، واضغط ▶ شغّل هنا لتكتب حلّك وتجرّبه مباشرة:

main.py
from bs4 import BeautifulSoupimport pandas as pdhtml = """<table>  <tr><th>city</th><th>sales</th></tr>  <tr><td>Riyadh</td><td>300</td></tr>  <tr><td>Jeddah</td><td>250</td></tr>  <tr><td>Dammam</td><td>180</td></tr></table>"""# ابنِ الإطار ثم اطبع عدد المدن ومجموع المبيعات
المطلوب×
3
730
💡 تلميح 1
اجمع خلايا كل صفّ: [td.text for td in r.select("td")].
💡 تلميح 2
حوّل العمود: df["sales"].astype(int) قبل الجمع.

حاول بنفسك أولًا؛ للمسألة أكثر من حلّ صحيح.

main.py
from bs4 import BeautifulSoupimport pandas as pdhtml = """<table>  <tr><th>city</th><th>sales</th></tr>  <tr><td>Riyadh</td><td>300</td></tr>  <tr><td>Jeddah</td><td>250</td></tr>  <tr><td>Dammam</td><td>180</td></tr></table>"""soup = BeautifulSoup(html, "html.parser")rows = soup.select("tr")data = [[td.text for td in r.select("td")] for r in rows[1:]]df = pd.DataFrame(data, columns=["city", "sales"])df["sales"] = df["sales"].astype(int)print(len(df))print(int(df["sales"].sum()))
انتقل إلى تقييم الدرساختيار من متعدد، وصح وخطأ، وأكمل الفراغ، وتتبّع الناتج.ابدأ التقييم ←

📝 معلم؟ أرسل ملاحظة للمؤلف عن هذا الدرس