ممارسات الاستخلاص المسؤولة
الامتثال لـ robots.txt، وترويسات user agent، وتأخير الطلبات، والتخزين المؤقت
ممارسات الاستخلاص المسؤولة درس مجاني في AI Agents على CoddyKit. هذا هو الدرس 4 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في AI Agents، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة AI Agents 4 دروس في المجموع.
أهمية استخراج البيانات من الويب باحترام
قد يجهد استخراج البيانات من الويب الخوادم، ويخالف شروط الخدمة، ويتسبب في حظر عنوان IP الخاص بالوكيل. يحترم من يستخرجون البيانات بمسؤولية حدود معدل الطلبات، ويعرّفون بأنفسهم، ويلتزمون بالقواعد التي تنشرها المواقع.
يغطي هذا الدرس الأدوات والتقنيات اللازمة لاستخراج البيانات بطريقة أخلاقية ومستدامة.
التحقق من robots.txt
يمكن لكل موقع ويب نشر ملف robots.txt يحدد المسارات التي يُسمح للوكلاء الآليين بالوصول إليها أو يُمنعون من الوصول إليها. تتضمن مكتبة Python القياسية urllib.robotparser لتحليل هذا الملف.
تحققوا دائمًا من robots.txt قبل استخراج البيانات من أي موقع.
import urllib.robotparser
rp = urllib.robotparser.RobotFileParser()
rp.set_url('https://example.com/robots.txt')
rp.read()
# Check if our bot can fetch a specific path
can_fetch = rp.can_fetch('MyAgent/1.0', 'https://example.com/public-data')
print(f'Can fetch: {can_fetch}') # True or False
cannot_fetch = rp.can_fetch('*', 'https://example.com/private/admin')
print(f'Admin allowed: {cannot_fetch}') # Often Falseتعيين User-Agent وصفي
يحدد رأس HTTP User-Agent الجهة التي تجري الطلب. يتيح User-Agent الصادق لمسؤولي الموقع معرفة ماهية برنامجكم الآلي وكيفية التواصل معكم عند حدوث مشكلات. أما التنكّر في هيئة متصفح لتجاوز عمليات الحظر فيثير مخاوف أخلاقية.
import httpx
headers = {
# Honest, descriptive User-Agent
'User-Agent': 'MyResearchBot/1.0 (contact: me@example.com; purpose: academic research)'
}
response = httpx.get(
'https://example.com/data',
headers=headers,
timeout=10.0
)
print(response.status_code)تحديد معدل الطلبات باستخدام time.sleep()
قد يؤدي إرسال مئات الطلبات في الثانية إلى إرهاق الخادم، وغالبًا ما يُعامل كهجوم لحجب الخدمة. أضيفوا فواصل زمنية بين الطلبات باستخدام time.sleep(). استخدموا random.uniform() لجعل التأخير أقل آلية وأكثر شبهًا بالسلوك البشري.
import time
import random
import httpx
urls = [
'https://example.com/page/1',
'https://example.com/page/2',
'https://example.com/page/3'
]
for url in urls:
response = httpx.get(url, timeout=10.0)
print(f'Fetched {url}: {response.status_code}')
# Wait between 1 and 3 seconds before the next request
delay = random.uniform(1, 3)
print(f'Sleeping {delay:.1f}s...')
time.sleep(delay)احترام رؤوس Retry-After
عندما يستجيب الخادم بالرمز 429 Too Many Requests، فإنه يضمّن غالبًا رأس Retry-After الذي يحدد عدد الثواني الواجب انتظارها. ينبغي لوكيلكم قراءة هذه القيمة والالتزام بها بدلًا من إعادة المحاولة فورًا.
import time
import httpx
def fetch_with_retry(url: str) -> httpx.Response:
while True:
response = httpx.get(url, timeout=10.0)
if response.status_code == 429:
retry_after = int(response.headers.get('Retry-After', 5))
print(f'Rate limited. Waiting {retry_after}s...')
time.sleep(retry_after)
continue # retry
response.raise_for_status()
return responseتخزين الاستجابات مؤقتًا لتجنب جلبها مجددًا
تخزّن requests-cache استجابات HTTP مؤقتًا على القرص تلقائيًا. إذا احتاج وكيلكم إلى جلب عنوان URL نفسه عدة مرات، مثلًا أثناء التطوير أو إعادة التشغيل، فستُعاد الاستجابات المخزنة مؤقتًا فورًا من دون إرسال طلب إلى الخادم.
# pip install requests-cache
import requests_cache
# Install the cache globally — cached responses expire after 1 hour
requests_cache.install_cache(
'agent_cache',
backend='sqlite',
expire_after=3600 # seconds
)
import requests
# First call: fetches from network and caches
response = requests.get('https://api.example.com/data')
print(response.from_cache) # False
# Second call: returns cached result instantly
response2 = requests.get('https://api.example.com/data')
print(response2.from_cache) # Trueالتخزين المؤقت اليدوي القائم على الملفات باستخدام httpx
إذا كنتم تفضلون عدم استخدام requests-cache، فسيعمل مخزن مؤقت بسيط قائم على الملفات بشكل جيد. خزّنوا الاستجابات في ملفات JSON مفهرسة بتجزئة عنوان URL، وأعيدوا تحميلها إذا كان الملف لا يزال حديثًا بما يكفي.
import hashlib
import json
import os
import time
import httpx
CACHE_DIR = '/tmp/agent_cache'
os.makedirs(CACHE_DIR, exist_ok=True)
def cached_get(url: str, ttl_seconds: int = 3600) -> dict:
key = hashlib.md5(url.encode()).hexdigest()
cache_file = os.path.join(CACHE_DIR, key + '.json')
if os.path.exists(cache_file):
age = time.time() - os.path.getmtime(cache_file)
if age < ttl_seconds:
with open(cache_file) as f:
return json.load(f)
response = httpx.get(url, timeout=10.0)
response.raise_for_status()
data = response.json()
with open(cache_file, 'w') as f:
json.dump(data, f)
return dataقراءة شروط الخدمة
قبل استخراج البيانات من أي موقع، اقرأوا شروط الخدمة الخاصة به. تحظر كثير من المواقع صراحةً الوصول الآلي أو الاستخدام التجاري لبياناتها. قد يؤدي انتهاك ToS إلى اتخاذ إجراءات قانونية، وليس فقط إلى حظر عنوان IP.
إذا وُجدت واجهة API رسمية، فاختاروها دائمًا بدلًا من استخراج HTML، فهي أسرع وأكثر استقرارًا وأمانًا من الناحية القانونية.
التراجع الأسي عند حدوث الأخطاء
عند فشل أحد الطلبات، لا تعيدوا المحاولة فورًا. استخدموا التراجع الأسي: انتظروا ثانية واحدة، ثم ثانيتين، ثم 4 ثوانٍ، وهكذا. يتجنب ذلك إرهاق خادم يواجه مشكلات، وهو نمط احترافي في الوكلاء المستخدمة في بيئات الإنتاج.
import time
import httpx
def fetch_with_backoff(url: str, max_retries: int = 4) -> dict:
for attempt in range(max_retries):
try:
response = httpx.get(url, timeout=10.0)
response.raise_for_status()
return response.json()
except (httpx.HTTPStatusError, httpx.RequestError) as e:
if attempt == max_retries - 1:
raise
wait = 2 ** attempt # 1, 2, 4, 8 seconds
print(f'Attempt {attempt+1} failed: {e}. Retrying in {wait}s...')
time.sleep(wait)
return {}استخراج ما تحتاجون إليه فقط
قلّلوا الحمل على الخادم بجلب ما يحتاج إليه وكيلكم فعلًا فقط. تجنبوا تنزيل صفحات كاملة عندما تعيد نقطة نهاية صغيرة لواجهة API البيانات نفسها. استخدموا طلبات HEAD للتحقق مما إذا كان أحد الموارد قد تغيّر قبل جلب المتن الكامل.
import httpx
def has_page_changed(url: str, last_etag: str = None) -> bool:
headers = {}
if last_etag:
headers['If-None-Match'] = last_etag
response = httpx.head(url, headers=headers, timeout=5.0)
if response.status_code == 304: # Not Modified
return False
new_etag = response.headers.get('ETag')
print(f'New ETag: {new_etag}')
return Trueملخص قواعد استخراج البيانات باحترام
قائمة تحقق سريعة قبل أن يبدأ وكيلكم استخراج البيانات من أي موقع:
- تحققوا من
robots.txtوالتزموا بقواعد المنع - عيّنوا
User-Agentصادقًا ووصفيًا - أضيفوا فواصل زمنية عشوائية بين الطلبات (
time.sleep(random.uniform(1,3))) - التزموا برؤوس
Retry-Afterعند تلقي استجابات 429 - خزّنوا الاستجابات مؤقتًا لتجنب عمليات الجلب المتكررة
- اقرؤوا شروط خدمة الموقع
- فضّلوا واجهات API الرسمية على استخراج HTML عندما تكون متاحة
اختبار المعرفة: استخراج البيانات باحترام
اختبروا فهمكم لممارسات استخراج البيانات الأخلاقية والمحترمة.
مراجعة: ممارسات استخراج البيانات باحترام
لديكم الآن مجموعة أدوات متكاملة لاستخراج البيانات بمسؤولية:
- استخدام
robotparserللتحقق مما يُسمح لكم بالوصول إليه - رؤوس
User-Agentوصفية تعرّف ببرنامجكم الآلي - استخدام
time.sleep(random.uniform(1,3))بين الطلبات - استخدام
requests-cacheأو التخزين المؤقت اليدوي لتجنب عمليات الجلب المكررة - التراجع الأسي لمعالجة الأخطاء
- الوعي القانوني: تحققوا دائمًا من ToS
يسهم استخراج البيانات بمسؤولية في بناء ويب أكثر صحة، ويُبقي وكلاءكم قيد التشغيل من دون حظر.
الأسئلة الشائعة
هل درس «ممارسات الاستخلاص المسؤولة» مجاني؟
نعم — نص درس «ممارسات الاستخلاص المسؤولة» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة AI Agents، انتقل إلى CoddyKit PRO. تتضمن دورة AI Agents 4 دروس في المجموع.
ماذا ستتعلم في «ممارسات الاستخلاص المسؤولة»؟
الامتثال لـ robots.txt، وترويسات user agent، وتأخير الطلبات، والتخزين المؤقت تتمرن على AI Agents مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.
هل أحتاج إلى خبرة سابقة لأبدأ AI Agents؟
لا تُشترط خبرة سابقة. AI Agents على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 4 من أصل 4.
كم من الوقت يستغرق درس «ممارسات الاستخلاص المسؤولة»؟
معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.
هل يمكنني كتابة وتشغيل أكواد في درس AI Agents هذا؟
نعم. كل درس في AI Agents يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.
جميع الدروس في هذه الدورة
- عملاء HTTP للوكلاء: httpx وrequests
- تحليل HTML باستخدام BeautifulSoup
- التعامل مع ترقيم الصفحات والمحتوى الديناميكي
- ممارسات الاستخلاص المسؤولة