سؤال

أحاول جلب مقالة ويكيبيديا باستخدام urllib الخاص بـ Python:

f = urllib.urlopen("http://en.wikipedia.org/w/index.php?title=Albert_Einstein&printable=yes")           
s = f.read()
f.close()

ولكن بدلاً من صفحة html أحصل على الرد التالي:خطأ - مؤسسة ويكيميديا:

Request: GET http://en.wikipedia.org/w/index.php?title=Albert_Einstein&printable=yes, from 192.35.17.11 via knsq1.knams.wikimedia.org (squid/2.6.STABLE21) to ()
Error: ERR_ACCESS_DENIED, errno [No Error] at Tue, 23 Sep 2008 09:09:08 GMT 

يبدو أن ويكيبيديا تمنع الطلب الذي لا يأتي من متصفح قياسي.

هل يعرف أحد كيفية التغلب على هذا؟

هل كانت مفيدة؟

المحلول

تحتاج إلى استخدام urllib2 الذي يحل محل urllib في ال مكتبة بايثون ستد من أجل تغيير وكيل المستخدم.

مباشرة من أمثلة

import urllib2
opener = urllib2.build_opener()
opener.addheaders = [('User-agent', 'Mozilla/5.0')]
infile = opener.open('http://en.wikipedia.org/w/index.php?title=Albert_Einstein&printable=yes')
page = infile.read()

نصائح أخرى

إنه ليس حلاً لمشكلة محددة.ولكن قد يكون من المثير للاهتمام بالنسبة لك استخدام مكتبة mwclient (http://botwiki.sno.cc/wiki/Python:Mwclient) بدلاً من.سيكون ذلك أسهل بكثير.خاصة وأنك ستحصل مباشرة على محتويات المقالة مما يلغي الحاجة إلى تحليل HTML.

لقد استخدمته بنفسي لمشروعين، وهو يعمل بشكل جيد للغاية.

بدلاً من محاولة خداع ويكيبيديا، يجب أن تفكر في استخدام واجهة برمجة التطبيقات عالية المستوى.

في حال كنت تحاول الوصول إلى محتوى ويكيبيديا (ولا تحتاج إلى أي معلومات محددة حول الصفحة نفسها)، فبدلاً من استخدام واجهة برمجة التطبيقات، يجب عليك فقط الاتصال بـ Index.php مع 'action=raw' للحصول على نص الويكي، مثل في:

"http://en.wikipedia.org/w/index.php?الإجراء = الخام&title=الصفحة_الرئيسية'

أو، إذا كنت تريد كود HTML، استخدم "action=render" كما في:

"http://en.wikipedia.org/w/index.php?action=render&title=الصفحة_الرئيسية'

يمكنك أيضًا تحديد قسم للحصول على جزء فقط من المحتوى بشيء مثل "القسم = 3".

يمكنك بعد ذلك الوصول إليه باستخدام وحدة urllib2 (كما هو مقترح في الإجابة المختارة).ومع ذلك، إذا كنت بحاجة إلى معلومات حول الصفحة نفسها (مثل المراجعات)، فمن الأفضل استخدام mwclient كما هو مقترح أعلاه.

تشير إلى الأسئلة الشائعة حول ميدياويكي اذا احتجت الى مزيد من المعلومات.

الحل العام الذي أستخدمه لأي موقع هو الوصول إلى الصفحة باستخدام Firefox، وباستخدام امتداد مثل Firebug، تسجيل جميع تفاصيل طلب HTTP بما في ذلك أي ملفات تعريف ارتباط.

في برنامجك (في هذه الحالة في Python) يجب أن تحاول إرسال طلب HTTP مشابهًا حسب الضرورة للطلب الذي يعمل من Firefox.يتضمن هذا غالبًا إعداد حقول وكيل المستخدم والمُحيل وملفات تعريف الارتباط، ولكن قد يكون هناك حقول أخرى.

requests رائع!

إليك كيفية الحصول على محتوى HTML باستخدام requests:

import requests
html = requests.get('http://en.wikipedia.org/w/index.php?title=Albert_Einstein&printable=yes').text

منتهي!

حاول تغيير رأس وكيل المستخدم الذي ترسله في طلبك إلى شيء مثل:وكيل المستخدم:موزيلا/5.0 (X11؛ش؛لينكس i686؛أون-الولايات المتحدة;rv:1.9.0.1) Gecko/2008072820 Ubuntu/8.04 (هاردي) Firefox/3.0.1 (Linux Mint)

لا تحتاج إلى انتحال شخصية وكيل مستخدم المتصفح؛سيعمل أي وكيل مستخدم على الإطلاق، ولكن ليس وكيل مستخدم فارغًا.

import urllib
s = urllib.urlopen('http://en.wikipedia.org/w/index.php?action=raw&title=Albert_Einstein').read()

يبدو أن هذا يعمل بالنسبة لي دون تغيير وكيل المستخدم.بدون "الإجراء = الخام" لا يعمل بالنسبة لي.

طلب الصفحة مع ?printable=yes يمنحك مستند HTML نظيفًا نسبيًا بالكامل. ?action=render يمنحك فقط نص HTML.طلب تحليل الصفحة من خلال واجهة برمجة تطبيقات إجراءات MediaWiki باستخدام action=parse يمنحك أيضًا نص HTML فقط، ولكن سيكون من الجيد إذا كنت تريد تحكمًا أفضل، راجع تعليمات تحليل API.

إذا كنت تريد فقط HTML للصفحة حتى تتمكن من عرضها، فمن الأسرع والأفضل استخدام الجديد RESTBase واجهة برمجة التطبيقات (API)، التي تُرجع تمثيل HTML المخبأ للصفحة.في هذه الحالة، https://en.wikipedia.org/api/rest_v1/page/html/Albert_Einstein.

اعتبارًا من نوفمبر 2015، لن يتعين عليك تعيين وكيل المستخدم الخاص بك، ولكن يتم تشجيعه بشدة.وأيضًا جميع مواقع ويكي ويكيميديا ​​تقريبًا تتطلب HTTPS, ، لذا تجنب إعادة التوجيه 301 وقم بإجراء httpس طلبات.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top