{ "cells": [ { "cell_type": "raw", "metadata": { "vscode": { "languageId": "raw" } }, "source": [ "---\n", "title: \"مسألة سحب البيانات\"\n", "og:title: requests_ex\n", "toc: true\n", "format:\n", " html: default\n", "---\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "في هذا التمرين ستتعلّم إرسال طلبات HTTP عبر الإنترنت باستعمال مكتبة `requests`، ثم تطبّق ذلك على واجهة برمجية تختارها بنفسك. اقرأ الأقسام بالترتيب، شغّل الخلايا واقرأ المخرجات، ثم انتقل إلى المسألة في القسم الأخير.\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "[تحميل الدفتر](https://raw.githubusercontent.com/HassanAlgoz/python/main/book/chapters/ch7-computer-and-world/exercise_7.ipynb)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "أضِف المكتبة إلى بيئتك (راجع [إعداد بيئة التطوير](../ch0-intro/lesson_setup.ipynb)؛ مثلاً بـ `uv add requests` محلياً أو `! uv pip install requests` على Colab)، ثم استوردها في الخلية التالية.\n" ] }, { "cell_type": "code", "execution_count": null, "id": "b91d2c6d", "metadata": { "vscode": { "languageId": "python" } }, "outputs": [], "source": [ "# ! uv pip install requests" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "vscode": { "languageId": "python" } }, "outputs": [], "source": [ "import requests" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## مثال: PoetryDB\n", "\n", "في هذا القسم طلب بسيط إلى خدمة شِعر جاهزة؛ شغّل الخلايا وتابع كيف تتحوّل الاستجابة إلى بيانات بايثون (`json`).\n" ] }, { "cell_type": "code", "execution_count": null, "id": "1d8650ef", "metadata": { "vscode": { "languageId": "python" } }, "outputs": [], "source": [ "response = requests.get(\"https://poetrydb.org/author/Emily%20Dickinson/title\")\n" ] }, { "cell_type": "code", "execution_count": null, "id": "ab8b5116", "metadata": { "vscode": { "languageId": "python" } }, "outputs": [], "source": [ "data = response.json()\n", "print(data)" ] }, { "cell_type": "code", "execution_count": null, "id": "022b28b5", "metadata": { "vscode": { "languageId": "python" } }, "outputs": [], "source": [ "response = requests.get(\"https://poetrydb.org/author,title/Shakespeare;Sonnet\")\n", "data = response.json()\n", "print(data)" ] }, { "cell_type": "markdown", "id": "c34a56ab", "metadata": {}, "source": [ "## مثال: تنزيل ملفات من GitHub" ] }, { "cell_type": "markdown", "id": "5c4c3615", "metadata": {}, "source": [ "يلزمنا GitHub لتحميل الملفات بالنمط التالي:\n", "\n", "- إن كنا نتصفح الملف على هذا المسار: `https://github.com/HassanAlgoz/python/blob/main/book/datasets/students.csv`\n", "- فوجب تنزيله عبر هذا المسار: `https://raw.githubusercontent.com/HassanAlgoz/python/main/book/datasets/students.csv`" ] }, { "cell_type": "markdown", "id": "8faee5c0", "metadata": {}, "source": [ "في المثال التالي نعرّف دالة تحوّل رابط صفحة GitHub (عرض المتصفّح) إلى رابط **raw** مناسب للتنزيل. نفّذ الخلايا وتابع التحويل ثم محتوى الملف المنزَّل.\n" ] }, { "cell_type": "code", "execution_count": null, "id": "bba8337d", "metadata": { "vscode": { "languageId": "python" } }, "outputs": [], "source": [ "from urllib.parse import urlparse\n", "\n", "def github_convert_url(url: str) -> str:\n", " parsed = urlparse(url)\n", " if parsed.hostname and \"githubusercontent\" in parsed.hostname:\n", " return url\n", " # /owner/repo/blob/branch/... → /owner/repo/branch/...\n", " path = parsed.path.replace(\"/blob\", \"\", 1)\n", " return \"https://raw.githubusercontent.com\" + path\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "ثم نعرّف دالة ترسل الطلب بعد تحويل الرابط إلى صيغة `raw` المناسبة:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "vscode": { "languageId": "python" } }, "outputs": [], "source": [ "def github_request_file(url: str):\n", " x = github_convert_url(url)\n", " return requests.get(x)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "vscode": { "languageId": "python" } }, "outputs": [], "source": [ "response1 = github_request_file(\n", " url=\"https://github.com/HassanAlgoz/python/blob/main/book/datasets/students.csv\"\n", ")" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "vscode": { "languageId": "python" } }, "outputs": [], "source": [ "print(response1.text)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "ونفس النتيجة لو جربنا بالرابط المباشر للتنزيل، لأننا تعاملنا مع هذه الحالة:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "vscode": { "languageId": "python" } }, "outputs": [], "source": [ "response2 = github_request_file(\n", " url=\"https://raw.githubusercontent.com/HassanAlgoz/python/main/book/datasets/students.csv\"\n", ")" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "vscode": { "languageId": "python" } }, "outputs": [], "source": [ "print(response2.text)" ] }, { "cell_type": "markdown", "id": "6152bfe2", "metadata": {}, "source": [ "## مثال: طلب صور من موقع القطط\n", "\n", "هنا نطلب JSON يصف صورة عشوائية؛ يمكن تشغيل المثال بدون مفتاح ضمن حدود الخدمة، أو تعيين المتغير البيئي `CAT_API_KEY` إن وفّرت مفتاحًا من الموقع.\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "vscode": { "languageId": "python" } }, "outputs": [], "source": [ "import os\n", "\n", "# الطلب يعمل بدون مفتاح ضمن حدود معيّنة؛ إن رغبت بمفتاح مجاني راجع https://thecatapi.com/\n", "headers = {}\n", "if key := os.environ.get(\"CAT_API_KEY\"):\n", " headers[\"x-api-key\"] = key\n", "\n", "response = requests.get(\n", " url=\"https://api.thecatapi.com/v1/images/search\",\n", " headers=headers,\n", ")\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "vscode": { "languageId": "python" } }, "outputs": [], "source": [ "print(response.text)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "vscode": { "languageId": "python" } }, "outputs": [], "source": [ "data = response.json()\n", "data[0][\"url\"]" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "vscode": { "languageId": "python" } }, "outputs": [], "source": [ "from IPython.display import Image, display\n", "\n", "# display(Image(url=data[0][\"url\"]))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## المسألة: التطبيق على إحدى الواجهات البرمجية\n", "\n", "اختر واجهة برمجية واحدة وحقّق بها **مهمة واحدة** واضحة (مثلاً: جلب بيانات، أو بحث، أو صورة). في موقع المزوّد ابحث عن **API Documentation** أو **Developers** أو **Quick Start**؛ هناك تجد **نقاط الالتقاء** (Endpoints) والمعاملات المطلوبة.\n", "\n", "**استعمل إحدى الواجهات التالية** (أو واجهة أخرى بموافقة المدرّس):\n", "\n", "- [website screenshot | abstractapi](https://www.abstractapi.com/api/website-screenshot-api)\n", "- [poetrydb](https://poetrydb.org/index.html)\n", "- [newton](https://newton.vercel.app/)\n", "- [alquran-cloud](https://alquran.cloud/api)\n", "- [Wikipedia](https://pypi.org/project/Wikipedia-API/)\n", "- [nasa](https://api.nasa.gov/)\n", "- [arxiv](https://info.arxiv.org/help/api/user-manual.html)\n", "- [Telegram](https://core.telegram.org/)\n", "- [Discord](https://discord.com/developers/docs/intro)\n", "\n", "قائمة أوسع (قد يتعطّل بعضها): [public-apis](https://github.com/public-apis/public-apis).\n", "\n", "للبحث عن فكرة: اكتب في محرك البحث ما تريد إنجازه + `API`؛ مثلاً `Google Maps API`.\n", "\n", "**ملاحظة:** قد تحتاج تسجيلًا للحصول على مفتاح، أو رصيدًا مدفوعًا — كل ذلك يُبيّن في مرجع المزوّد.\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "vscode": { "languageId": "python" } }, "outputs": [], "source": [ "# طلباتك إلى الواجهة التي اخترتها، ثم معالجة الاستجابة (json() أو .text)\n", "pass # اكتب هنا\n" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" } }, "nbformat": 4, "nbformat_minor": 5 }