Я пытаюсь получить статью из Википедии с помощью 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
Википедия, похоже, блокирует запросы, поступающие не из стандартного браузера.
Кто-нибудь знает, как это обойти?






Попробуйте изменить заголовок пользовательского агента, который вы отправляете в своем запросе, на что-то вроде: Пользовательский агент: Mozilla / 5.0 (X11; U; Linux i686; en-US; rv: 1.9.0.1) Gecko / 2008072820 Ubuntu / 8.04 (надежный) Firefox / 3.0.1 (Linux Mint)
Вам не нужно олицетворять пользовательский агент браузера; любой пользовательский агент будет работать, только не пустой.
urllib и urllib2 отправляют пользовательский агент
s/blank/blank or default/ - идея как раз в том, что вы должны каким-то образом идентифицировать своего бота через заголовок пользовательского агента. Вот почему они блокируют стандартный urllib.
Это не решение конкретной проблемы. Но, возможно, вам будет интересно использовать вместо этого библиотеку mwclient (http://botwiki.sno.cc/wiki/Python:Mwclient). Это было бы намного проще. Тем более, что вы напрямую получите содержимое статьи, что избавит вас от необходимости разбирать HTML.
Я сам использовал его в двух проектах, и он работает очень хорошо.
Использование сторонних библиотек для того, что можно легко сделать с помощью встроенных библиотек, в пару строк кода - не лучший совет.
Поскольку mwclient использует mediawiki api, он не требует синтаксического анализа содержимого. И я предполагаю, что исходному плакату нужен контент, а не необработанный HTML с меню и всем остальным.
Вам необходимо использовать urllib2, который заменяет urllib в библиотека Python std, чтобы изменить пользовательский агент.
Прямо от Примеры
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()
Википедия не зря пытается заблокировать скребки экрана. Их серверам приходится проделать большую работу по преобразованию викикода в HTML, когда есть более простые способы получить содержание статьи. en.wikipedia.org/wiki/…
Вы не должны пытаться выдавать себя за браузер с помощью пользовательского агента, такого как Mozilla/5.0. Вместо этого вы должны использовать информативный пользовательский агент с некоторой контактной информацией.
Общее решение, которое я использую для любого сайта, - это получить доступ к странице с помощью Firefox и, используя расширение, такое как Firebug, записать все детали HTTP-запроса, включая любые файлы cookie.
В своей программе (в данном случае в Python) вы должны попытаться отправить HTTP-запрос, настолько похожий, насколько это необходимо, на тот, который работал в Firefox. Это часто включает настройку полей User-Agent, Referer и Cookie, но могут быть и другие.
Вместо того, чтобы пытаться обмануть Википедию, вам следует подумать об использовании их API высокого уровня.
Что, в свою очередь, по-прежнему будет блокировать запросы от urllib с использованием заголовка пользовательского агента по умолчанию. Таким образом, OP по-прежнему будет иметь ту же проблему, хотя API может быть более простым способом взаимодействия с содержимым вики, в зависимости от того, каковы цели OP.
У меня они работают нормально. Разве они не работают на вас? Пример: en.wikipedia.org/w/… или en.wikipedia.org/w/…
Если вы пытаетесь получить доступ к содержимому Википедии (и не нуждаетесь в какой-либо конкретной информации о самой странице), вместо использования api вы должны просто вызвать index.php с помощью 'action = raw', чтобы получить викитекст, например в:
'http://en.wikipedia.org/w/index.php?действие = сырье&title=Main_Page'
Или, если вам нужен HTML-код, используйте 'action = render', как в:
"http://en.wikipedia.org/w/index.php?действие = визуализация&title=Main_Page"
Вы также можете определить раздел, чтобы получить только часть контента, с чем-то вроде 'section = 3'.
Затем вы можете получить к нему доступ с помощью модуля urllib2 (как указано в выбранном ответе). Однако, если вам нужна информация о самой странице (например, версии), вам лучше использовать mwclient, как предложено выше.
Обратитесь к Часто задаваемые вопросы MediaWiki, если вам нужна дополнительная информация.
привет, если я не знаю номер раздела как 3, но я знаю, что заголовок раздела - «Существительное», как получить этот конкретный раздел?
import urllib
s = urllib.urlopen('http://en.wikipedia.org/w/index.php?action=raw&title=Albert_Einstein').read()
Кажется, это работает для меня без изменения пользовательского агента. Без "action = raw" у меня не работает.
Запрос страницы с помощью ?printable=yes дает вам полностью относительно чистый HTML-документ. ?action=render дает вам только основной HTML. Запрос на синтаксический анализ страницы через API действий MediaWiki с помощью action=parse также дает вам только основной HTML-код, но было бы хорошо, если вы хотите более точный контроль, см. справку по parse API.
Если вам просто нужен HTML-код страницы, чтобы вы могли его отобразить, быстрее и лучше будет использовать новый RESTBase API, который возвращает кешированное HTML-представление страницы. В этом случае https://en.wikipedia.org/api/rest_v1/page/html/Albert_Einstein.
По состоянию на ноябрь 2015 года вам не нужно устанавливать свой пользовательский агент, а только это настоятельно рекомендуется. Кроме того, почти все вики Викимедиа - это требуется HTTPS, поэтому избегайте перенаправления 301 и выполняйте запросы https.
Википедия не блокирует запросы не из стандартного браузера, а блокирует запросы из стандартных библиотек без изменения их пользовательского агента.