سحب البيانات (Web Scraping) وتحويل المواقع الجامدة إلى APIs.
يا هلا بالشباب! اليوم بنتكلم عن موضوع مهم ومفيد جداً: سحب البيانات من المواقع (Web Scraping) وكيف نحول أي موقع جامد ما فيه API إلى API خاص فينا. الموضوع بسيط لو ركزت معي.
إيش هو الـ Web Scraping وليش نحتاجه؟
بكل بساطة، الـ Web Scraping هو عملية استخراج البيانات من صفحات الويب. تخيل عندك موقع ما عنده API رسمي، بس أنت تحتاج بيانات معينة منه، مثلاً أسعار منتجات، أخبار، أو معلومات جامعية. هنا يجي دور الـ Scraping، كأنك تقرأ الموقع ببرنامج وتطلع منه اللي تبيه.
ملاحظة: أغلب المواقع الجامدة اللي ما فيها تفاعل كبير أو تحديثات متكررة، تكون مثالية لعملية سحب البيانات منها.
الأدوات اللي بنستخدمها (بايثون طبعاً!)
بايثون هو ملك الـ Scraping. بنستخدم مكتبتين أساسيتين:
requests: عشان نجيب محتوى صفحة الويب.BeautifulSoup: عشان نحلل الـ HTML ونطلع منه البيانات اللي نبيها بسهولة.
قبل ما نبدأ، تأكد إنك مثبتهم:
pip install requests beautifulsoup4 flask
مثال عملي: سحب عنوان صفحة
خلنا نقول بنسحب عنوان صفحة من موقع بسيط. هذا مثال سريع:
import requests
from bs4 import BeautifulSoup
url = 'http://quotes.toscrape.com/' # موقع تجريبي للسكرابينج
try:
response = requests.get(url)
response.raise_for_status() # عشان نتأكد إن الطلب نجح (status 200)
soup = BeautifulSoup(response.text, 'html.parser')
# مثال: سحب عنوان الصفحة
page_title = soup.find('h1').text.strip()
print(f"عنوان الصفحة: {page_title}")
# مثال آخر: سحب أول اقتباس
first_quote = soup.find('div', class_='quote').find('span', class_='text').text.strip()
print(f"أول اقتباس: {first_quote}")
except requests.exceptions.RequestException as e:
print(f"حدث خطأ أثناء الاتصال: {e}")
except Exception as e:
print(f"حدث خطأ آخر: {e}")
نصيحة: دائماً استخدم
try-exceptعشان تتعامل مع الأخطاء المحتملة زي مشاكل الاتصال بالإنترنت أو الأخطاء في تحليل الصفحة.
تحويل الموقع الجامد إلى API باستخدام Flask
الحين جينا للجزء الحلو! كيف نخلي الكود اللي سويناه فوق يصير API؟ بنستخدم Flask، إطار عمل بايثون خفيف وسهل.
الفكرة هي إننا بنسوي دالة داخل Flask تسوي الـ Scraping، وبعدين ترجع البيانات بصيغة JSON.
from flask import Flask, jsonify
import requests
from bs4 import BeautifulSoup
app = Flask(__name__)
@app.route('/scrape-quotes', methods=['GET'])
def scrape_quotes_api():
url = 'http://quotes.toscrape.com/'
quotes_data = []
try:
response = requests.get(url)
response.raise_for_status()
soup = BeautifulSoup(response.text, 'html.parser')
# سحب كل الاقتباسات الموجودة في الصفحة
quotes = soup.find_all('div', class_='quote')
for quote in quotes:
text = quote.find('span', class_='text').text.strip()
author = quote.find('small', class_='author').text.strip()
tags = [tag.text for tag in quote.find('div', class_='tags').find_all('a', class_='tag')]
quotes_data.append({
'text': text,
'author': author,
'tags': tags
})
return jsonify(quotes_data)
except requests.exceptions.RequestException as e:
return jsonify({'error': f'Request failed: {e}'}), 500
except Exception as e:
return jsonify({'error': f'Scraping failed: {e}'}), 500
if __name__ == '__main__':
app.run(debug=True)
بعد ما تشغل هذا الكود (python your_script_name.py)، تقدر تفتح متصفحك أو تستخدم أداة زي Postman وتطلب هذا الرابط:
http://127.0.0.1:5000/scrape-quotes
وراح تشوف JSON فيه كل الاقتباسات! مبروك، صار عندك API لموقع جامد.
نقاط مهمة لازم تنتبه لها (أخلاقيات الـ Scraping)
- ملف
robots.txt: هذا الملف يقول لك إيش المسموح وغير المسموح تسحبه من الموقع. دائماً شيك عليه (yourwebsite.com/robots.txt). - معدل الطلبات (Rate Limiting): لا تسوي طلبات كثيرة وبسرعة خرافية للموقع عشان ما تحمل عليه وتسبب له مشاكل، وممكن يحظرون الـ IP حقك. حط تأخير بين الطلبات (
time.sleep()). - وكيل المستخدم (User-Agent): بعض المواقع تحجب الطلبات اللي ما فيها
User-Agentحقيقي. خلي الـrequestsيرسلUser-Agentعشان تبين إنك متصفح عادي. - شروط الاستخدام (Terms of Service): دائماً اقرأ شروط استخدام الموقع. بعض المواقع تمنع الـ Scraping تماماً.
- التغييرات في بنية الموقع: المواقع تتغير. لو تغيرت بنية الـ HTML، الكود حقك ممكن يخرب ويحتاج تحديث.
الخلاصة
الـ Web Scraping أداة قوية جداً تقدر تستخدمها عشان تستفيد من البيانات الموجودة في المواقع، وتحولها لـ APIs سهلة الاستخدام. بس أهم شيء تستخدمها بمسؤولية وأخلاقية عشان ما تسبب مشاكل لنفسك أو للموقع اللي تسحب منه البيانات. بالتوفيق يا بطل!