إذا كنت قد بحثت مؤخرًا عن "scrape IMDb with Python"، فغالبًا لاحظت شيئًا واحدًا: معظم الشروحات التي ستجدها لا تعمل. وليس المقصود أنها "قديمة قليلًا" فقط — بل لا تعمل على طريقة: تعطيك صفر نتائج ثم تغرقك بسيل من أخطاء NoneType.
خلال الأسابيع الماضية، جرّبت كل شرح رئيسي لاستخراج بيانات IMDb استطعت العثور عليه — GeeksforGeeks، وMedium، وfreeCodeCamp، ودفاتر Kaggle، وغير ذلك. ومن بين وُسمت لاستخراج بيانات IMDb، تشير الغالبية العظمى إلى محددات CSS (td.titleColumn وtd.ratingColumn) لم تعد موجودة منذ يونيو 2023، عندما أعاد IMDb تصميم صفحة Top 250. النتيجة؟ منتديات مليئة بالمطورين يسألون: "لماذا يعيد الكود الخاص بي نتائج فارغة؟" ومشرفو مكتبات شهيرة مثل بأنهم "لا يستطيعون فعل الكثير، سوى إصلاح كل محلل." هذا الدليل يشرح طريقتين في Python تعملان فعلًا الآن، وكيف تتعامل مع الترقيم والأخطاء الشائعة، ومتى لا تكون Python هي الأداة المناسبة أصلًا، وكيف تجعل أداة الاستخراج أكثر استقرارًا حتى لا تنضم إلى المقبرة.
ماذا يعني استخراج IMDb باستخدام Python؟
استخراج الويب هو عملية سحب البيانات من صفحات الويب برمجيًا — بدلًا من النسخ واللصق يدويًا، تكتب سكربت يقوم بالمهمة عنك. وعندما نتحدث عن "استخراج IMDb"، فنحن نعني سحب بيانات الأفلام المنظمة (العناوين، التقييمات، الأنواع، طاقم التمثيل، مدة العرض، أعداد الأصوات) من صفحات IMDb باستخدام Python.
الحزمة المعتادة في Python لهذا الغرض تتضمن ثلاث مكتبات: requests (لجلب صفحة الويب)، وBeautifulSoup (لتحليل HTML والعثور على البيانات)، وpandas (لتنظيم النتائج وتصديرها). وبعض الشروحات تستخدم أيضًا Selenium أو Playwright للصفحات التي تتطلب عرض JavaScript، لكن كما سترى، هناك طرق أسرع.
تنبيه مهم: كل ما في هذا الدليل تم التحقق منه وفق بنية صفحات IMDb الحالية حتى منتصف 2025. يغيّر IMDb أمورًا كثيرة تقريبًا كل 6–12 شهرًا، لذلك إذا كنت تقرأ هذا في 2027 فقد تكون بعض المحددات قد تغيرت. (وسأشرح لك أيضًا كيف تتعامل مع ذلك.)
لماذا تستخرج IMDb باستخدام Python؟ حالات استخدام واقعية
قبل أن تكتب سطرًا واحدًا من الكود، ما الذي ستفعله فعلًا ببيانات IMDb؟ الإجابة تعتمد على من أنت.
تُعد مجموعة بيانات مراجعات IMDb أحد أكثر معايير NLP استخدامًا في العالم — فقد جمعت الورقة الأساسية لـ Maas وآخرين (2011) ، ومجموعة البيانات مدمجة في TensorFlow وKeras وPyTorch. وعلى Hugging Face، تحصل مجموعة بيانات stanfordnlp/imdb على 213,321 تنزيلًا شهريًا وقد استُخدمت لتدريب أكثر من 1,500 نموذج. لذا إذا كنت تعمل في تعلم الآلة، فغالبًا أنت تعرف بيانات IMDb بالفعل.
لكن حالات الاستخدام تتجاوز البحث الأكاديمي بكثير:
| حالة الاستخدام | الفئة المستهدفة | الحقول المطلوبة |
|---|---|---|
| محرك توصية أفلام | علماء البيانات، الهواة | العناوين، الأنواع، التقييمات، طاقم التمثيل |
| استراتيجية محتوى منصات البث | فرق المنتج/المحتوى | التقييمات، الأصوات، سنة الإصدار، الأنواع |
| تحليل المشاعر / تدريب NLP | باحثو تعلم الآلة، الطلاب | المراجعات، التقييمات |
| تحليل المحتوى التنافسي | محللو صناعة الترفيه | الإيرادات، تواريخ الإصدار، اتجاهات التقييم |
| أبحاث السياحة السينمائية | هيئات السياحة، شركات السفر | مواقع التصوير، مقاييس الشعبية |
| البحث الأكاديمي | باحثو الجامعات | أي بيانات وصفية منظمة عن الأفلام |
تبلغ قيمة سوق السياحة السينمائية وحدها نحو . وأنفقت Netflix أكثر من 17 مليار دولار على المحتوى في 2024، مع مدفوعًا بتوصيات مخصصة. الخلاصة: بيانات IMDb تدخل في قرارات حقيقية عبر قطاعات متعددة.
خياراتك للحصول على بيانات IMDb (قبل كتابة سطر كود واحد)
هذا هو القسم الذي تتجاهله معظم الشروحات تمامًا. فهي تقفز مباشرة إلى pip install beautifulsoup4 من دون أن تسأل: هل استخراج البيانات باستخدام Python هو أصلًا النهج المناسب لحالتك؟
إليك الصورة كاملة:
| المسار | الأفضل لـ | المزايا | العيوب |
|---|---|---|---|
| Python + BeautifulSoup | التعلم، الاستخراج المخصص | تحكم كامل، مرونة عالية | محددات هشة، يتعطل كثيرًا |
استخراج JSON-LD / __NEXT_DATA__ | المطورون الذين يريدون الاستقرار | يتعامل مع محتوى JavaScript، أكثر صلابة | يتطلب فهم بنية JSON |
| IMDb Official Datasets | التحليل واسع النطاق، الاستخدام الأكاديمي | قانوني، شامل، أكثر من 26 مليون عنوان، تحديثات يومية | صيغة TSV، بلا مراجعات/صور |
| مكتبة Cinemagoer (IMDbPY) | عمليات بحث برمجية لكل عنوان | واجهة Pythonية، حقول غنية | 88 مشكلة مفتوحة، آخر إصدار في مايو 2023 |
| TMDb API | بيانات الأفلام + الصور | مفتاح API مجاني، JSON، موثق جيدًا | مصدر مختلف (ليست تقييمات IMDb) |
| Thunderbit (بدون كود) | غير المبرمجين، التصدير السريع | استخراج بنقرتين، الذكاء الاصطناعي يقترح الحقول، التصدير إلى Excel/Sheets | يعتمد على الرصيد في عمليات الاستخراج الكبيرة |
بعض الملاحظات حول هذه الخيارات. لم تحصل Cinemagoer على إصدار على PyPI منذ مايو 2023، وقد تعطلت معظم محللاتها بعد إعادة تصميم IMDb في يونيو 2025 — لا أنصح بها للاستخدام الإنتاجي الآن. أما TMDb فهو ممتاز لكنه يستخدم نظام تقييمه الخاص، وليس تقييم IMDb. وواجهة IMDb الرسمية للمؤسسات تكلف عبر AWS Data Exchange، لذا فهي ليست خيارًا لمعظمنا.
أما للقراء الذين لا يريدون كتابة أي كود، فإن تقرأ صفحة IMDb وتقترح حقول الاستخراج تلقائيًا (العنوان، التقييم، السنة، النوع)، ثم تصدر إلى Excel أو Google Sheets أو Airtable أو Notion بنقرتين. يتكيف الذكاء الاصطناعي عندما يغيّر IMDb تصميمه، لذلك لا توجد محددات تحتاج إلى صيانة. المزيد عن ذلك لاحقًا.
والآن، لمن يريد كتابة Python — إليك طريقتان تعملان.
الطريقة 1: استخراج IMDb باستخدام Python وBeautifulSoup (النهج التقليدي)
هذا هو النهج الكلاسيكي الذي ستجده في معظم الشروحات. وهو يعمل، لكنني أريد أن أكون صريحًا: إنه الأكثر هشاشة بين الطرق التي سأغطيها. أسماء فئات CSS في IMDb تُولَّد تلقائيًا وتتغير مع كل إعادة تصميم. ومع ذلك، فهو أفضل طريقة لتعلّم أساسيات استخراج الويب.
الخطوة 1: تثبيت مكتبات Python واستيرادها
تحتاج إلى أربع حزم:
1pip install requests beautifulsoup4 pandas lxml
وهذا ما تفعله كل واحدة:
requests— يرسل طلبات HTTP لجلب صفحة الويبbeautifulsoup4— يحلل HTML حتى تتمكن من البحث عن عناصر محددةpandas— ينظم البيانات المستخرجة في جداول ويصدرها إلى CSV/Excellxml— محلل HTML سريع (يمكن لـ BeautifulSoup استخدامه كخلفية)
كتلة الاستيراد الخاصة بك:
1import requests
2from bs4 import BeautifulSoup
3import pandas as pd
الخطوة 2: إرسال طلب HTTP إلى IMDb
هنا يصطدم معظم المبتدئين بأول جدار. يحظر IMDb الطلبات التي لا تتضمن ترويسة User-Agent مناسبة — وستحصل على خطأ 403 Forbidden. سلسلة وكيل المستخدم الافتراضية في Python Requests (python-requests/2.31.0) تُرصد فورًا.
1url = "https://www.imdb.com/chart/top/"
2headers = {
3 "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
4 "Accept-Language": "en-US,en;q=0.9"
5}
6response = requests.get(url, headers=headers)
7if response.status_code != 200:
8 print(f"فشل جلب الصفحة: {response.status_code}")
9else:
10 print("تم جلب الصفحة بنجاح")
ترويسة Accept-Language مهمة أيضًا — فمن دونها قد يعيد IMDb المحتوى بلغة مختلفة بحسب موقع عنوان IP الخاص بك.
الخطوة 3: تحليل HTML باستخدام BeautifulSoup
بمجرد حصولك على HTML، أنشئ كائن BeautifulSoup وابدأ البحث عن العناصر الصحيحة. افتح صفحة IMDb Top 250 في Chrome، ثم انقر بزر الماوس الأيمن على عنوان فيلم واضغط "Inspect" لرؤية بنية HTML الأساسية.
1soup = BeautifulSoup(response.text, "lxml")
حتى منتصف 2025، تستخدم صفحة Top 250 المحددات التالية:
- حاوية الفيلم:
li.ipc-metadata-list-summary-item - العنوان:
h3.ipc-title__text - السنة:
span.cli-title-metadata-item(أول span) - التقييم:
span.ipc-rating-star--rating
تحذير مهم: تلك الفئات التي تبدأ بـ ipc- تُولَّد بواسطة نظام المكونات في IMDb. لقد ظلت مستقرة منذ إعادة تصميم يونيو 2023، لكن لا يوجد ضمان ألا تتغير مرة أخرى.
الخطوة 4: استخراج بيانات الفيلم (العنوان، السنة، التقييم)
هنا أختلف عن معظم الشروحات: أنا أضيف معالجة أخطاء try/except. لم يضع أي من أدلة المنافسين التي راجعتها هذا، وهذا بالضبط سبب تعطل أكوادهم بصمت عندما يتغير أحد المحددات.
1movies = []
2movie_items = soup.select("li.ipc-metadata-list-summary-item")
3for item in movie_items:
4 try:
5 title_tag = item.select_one("h3.ipc-title__text")
6 title = title_tag.text.strip() if title_tag else "N/A"
7 year_tag = item.select_one("span.cli-title-metadata-item")
8 year = year_tag.text.strip() if year_tag else "N/A"
9 rating_tag = item.select_one("span.ipc-rating-star--rating")
10 rating = rating_tag.text.strip() if rating_tag else "N/A"
11 movies.append({
12 "title": title,
13 "year": year,
14 "rating": rating
15 })
16 except Exception as e:
17 print(f"خطأ أثناء تحليل الفيلم: {e}")
18 continue
19print(f"تم استخراج {len(movies)} فيلمًا")
الخطوة 5: الحفظ إلى CSV أو Excel باستخدام Pandas
1df = pd.DataFrame(movies)
2df.to_csv("imdb_top_250.csv", index=False)
3df.to_excel("imdb_top_250.xlsx", index=False)
4print(df.head())
مثال على المخرجات:
1 title year rating
20 1. The Shawshank Redemption 1994 9.3
31 2. The Godfather 1972 9.2
42 3. The Dark Knight 2008 9.0
53 4. The Godfather Part II 1974 9.0
64 5. 12 Angry Men 1957 9.0
هذا ينجح، لكنه قائم على محددات CSS قد تنكسر في أي يوم — وهذا يقودنا إلى النهج الذي أوصي به فعلًا.
الطريقة 2: حيلة JSON-LD — تجاهل تحليل HTML بالكامل
هذه هي التقنية التي لا يغطيها أي مقال منافس، وهي التقنية التي سأستخدمها في أي مشروع جاد. يضمّن IMDb البيانات المنظمة على شكل (JavaScript Object Notation for Linked Data) داخل وسوم <script type="application/ld+json"> في كل صفحة. تتبع هذه البيانات معيار Schema.org، وتستخدمها Google لنتائج البحث الغنية، وتتغير بوتيرة أقل بكثير من أسماء فئات CSS.
تستخدم أداة Apify IMDb Scraper، وهي أداة إنتاجية، ترتيب الأولوية التالي للاستخراج: "JSON-LD > NEXT_DATA > DOM." وهذا هو التسلسل الذي أوصي به أيضًا.
لماذا يعد JSON-LD أكثر موثوقية من محددات CSS
| النهج | يتعامل مع محتوى JavaScript؟ | مقاوم لتغيرات الواجهة؟ | السرعة | التعقيد |
|---|---|---|---|---|
| BeautifulSoup + محددات CSS | ❌ لا | ⚠️ هش (تتغير أسماء الفئات) | سريع | منخفض |
| استخراج JSON-LD | ✅ نعم | ✅ يتبع معيار Schema.org | سريع | منخفض-متوسط |
استخراج JSON من __NEXT_DATA__ | ✅ نعم | ✅ مستقر نسبيًا | سريع | منخفض-متوسط |
| Selenium / Playwright | ✅ نعم | ⚠️ هش | بطيء | متوسط-عالٍ |
| Thunderbit (بدون كود، بنقرتين) | ✅ نعم (الذكاء الاصطناعي يقرأ الصفحة) | ✅ يتكيف الذكاء الاصطناعي تلقائيًا | سريع | لا شيء |
أسماء الفئات مثل ipc-metadata-list-summary-item تُولَّد تلقائيًا بواسطة نظام مكونات React في IMDb وتتغير مع كل إعادة تصميم. أما مخطط JSON-LD فيمثل نموذج البيانات الفعلي، لا طبقة العرض. الفرق يشبه الفرق بين قراءة فهرس الكتاب ومحاولة تحديد الفصول من خلال حجم الخط.

خطوة بخطوة: استخراج بيانات IMDb من JSON-LD
الخطوة 1: جلب الصفحة
كما في السابق — استخدم requests مع ترويسة User-Agent مناسبة.
1import requests
2from bs4 import BeautifulSoup
3import json
4import pandas as pd
5url = "https://www.imdb.com/chart/top/"
6headers = {
7 "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
8 "Accept-Language": "en-US,en;q=0.9"
9}
10response = requests.get(url, headers=headers)
11soup = BeautifulSoup(response.text, "lxml")
الخطوة 2: العثور على وسم Script الخاص بـ JSON-LD
1script_tag = soup.find("script", {"type": "application/ld+json"})
2if not script_tag:
3 print("لم يتم العثور على JSON-LD في هذه الصفحة")
4else:
5 data = json.loads(script_tag.string)
6 print(f"تم العثور على JSON-LD بالنوع: {data.get('@type', 'unknown')}")
الخطوة 3: تحليل البيانات المنظمة
في صفحة Top 250، يحتوي JSON-LD على مصفوفة itemListElement بكل الأفلام الـ250. يتضمن كل إدخال الترتيب، الاسم، الرابط، aggregateRating، تاريخ النشر، النوع، الوصف، المخرج، ومصفوفات الممثلين.
1movies = []
2for item in data.get("itemListElement", []):
3 movie = item.get("item", {})
4 rating_info = movie.get("aggregateRating", {})
5 movies.append({
6 "rank": item.get("position"),
7 "title": movie.get("name"),
8 "url": movie.get("url"),
9 "rating": rating_info.get("ratingValue"),
10 "vote_count": rating_info.get("ratingCount"),
11 "date_published": movie.get("datePublished"),
12 "genre": ", ".join(movie.get("genre", [])),
13 "description": movie.get("description"),
14 })
الخطوة 4: التصدير إلى CSV
1df = pd.DataFrame(movies)
2df.to_csv("imdb_top_250_json_ld.csv", index=False)
3print(df.head())
مثال على المخرجات:
1 rank title url rating vote_count date_published genre
20 1 The Shawshank Redemption https://www.imdb.com/title/tt0111161/ 9.3 2900000 1994-10-14 Drama
31 2 The Godfather https://www.imdb.com/title/tt0068646/ 9.2 2000000 1972-03-24 Crime, Drama
42 3 The Dark Knight https://www.imdb.com/title/tt0468569/ 9.0 2800000 2008-07-18 Action, Crime, Drama
كل الأفلام الـ250. نظيف، منظم، بلا حيل محددات CSS. وبما أن هذه البيانات تتبع معيار Schema.org (الذي تعتمد عليه Google في نتائج البحث)، فمن غير المرجح أن تتغير مقارنة بتغير التخطيط المرئي.
إضافة: __NEXT_DATA__ لصفحات الأفلام الفردية
للحصول على بيانات أغنى من صفحات العناوين الفردية (مدة العرض، طاقم التمثيل الكامل، ملخص الحبكة، صور الملصق)، يضمّن IMDb أيضًا كائن JSON باسم __NEXT_DATA__. هذه هي البيانات التي يستخدمها React لتهيئة الصفحة — ولا يمكن إزالتها من دون كسر الموقع.
1# في صفحة فيلم فردية مثل /title/tt0111161/
2next_data_tag = soup.find("script", {"id": "__NEXT_DATA__"})
3if next_data_tag:
4 next_data = json.loads(next_data_tag.string)
5 above_fold = next_data["props"]["pageProps"]["aboveTheFoldData"]
6 title = above_fold["titleText"]["text"]
7 year = above_fold["releaseYear"]["year"]
8 rating = above_fold["ratingsSummary"]["aggregateRating"]
9 runtime_seconds = above_fold.get("runtime", {}).get("seconds", 0)
10 genres = [g["text"] for g in above_fold["genres"]["genres"]]
11 plot = above_fold["plot"]["plotText"]["plainText"]
استخدم JSON-LD لصفحات القوائم/الترتيب، و__NEXT_DATA__ لصفحات العناوين الفردية. هذا هو النهج المناسب للإنتاج.
لماذا تستمر أداة استخراج IMDb الخاصة بك في التعطل (وكيف تصلح ذلك)
هذه هي أكثر نقطة ألم يتم ذكرها عبر كل منتدى لاستخراج IMDb راجعته. يكتب المستخدمون: "تعطل بعض الكود بسبب تغييرات الواجهة" و*"لا يعمل في 2024!"* — وغالبًا ما تكون الإجابة صمتًا أو "جرّب Selenium."
السبب الجذري هو انتقال IMDb المستمر إلى واجهة أمامية مبنية على React/Next.js. إليك الجدول الزمني لأهم التغييرات التي كسرت الأدوات:
| التاريخ | ما الذي تغيّر | ما الذي تعطّل |
|---|---|---|
| نوفمبر 2022 | إعادة تصميم صفحات الأسماء | أدوات استخراج صفحات الأسماء القديمة |
| يونيو 2023 | إعادة تصميم صفحة Top 250 | جميع المحددات td.titleColumn / td.ratingColumn |
| أبريل 2023 | إعادة تصميم الصفحات الفرعية للعناوين | أدوات السيرة والجوائز والأخبار |
| أكتوبر 2023 | إعادة تصميم البحث المتقدم | أدوات الاستخراج القائمة على البحث |
| يونيو 2025 | إعادة تصميم صفحات /reference | مكتبة Cinemagoer (معظم المحللات) |
هذا يعني تقريبًا تغييرًا جذريًا كل 6–12 شهرًا. إذا كانت أداة الاستخراج الخاصة بك تعتمد على أسماء فئات CSS، فأنت تركض على جهاز مشي.
الأخطاء الشائعة وكيفية إصلاحها
نتائج فارغة / أخطاء NoneType
هذا هو الخطأ الأكثر شيوعًا. سترى: AttributeError: 'NoneType' object has no attribute 'text'. هذا يعني أن BeautifulSoup لم يتمكن من العثور على العنصر الذي تبحث عنه — عادةً لأن اسم فئة CSS تغيّر أو لأن المحتوى يُعرض بواسطة JavaScript.
الإصلاح: انتقل إلى استخراج JSON-LD (الطريقة 2 أعلاه). البيانات موجودة في استجابة HTML الأولية، ولا تحتاج إلى JavaScript.
403 Forbidden
يستخدم IMDb لاكتشاف الروبوتات وحظرها. السبب الأول هو غياب ترويسة User-Agent مناسبة أو كونها مزيفة بشكل واضح. تم توثيق ذلك عبر مشاريع مفتوحة المصدر، وكذلك في حيث أقر موظف في IMDb بالمشكلة.
الإصلاح: أضف دائمًا سلسلة User-Agent واقعية تشبه المتصفح، وترويسة Accept-Language: en-US. استخدم requests.Session() لتجميع الاتصالات.
تم إرجاع 25 نتيجة فقط
تستخدم صفحات البحث وقوائم "الأكثر شهرة" التحميل الكسول — فهي تعرض نحو 25 نتيجة فقط في البداية وتحمّل المزيد عبر AJAX أثناء التمرير.
الإصلاح: استخدم ترقيم الصفحات عبر معلمة URL (مغطاة في القسم التالي) أو انتقل إلى صفحة Top 250، التي تحمل كل الأفلام الـ250 في استجابة واحدة.
تتوقف المحددات عن العمل فجأة
المحددات القديمة التي لم تعد تعمل: td.titleColumn وtd.ratingColumn و.lister-item-header و.inline-block.ratings-imdb-rating. إذا كان كودك يستخدم أيًا منها، فهو معطّل.
الإصلاح: فضّل سمات data-testid (مثل h1[data-testid="hero-title-block__title"]) بدل أسماء الفئات المولدة تلقائيًا. والأفضل من ذلك كله: استخدم JSON-LD.
إطار لاتخاذ القرار: إصلاحات قصيرة الأجل مقابل طويلة الأجل
- إصلاح سريع: أضف كتل
try/exceptحول كل محدد، تحقق من رموز حالة HTTP، وسجل الأخطاء بدل التعطل - إصلاح متوسط الأجل: انتقل من محددات CSS إلى استخراج JSON-LD (الطريقة 2)
- إصلاح طويل الأجل: استخدم للتحليل واسع النطاق، أو أداة مثل التي تستخدم الذكاء الاصطناعي لإعادة قراءة بنية الصفحة من جديد كل مرة — بلا محددات تحتاج إلى صيانة، والذكاء الاصطناعي يتكيف تلقائيًا مع تغييرات التخطيط
ما بعد حاجز 25 نتيجة: استخراج ترقيم صفحات IMDb ومجموعات البيانات الكبيرة
كل شرح منافس راجعته يستخرج صفحة واحدة فقط. لا أحد يغطي الترقيم. لكن إذا كنت تحتاج أكثر من قائمة واحدة، فستصطدم بالجدران بسرعة.
الصفحات التي لا تحتاج إلى ترقيم
خبر جيد: صفحة Top 250 تحمل كل الأفلام الـ250 في استجابة واحدة من الخادم. كل من JSON-LD و__NEXT_DATA__ يحتويان على المجموعة الكاملة من البيانات. لا حاجة للترقيم.
كيف يعمل ترقيم صفحات بحث IMDb
تستخدم صفحات بحث IMDb معلمة URL start= وتزيدها بمقدار 50:
1https://www.imdb.com/search/title/?groups=top_1000&start=1
2https://www.imdb.com/search/title/?groups=top_1000&start=51
3https://www.imdb.com/search/title/?groups=top_1000&start=101
إليك حلقة Python تمر عبر النتائج:
1import time
2all_movies = []
3for start in range(1, 1001, 50): # يتنقل عبر أفضل 1000
4 url = f"https://www.imdb.com/search/title/?groups=top_1000&start={start}"
5 response = requests.get(url, headers=headers)
6 if response.status_code != 200:
7 print(f"فشل عند start={start}: {response.status_code}")
8 break
9 soup = BeautifulSoup(response.text, "lxml")
10 # استخرج الأفلام بالطريقة المفضلة لديك
11 # ...
12 print(f"تم استخراج الصفحة التي تبدأ عند {start}")
13 time.sleep(3) # كن مهذبًا — IMDb يحظر بعد نحو 50 طلبًا سريعًا
هذا time.sleep(3) مهم. تشير تقارير المجتمع إلى أن IMDb يبدأ بحظر عناوين IP بعد حوالي 50 طلبًا سريعًا. تأخير عشوائي بين 2–5 ثوانٍ ممارسة جيدة.
متى تتجاوز الاستخراج تمامًا: مجموعات البيانات الرسمية من IMDb
للاحتياجات واسعة النطاق فعلًا، يوفر IMDb 7 ملفات TSV مجانية على ، ويتم تحديثها يوميًا:
| الملف | المحتويات | الحجم |
|---|---|---|
| title.basics.tsv.gz | العناوين، الأنواع، المدة، السنة | ~800 ميغابايت |
| title.ratings.tsv.gz | متوسط التقييم، عدد الأصوات | ~25 ميغابايت |
| title.crew.tsv.gz | المخرجون، الكُتّاب | ~300 ميغابايت |
| title.principals.tsv.gz | طاقم التمثيل/العمل الرئيسي | ~2 جيجابايت |
| title.akas.tsv.gz | العناوين البديلة حسب المنطقة | ~1.5 جيجابايت |
| title.episode.tsv.gz | معلومات حلقات التلفزيون | ~200 ميغابايت |
| name.basics.tsv.gz | الأشخاص: الاسم، سنة الميلاد، العناوين المعروفة | ~700 ميغابايت |
تحميلها إلى Pandas سهل:
1ratings = pd.read_csv("title.ratings.tsv.gz", sep="\t", compression="gzip")
2basics = pd.read_csv("title.basics.tsv.gz", sep="\t", compression="gzip", low_memory=False)
3# الدمج على tconst (معرّف عنوان IMDb)
4merged = basics.merge(ratings, on="tconst")
5top_movies = merged[merged["titleType"] == "movie"].nlargest(250, "averageRating")
تغطي هذه المجموعات أكثر من 26 مليون عنوان. لا ترقيم صفحات، لا محددات، لا أخطاء 403. الترخيص للاستخدام الشخصي وغير التجاري فقط — لا يمكنك إعادة نشر البيانات أو إعادة بيعها.
الطريق المختصر بدون كود: Thunderbit يتولى الترقيم نيابةً عنك
بالنسبة للقراء الذين يحتاجون إلى بيانات IMDb مرقمة الصفحات لكنهم لا يريدون كتابة منطق الترقيم، يدعم الترقيم بالنقر والتمرير اللانهائي بشكل أصلي. أنت تطلب منه الاستخراج، وهو يتولى الباقي — بما في ذلك التمرير عبر المحتوى المحمّل تدريجيًا.
استخراج IMDb باستخدام Python: الكود الكامل الجاهز للعمل
إليك نصين مستقلين يمكنك تشغيلهما الآن.
السكربت أ: طريقة BeautifulSoup (محددات CSS)
1import requests
2from bs4 import BeautifulSoup
3import pandas as pd
4url = "https://www.imdb.com/chart/top/"
5headers = {
6 "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
7 "Accept-Language": "en-US,en;q=0.9"
8}
9response = requests.get(url, headers=headers)
10if response.status_code != 200:
11 print(f"خطأ: {response.status_code}")
12 exit()
13soup = BeautifulSoup(response.text, "lxml")
14movie_items = soup.select("li.ipc-metadata-list-summary-item")
15movies = []
16for item in movie_items:
17 try:
18 title = item.select_one("h3.ipc-title__text")
19 year = item.select_one("span.cli-title-metadata-item")
20 rating = item.select_one("span.ipc-rating-star--rating")
21 movies.append({
22 "title": title.text.strip() if title else "N/A",
23 "year": year.text.strip() if year else "N/A",
24 "rating": rating.text.strip() if rating else "N/A",
25 })
26 except Exception as e:
27 print(f"تخطي الفيلم بسبب خطأ: {e}")
28df = pd.DataFrame(movies)
29df.to_csv("imdb_top250_bs4.csv", index=False)
30print(f"تم حفظ {len(df)} فيلمًا")
31print(df.head())
السكربت ب: طريقة JSON-LD (الموصى بها)
1import requests
2from bs4 import BeautifulSoup
3import json
4import pandas as pd
5url = "https://www.imdb.com/chart/top/"
6headers = {
7 "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
8 "Accept-Language": "en-US,en;q=0.9"
9}
10response = requests.get(url, headers=headers)
11if response.status_code != 200:
12 print(f"خطأ: {response.status_code}")
13 exit()
14soup = BeautifulSoup(response.text, "lxml")
15script_tag = soup.find("script", {"type": "application/ld+json"})
16if not script_tag:
17 print("لم يتم العثور على بيانات JSON-LD")
18 exit()
19data = json.loads(script_tag.string)
20movies = []
21for item in data.get("itemListElement", []):
22 movie = item.get("item", {})
23 rating_info = movie.get("aggregateRating", {})
24 directors = movie.get("director", [])
25 director_names = ", ".join(
26 d.get("name", "") for d in (directors if isinstance(directors, list) else [directors])
27 )
28 movies.append({
29 "rank": item.get("position"),
30 "title": movie.get("name"),
31 "url": movie.get("url"),
32 "rating": rating_info.get("ratingValue"),
33 "votes": rating_info.get("ratingCount"),
34 "year": movie.get("datePublished", "")[:4],
35 "genre": ", ".join(movie.get("genre", [])),
36 "director": director_names,
37 "description": movie.get("description"),
38 })
39df = pd.DataFrame(movies)
40df.to_csv("imdb_top250_jsonld.csv", index=False)
41print(f"تم حفظ {len(df)} فيلمًا")
42print(df.head())
كلا السكربتين يتضمنان معالجة أخطاء ويُنتجان مخرجات CSV نظيفة. يمنحك السكربت ب بيانات أغنى — المخرج، الوصف، الرابط — وهو أكثر صمودًا أمام تغييرات التخطيط.
كيف تستخرج IMDb من دون كتابة أي كود (باستخدام Thunderbit)
ليس الجميع بحاجة أو يرغب في كتابة Python. ربما أنت محلل عمليات وتحتاج فقط إلى أفضل الأفلام تقييمًا هذا الأسبوع في جدول بيانات. ربما أنت مختص استراتيجية محتوى تريد مقارنة اتجاهات الأنواع عبر السنوات. في هذه الحالات، كتابة أداة استخراج كاملة قد تكون مبالغة.
إليك كيفية الحصول على البيانات نفسها باستخدام :
قبل أن تبدأ:
- مستوى الصعوبة: مبتدئ
- الوقت المطلوب: حوالي دقيقتين
- ما ستحتاجه: متصفح Chrome، و (الخطة المجانية تعمل)
الخطوة 1: انتقل إلى صفحة IMDb التي تريد استخراجها. افتح IMDb Top 250 (أو أي صفحة قائمة/بحث أخرى على IMDb) في Chrome.
الخطوة 2: انقر "AI Suggest Fields" في الشريط الجانبي لـ Thunderbit. يمسح الذكاء الاصطناعي الصفحة ويقترح الأعمدة — عادةً العنوان، السنة، التقييم، النوع، وغيرها بحسب الصفحة. سترى جدول معاينة بالحقول المقترحة.
الخطوة 3: عدّل الحقول إذا لزم الأمر. أزل الأعمدة التي لا تحتاجها، أو أضف أعمدة مخصصة بالنقر على "+ Add Column" وشرح ما تريد بلغة بسيطة (مثل: "اسم المخرج" أو "عدد الأصوات").
الخطوة 4: انقر "Scrape." يستخرج Thunderbit البيانات. بالنسبة للصفحات ذات التمرير اللانهائي أو الترقيم، يتولى التمرير تلقائيًا.
الخطوة 5: التصدير. انقر زر التصدير واختر الصيغة — Excel، Google Sheets، CSV، Airtable، أو Notion. تصل البيانات إلى وجهتها في ثوانٍ.
الميزة الأساسية هنا ليست الراحة فقط — بل أن الذكاء الاصطناعي في Thunderbit يقرأ بنية الصفحة من جديد في كل مرة. عندما يغيّر IMDb تصميمه (وسيفعل)، يتكيف الذكاء الاصطناعي. لا محددات تحتاج إلى تحديث، ولا كود يحتاج إلى إصلاح. بالنسبة لأي شخص سبق أن أُحبط بسبب أداة استخراج مكسورة في الثانية صباحًا قبل موعد نهائي، فهذه ميزة ثمينة جدًا.
يدعم Thunderbit أيضًا استخراج الصفحات الفرعية — يمكنك الدخول إلى صفحة تفاصيل كل فيلم وإثراء جدولك بطاقم التمثيل، والمخرج، ومدة العرض، وحقول أخرى غير ظاهرة في صفحة القائمة. إذا أردت رؤيته عمليًا، فاطلع على .
هل استخراج IMDb قانوني؟ ما الذي تحتاج إلى معرفته
يسأل المستخدمون هذا صراحةً في المنتديات: "هل شيء كهذا قانوني؟… IMDb لا يريد من الناس استخراج بيانات موقعه." إنه سؤال عادل، ولم يتناوله أي مقال منافس.
robots.txt الخاص بـ IMDb: مخطط Top 250 (/chart/top/) وصفحات العناوين الفردية (/title/ttXXXXXXX/) وصفحات الأسماء (/name/nmXXXXXXX/) ليست محجوبة بواسطة robots.txt. وتشمل المسارات المحجوبة /find و/_json/* و/search/name-text و/user/ur*/ratings ومجموعة من نقاط نهاية AJAX. لا توجد توجيهات Crawl-delay محددة.
شروط استخدام IMDb: تنص الفقرة ذات الصلة على: "لا يجوز لك استخدام التنقيب عن البيانات، أو الروبوتات، أو screen scraping، أو أدوات جمع البيانات والاستخراج المشابهة على هذا الموقع، إلا بموافقتنا الخطية الصريحة." وهناك فقرة إضافية تمنع إعادة بيع البيانات المستخرجة أو استخدامها تجاريًا.
ماذا يعني هذا عمليًا: أحكام قضائية حديثة في 2024 (Meta v. Bright Data، وX Corp v. Bright Data) وجدت أن شروط الخدمة قد لا تلزم المستخدمين الذين لم يوافقوا عليها أصلًا — فإذا كنت تستخرج بيانات متاحة للعامة من دون تسجيل دخول، فإلزامية شروط الاستخدام محل نقاش قانوني. لكن هذا مجال قانوني يتطور.
بدائل آمنة: مجموعات البيانات مرخصة صراحةً للاستخدام الشخصي وغير التجاري. وواجهة TMDb API متساهلة مع مفتاح API مجاني. كلاهما خياران قويان إذا أردت البقاء في المنطقة الآمنة بوضوح.
إرشاد عملي: إذا قررت الاستخراج، فاحرص على معدل زحف محترم (time.sleep(3) بين الطلبات)، واضبط الترويسات بشكل صحيح، ولا تزُر المسارات المحجوبة في robots.txt. وللمشاريع التجارية، استشر مختصًا قانونيًا أو استخدم مجموعات البيانات/الواجهة الرسمية.
لقد تناولنا بعمق في مدونة Thunderbit.
الخلاصة: اختر الطريقة المناسبة لاستخراج IMDb باستخدام Python
الخلاصة السريعة:
- BeautifulSoup + محددات CSS: جيد لتعلّم الأساسيات. توقّع أن يتعطل كل 6–12 شهرًا. يجب دائمًا إضافة معالجة أخطاء.
- استخراج JSON-LD: النهج الذي أوصي به لأي مشروع Python مستمر. يتبع معيار Schema.org، ويتغير بوتيرة أقل بكثير من فئات CSS، ويمنحك بيانات منظمة نظيفة من دون عرض JavaScript.
- JSON
__NEXT_DATA__: استخدمه كمكمل للحصول على بيانات أغنى من صفحات العناوين الفردية (مدة العرض، طاقم العمل الكامل، الحبكة، صور الملصق). - مجموعات بيانات IMDb الرسمية: الخيار الأفضل للتحليل واسع النطاق. أكثر من 26 مليون عنوان، تُحدَّث يوميًا، ولا تحتاج إلى استخراج. للاستخدام الشخصي/غير التجاري فقط.
- : الخيار الأفضل لغير المبرمجين أو لأي شخص يريد البيانات بسرعة من دون صيانة كود. يتكيف الذكاء الاصطناعي مع تغييرات التخطيط، ويتولى الترقيم، ويصدر إلى Excel/Sheets/Airtable/Notion.
احفظ هذا الدليل في المفضلة — سأحدّثه عندما تتغير بنية IMDb مرة أخرى. وإذا أردت تجاوز الكود بالكامل، وشاهد كم بسرعة يمكنك الانتقال من صفحة IMDb إلى جدول بيانات نظيف. وإذا كنت تعمل مع مواقع أخرى أيضًا، فإن دليلنا حول يغطي سير العمل الأوسع.
الأسئلة الشائعة
هل استخراج IMDb قانوني؟
تمنع شروط خدمة IMDb الاستخراج من دون موافقة، لكن قابلية إنفاذ شروط الخدمة على البيانات المتاحة للعامة محل نقاش قانوني بعد أحكام قضائية حديثة في 2024. أكثر الخيارات أمانًا هي (للاستخدام الشخصي/غير التجاري) أو TMDb API (مفتاح مجاني). إذا قررت الاستخراج، فاحترم robots.txt، واستخدم فواصل زمنية معقولة بين الطلبات، وتجنب المسارات المحجوبة. وللاستخدام التجاري، استشر مختصًا قانونيًا.
لماذا تعيد أداة استخراج IMDb الخاصة بي نتائج فارغة؟
في الغالب، السبب هو أن محددات CSS قديمة — فالفئات مثل td.titleColumn وtd.ratingColumn لم تعد موجودة منذ يونيو 2023. الحل هو الانتقال إلى استخراج JSON-LD (تحليل وسم <script type="application/ld+json">) أو تحديث المحددات إلى الفئات الحالية التي تبدأ بـ ipc-. وتحقق أيضًا من تضمين ترويسة User-Agent صحيحة، لأن غيابها يؤدي إلى خطأ 403 قد يظهر على شكل نتائج فارغة.
كيف أستخرج أكثر من 25 نتيجة من IMDb؟
صفحة Top 250 تحمل الأفلام الـ250 كلها في استجابة واحدة — لا حاجة للترقيم. أما نتائج البحث، فاستخدم معلمة URL start= (تزيد بمقدار 50) للتنقل بين النتائج. مثلًا: start=1 وstart=51 وstart=101. أضف time.sleep(3) بين الطلبات لتجنب الحظر. أو استخدم مجموعات البيانات الرسمية من التي تحتوي على أكثر من 26 مليون عنوان من دون حاجة إلى ترقيم.
ما هو __NEXT_DATA__ ولماذا يجب أن أستخدمه لاستخراج IMDb؟
__NEXT_DATA__ هو كائن JSON مضمّن داخل وسم <script id="__NEXT_DATA__"> في صفحات IMDb المبنية على React/Next.js. يحتوي على البيانات المنظمة الكاملة التي يستخدمها React لعرض الصفحة — العناوين، التقييمات، الممثلون، الأنواع، مدة العرض، وغيرها. وبما أنه يمثل نموذج البيانات الأساسي بدل التخطيط المرئي، فهو أكثر صمودًا أمام إعادة تصميم الواجهة من محددات CSS. استخدمه مع JSON-LD للحصول على أقوى نهج استخراج.
هل يمكنني استخراج IMDb من دون برمجة؟
نعم. هناك خياران رئيسيان: (1) تنزيل — 7 ملفات TSV تغطي أكثر من 26 مليون عنوان، وتُحدَّث يوميًا، ومجانية للاستخدام غير التجاري. (2) استخدام ، التي تقرأ صفحة IMDb وتقترح الحقول تلقائيًا وتصدر إلى Excel أو Google Sheets أو CSV بنقرتين — بلا كود، ولا محددات تحتاج إلى صيانة.
اعرف المزيد
