2008-09-23 15 views
37

ich versuche, einen Wikipedia-Artikel mit Pythons urllib zu holen:Holt einen Wikipedia-Artikel mit Python

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

jedoch anstelle der HTML-Seite, die ich die folgende Antwort erhalten: Fehler - 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 

Wikipedia scheint Anfragen zu blockieren, die nicht von einem Standard-Browser stammen.

Weiß jemand, wie man das umgeht?

+3

Wikipedia blockiert keine Anforderungen, die nicht von einem Standard-Browser stammen, es blockiert Anfragen, die von Standardbibliotheken stammen, ohne ihren Benutzeragenten zu ändern. – svick

Antwort

50

Sie müssen die urllib2 verwenden, die urllib in der python std library übergeordnet ist, um den Benutzer-Agent zu ändern.

Gerade vom 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

Wikipedia versucht, Screen Scraper aus einem bestimmten Grund zu blockieren. Ihre Server müssen viel arbeiten, um Wikikode in HTML zu konvertieren, wenn es leichtere Möglichkeiten gibt, den Artikelinhalt zu bekommen. http://en.wikipedia.org/wiki/Wikipedia:Database_download#Please_do_not_use_a_web_crawler – Cerin

+1

Sie sollten nicht versuchen, einen Browser mit einem Benutzer-Agent wie 'Mozilla/5.0' zu imitieren. Stattdessen sollten Sie [einen informativen Benutzeragenten mit einigen Kontaktinformationen verwenden] (http://meta.wikimedia.org/wiki/User-Agent_policy). – svick

+0

Und die meisten Bots sollten "robots.txt" lesen und respektieren. – Bryce

1

Versuchen Sie, die User-Agent-Header zu ändern Sie in Ihrer Anfrage zu so etwas wie senden: User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv: 1.9.0.1) Gecko/2008072820 Ubuntu /8.04 (robust) Firefox/3.0.1 (Linux Mint)

1

Sie müssen sich nicht als Browser-User-Agent ausgeben; jeder User-Agent wird überhaupt funktionieren, nur kein leerer.

+4

urllib und urllib2 senden beide einen User-Agent – Teifion

+2

's/leer/leer oder default /' - die Idee ist genau, dass Sie Ihren Bot irgendwie über den User-Agent-Header identifizieren sollten. Deshalb blockieren sie die 'urllib'-Standard-Einstellung. – njsg

36

Es ist keine Lösung für das spezifische Problem. Es könnte aber interessant sein, stattdessen die mwclient-Bibliothek() zu verwenden. Das wäre so viel einfacher. Vor allem, weil Sie den Inhalt des Artikels direkt erhalten, wodurch Sie den HTML-Code nicht mehr analysieren müssen.

Ich habe es selbst für zwei Projekte verwendet, und es funktioniert sehr gut.

+4

Die Verwendung von Drittanbieter-Bibliotheken für das, was mit Builtin-Bibliotheken in ein paar Zeilen Code leicht gemacht werden kann, ist kein guter Rat. –

+17

Da mwclient das mediawiki api verwendet, muss der Inhalt nicht analysiert werden. Und ich vermute, das ursprüngliche Poster will den Inhalt, und nicht das rohe HTML mit Menüs und allem. –

2

Die allgemeine Lösung, die ich für jede Website verwenden ist auf die Seite zuzugreifen unter Verwendung von Firefox und eine Erweiterung wie Firebug, erfassen alle Details der HTTP-Anforderung einschließlich Cookies.

In Ihrem Programm (in diesem Fall in Python) sollten Sie versuchen, eine HTTP-Anfrage zu senden, die der von Firefox ähnlich ist. Dazu gehören häufig die Felder User-Agent, Referer und Cookie, aber möglicherweise auch andere.

14

Anstatt zu versuchen, Wikipedia zu überlisten, sollten Sie ihre High-Level API verwenden.

+0

Diese wiederum blockiert weiterhin Anfragen von 'urllib' unter Verwendung des Bibliotheks-Standard-User-Agent-Headers. Daher wird das OP immer noch das gleiche Problem haben, obwohl die API eine einfachere Möglichkeit ist, den Wiki-Inhalt zu verlinken, abhängig davon, was die OP-Ziele sind. – njsg

+0

Sie funktionieren gut für mich. Arbeiten sie nicht für dich? Ex: http://en.wikipedia.org/w/api.php?format=xml&action=query&prop=info&titles=Main%20Page oder http://en.wikipedia.org/w/api.php?format=xml&action= query & titles = Main% 20Page & prop = revisions & rvprop = Inhalt – sligocki

3

Falls Sie versuchen, auf Wikipedia-Inhalte zuzugreifen (und keine spezifischen Informationen über die Seite selbst benötigen), sollten Sie index.php einfach mit 'action = raw' aufrufen, um die API zu erhalten der wikitext, wie in:

'http://en.wikipedia.org/w/index.php? action = raw & title = Main_Page '

Oder, wenn Sie die HTML-Code, verwenden wollen 'action = machen' wie in:

' http://en.wikipedia.org/w/index .php? action = render & title = Main_Page‘

Sie können auch einen Abschnitt definieren nur ein Teil des Inhalts mit so etwas wie zu bekommen 'section = 3'.

Sie können dann mit dem Modul urllib2 darauf zugreifen (wie in der gewählten Antwort enthalten). Wenn Sie jedoch Informationen über die Seite selbst (z. B. Revisionen) benötigen, verwenden Sie besser den mwclient wie oben beschrieben.

Weitere Informationen finden Sie unter MediaWiki's FAQ.

+0

Hallo, wenn ich die Abschnittsnummer nicht als 3 kenne, aber ich weiß, dass der Abschnittstitel "Substantiv" lautet, wie bekomme ich diesen bestimmten Abschnitt? – emaillenin

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

Dies scheint für mich zu arbeiten, ohne den Benutzer-Agent zu ändern. Ohne die "Aktion = roh" funktioniert es nicht für mich.

2

requests ist genial!

Hier ist, wie Sie den HTML-Inhalt mit requests zu bekommen:

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

Fertig!

0

Wenn Sie die Seite mit ?printable=yes anfordern, erhalten Sie ein relativ sauberes HTML-Dokument. ?action=render gibt Ihnen nur den Körper HTML. Anfordern, die Seite durch die MediaWiki-Aktions-API mit action=parse zu analysieren, gibt Ihnen ebenfalls nur den Body HTML, wäre aber gut, wenn Sie feinere Kontrolle wünschen, see parse API help.

Wenn Sie nur die Seite HTML möchten, damit Sie sie rendern können, ist es schneller und besser, die neue RESTBase API zu verwenden, die eine zwischengespeicherte HTML-Darstellung der Seite zurückgibt. In diesem Fall https://en.wikipedia.org/api/rest_v1/page/html/Albert_Einstein.

Ab November 2015 müssen Sie nicht Ihren User-Agent, sondern it's strongly encouraged einstellen. Auch, fast alle Wikimedia Wikis require HTTPS, so vermeiden Sie eine 301 Redirect und machen http s Anfragen.