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

سجلّات الخادم: من نصّ إلى جدول

السلوك الحقيقي مكتوبٌ في السجلّات؛ كيف نحوّله من نصٍّ خام إلى جدول؟ ⏱ نحو 45 دقيقة.

بعد هذا الدرس ستستطيع أن:
  • تدرك قيمة سجلّات الخادم للسلوك.
  • تقطّع السجلّ المنتظم بـ split.
  • تستخرج الحقول من السجلّ المعقّد بـ Regex و str.extract.
  • تحوّل الأعمدة الرقمية وتكتشف الأخطاء.

١كنزٌ في السجلّات

كل خادم ويب يكتب سجلًّا: سطرٌ لكل طلب فيه عنوان الزائر، والفعل، والمسار، ورمز الحالة، والزمن. هذه أثمن بيانات السلوك، لكنها نصّ خام لا جدول. مهمّتنا تحويلها إلى DataFrame.

٢التقطيع البسيط بـ split

حين تكون الحقول مفصولة بمسافات منتظمة، يكفي split لكل سطر:

main.py
log = """192.168.1.10 - GET /home 200 120192.168.1.11 - GET /products 200 340192.168.1.10 - POST /cart 201 90192.168.1.12 - GET /missing 404 20192.168.1.11 - GET /checkout 200 510"""rows = []for line in log.strip().split("\n"):    ip, _, method, path, status, ms = line.split()    rows.append({"ip": ip, "method": method, "path": path,                 "status": int(status), "ms": int(ms)}) import pandas as pddf = pd.DataFrame(rows)print(df)print("متوسط الزمن:", df["ms"].mean(), "مللي")
Shell×
>>> %Run main.py
ip method path status ms
0 192.168.1.10 GET /home 200 120
1 192.168.1.11 GET /products 200 340
2 192.168.1.10 POST /cart 201 90
3 192.168.1.12 GET /missing 404 20
4 192.168.1.11 GET /checkout 200 510
متوسط الزمن: 216.0 مللي
>>>

٣التعابير النمطية للسجلّات المعقّدة

السجلّات الحقيقية غير منتظمة (أقواس، اقتباسات). عندها نستخدم التعبير النمطي Regex لاستخراج الحقول بدقّة. وstr.extract يطبّقه على عمودٍ كامل دفعةً:

main.py
log = """192.168.1.10 - GET /home 200 120192.168.1.11 - GET /products 200 340192.168.1.10 - POST /cart 201 90192.168.1.12 - GET /missing 404 20192.168.1.11 - GET /checkout 200 510"""import pandas as pds = pd.Series(log.strip().split("\n")) # نمط: IP ... method path status mspat = r"(?P<ip>\S+) - (?P<method>\w+) (?P<path>\S+) (?P<status>\d+) (?P<ms>\d+)"df = s.str.extract(pat)df["status"] = df["status"].astype(int)df["ms"] = df["ms"].astype(int) print(df[["method", "path", "status"]])print("طلبات فاشلة (>=400):", int((df["status"] >= 400).sum()))
Shell×
>>> %Run main.py
method path status
0 GET /home 200
1 GET /products 200
2 POST /cart 201
3 GET /missing 404
4 GET /checkout 200
طلبات فاشلة (>=400): 1
>>>

المجموعات المسمّاة (?P<name>...) تصير أسماء أعمدة تلقائيًّا. هذا أمتن تقطيعٍ للسجلّات.

توقّع وتحقّق

لتقطيع سطرٍ منتظم بمسافات:

لاستخراج حقول من نصّ غير منتظم:

str.extract مع مجموعات مسمّاة ينتج:

رمز 404 يعني:

الخلاصة

تحدٍّ برمجي: حلّل سجلًّا

متقدم

حوّل السجلّ إلى جدول، واطبع عدد الطلبات الفاشلة (status ≥ 400)، وأبطأ مسار (الأعلى ms).

المطلوب:
  • قطّع كل سطر إلى حقوله وابنِ DataFrame بأعمدة رقمية.
  • اطبع عدد الطلبات ≥ 400، ثم المسار الأبطأ.

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

main.py
log = """10.0.0.1 - GET /home 200 12010.0.0.2 - GET /api 500 80010.0.0.1 - GET /x 404 3010.0.0.3 - POST /pay 200 650"""import pandas as pd# ابنِ الجدول ثم اطبع عدد الفاشلة (>=400) وأبطأ مسار
المطلوب×
2
/api
💡 تلميح 1
قطّع كل سطر: ip, _, method, path, status, ms = line.split().
💡 تلميح 2
الأبطأ: df.loc[df["ms"].idxmax(), "path"].

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

main.py
log = """10.0.0.1 - GET /home 200 12010.0.0.2 - GET /api 500 80010.0.0.1 - GET /x 404 3010.0.0.3 - POST /pay 200 650"""import pandas as pdrows = []for line in log.strip().split("\n"):    ip, _, method, path, status, ms = line.split()    rows.append({"path": path, "status": int(status), "ms": int(ms)})df = pd.DataFrame(rows)print(int((df["status"] >= 400).sum()))print(df.loc[df["ms"].idxmax(), "path"])
انتقل إلى تقييم الدرساختيار من متعدد، وصح وخطأ، وأكمل الفراغ، وتتبّع الناتج.ابدأ التقييم ←

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