Получить статью из Википедии с помощью Python
-
02-07-2019 - |
Вопрос
Я пытаюсь получить статью в Википедии с помощью 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 в стандартная библиотека Python чтобы сменить пользовательский агент.
Прямо из Примеры
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.
Я сам использовал его для двух проектов, и он работает очень хорошо.
Вместо того, чтобы пытаться обмануть Википедию, вам следует рассмотреть возможность использования их API высокого уровня.
Если вы пытаетесь получить доступ к содержимому Википедии (и вам не нужна какая-либо конкретная информация о самой странице), вместо использования API вам следует просто вызвать index.php с 'action=raw', чтобы получить викитекст, например в:
'http://en.wikipedia.org/w/index.php?действие = сырой&title=Главная_страница'
Или, если вам нужен HTML-код, используйте «action=render», например:
'http://en.wikipedia.org/w/index.php?действие = рендеринг&title=Главная_страница'
Вы также можете определить раздел, чтобы получить только часть контента, например, «section=3».
Затем вы можете получить к нему доступ с помощью модуля urllib2 (как предложено в выбранном ответе).Однако, если вам нужна информация о самой странице (например, об изменениях), вам лучше использовать mwclient, как предложено выше.
Ссылаться на Часто задаваемые вопросы MediaWiki если вам нужна дополнительная информация.
Общее решение, которое я использую для любого сайта, — получить доступ к странице с помощью Firefox и с помощью расширения, такого как Firebug, записать все детали HTTP-запроса, включая любые файлы cookie.
В вашей программе (в данном случае на Python) вам следует попытаться отправить HTTP-запрос, максимально похожий на тот, который работал из Firefox.Часто это включает в себя настройку полей User-Agent, Referer и Cookie, но могут быть и другие.
requests
это превосходно!
Вот как вы можете получить html-контент с помощью requests
:
import requests
html = requests.get('http://en.wikipedia.org/w/index.php?title=Albert_Einstein&printable=yes').text
Сделанный!
Попробуйте изменить заголовок пользовательского агента, который вы отправляете в своем запросе, на что-то вроде:Пользователь-Агент:Мозилла/5.0 (X11;У;Linux i686;ru-США;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()
Кажется, это работает для меня без изменения пользовательского агента.Без «action=raw» у меня не работает.
Запрос страницы с ?printable=yes
дает вам целый относительно чистый HTML-документ. ?action=render
дает вам только HTML-код тела.Запрос на анализ страницы через API действий MediaWiki с помощью action=parse
аналогично дает вам только HTML-код тела, но было бы хорошо, если вы хотите более точный контроль, см. справку по API синтаксического анализа.
Если вам просто нужен HTML-код страницы, чтобы вы могли его отобразить, быстрее и лучше использовать новый RESTBase API, который возвращает кэшированное HTML-представление страницы.В этом случае, https://en.wikipedia.org/api/rest_v1/page/html/Альберт_Эйнштейн.
С ноября 2015 г. вам не нужно устанавливать пользовательский агент, но это настоятельно рекомендуется.Кроме того, почти все вики Викимедиа требуется HTTPS, поэтому избегайте перенаправления 301 и сделайте httpс Запросы.