2008-09-23 3 views
37

Я стараюсь принести статью Википедии с URLLIB Пайтона:Fetch статью Википедии с Python

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

Однако вместо страницы HTML я получаю следующий ответ: Ошибка - Wikimedia Foundation:

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 

Википедия, похоже, блокирует запрос, который не является стандартным браузером.

Кто-нибудь знает, как обойти это?

+3

Wikipedia не блокирует запросы не из стандартного браузера, он блокирует запросы, которые из стандартных библиотек, не меняя их пользовательский агент. – svick 2012-08-05 08:09:39

ответ

50

Вам необходимо использовать urllib2, который superseedes urllib в python std library, чтобы изменить агент пользователя.

Прямо из examples

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() 
+6

Википедия пытается заблокировать скребки экрана по какой-то причине. Их серверам приходится много работать, чтобы конвертировать wikicode в HTML, когда есть более простые способы получить контент статьи. http://en.wikipedia.org/wiki/Wikipedia:Database_download#Please_do_not_use_a_web_crawler – Cerin 2010-08-12 17:49:53

1

Попробуйте изменить заголовок агента пользователя, который вы отправляете в свой запрос, например: User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv: 1.9.0.1) Gecko/2008072820 Ubuntu /8.04 (hardy) Firefox/3.0.1 (Linux Mint)

1

Вам не нужно олицетворять пользовательский агент браузера; любой пользовательский агент вообще будет работать, просто не пустой.

+4

urllib и urllib2 оба отправляют агенту пользователя – Teifion 2008-09-23 09:58:42

+2

`s/blank/blank или default /` - идея в том, что вы должны каким-то образом идентифицировать своего бота через заголовок user-agent. Вот почему они блокируют «urllib» по умолчанию. – njsg 2012-02-16 10:29:09

36

Это не решение конкретной проблемы. Но для вас может быть интересным использовать библиотеку mwclient (http://botwiki.sno.cc/wiki/Python:Mwclient). Это было бы намного проще. Тем более, что вы сразу получите содержимое статьи, которое избавит вас от необходимости анализировать html.

Я сам использовал его для двух проектов, и он работает очень хорошо.

+4

Использование сторонних библиотек для того, что можно легко сделать с помощью библиотек buildin в парах строк кода, не является хорошим советом. – 2008-09-23 10:18:40

+17

Поскольку mwclient использует mediawiki api, это не требует синтаксического анализа содержимого. И я предполагаю, что оригинальный плакат хочет содержания, а не сырой html с меню и все такое. – 2008-09-23 10:52:45

2

Общее решение я использую для любого сайта, чтобы открыть страницу с помощью Firefox и, используя расширение, например Firebug, запишите все детали запроса HTTP, включая любые куки.

В вашей программе (в данном случае на Python) вы должны попытаться отправить HTTP-запрос как можно более похожий на тот, который работал с Firefox. Это часто включает настройку полей User-Agent, Referer и Cookie, но могут быть и другие.

14

Вместо того, чтобы пытаться обмануть Википедию, вам следует рассмотреть возможность использования их High-Level API.

3

Если вы пытаетесь получить доступ к содержимому Википедии (и не нуждаетесь в какой-либо конкретной информации о самой странице), вместо использования api вам следует просто вызвать index.php с помощью «action = raw», чтобы получить wikitext, как в:

http://ru.wikipedia.org/w/index.php? действие = сырой & название = Main_Page '

Или, если вы хотите, чтобы HTML-код, используйте 'действие = визуализации', как в:

' http://en.wikipedia.org/w/index .php? действия = оказывает & названия = Main_Page»

Вы также можете определить раздел, чтобы получить только часть содержания с чем-то вроде„раздела = 3“.

Вы можете получить к нему доступ с помощью модуля urllib2 (как сказано в выбранном ответе). Однако, если вам нужна информация о самой странице (например, ревизии), вам будет лучше использовать mwclient, как описано выше.

Если вам нужна дополнительная информация, обратитесь к MediaWiki's FAQ.

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

Это, похоже, работает для меня, не меняя агента пользователя. Без «action = raw» это не работает для меня.

2

requests это замечательно!

Вот как вы можете получить содержимое HTML с requests:

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

Готово!

0

Запрашивая страницу с помощью ?printable=yes, вы получите относительно чистый HTML-документ. ?action=render дает вам только HTML тела. Запрос на анализ страницы с помощью API-интерфейса MediaWiki с помощью action=parse также дает вам только HTML-код тела, но будет хорошо, если вы хотите более тонкий контроль, see parse API help.

Если вам просто нужен HTML-код страницы, чтобы вы могли его визуализировать, быстрее и лучше использовать новый API RESTBase, который возвращает кэшированное HTML-представление страницы. В этом случае https://en.wikipedia.org/api/rest_v1/page/html/Albert_Einstein.

С ноября 2015 года вам не нужно устанавливать свой пользовательский агент, но it's strongly encouraged. Кроме того, почти все Wikimedia wikis require HTTPS, поэтому избегайте перенаправления 301 и делайте http с запросами.

Смежные вопросы