web-dev-qa-db-fra.com

Python `urllib2`: Pourquoi est-ce que je reçois l'erreur 403 quand je" urlopen "une page Wikipedia?

J'ai un bogue étrange lorsque j'essaie de urlopen une certaine page de Wikipedia. C'est la page:

http://en.wikipedia.org/wiki/OpenCola_(drink)

Ceci est la session Shell:

>>> f = urllib2.urlopen('http://en.wikipedia.org/wiki/OpenCola_(drink)')
Traceback (most recent call last):
  File "C:\Program Files\Wing IDE 4.0\src\debug\tserver\_sandbox.py", line 1, in <module>
    # Used internally for debug sandbox under external interpreter
  File "c:\Python26\Lib\urllib2.py", line 126, in urlopen
    return _opener.open(url, data, timeout)
  File "c:\Python26\Lib\urllib2.py", line 397, in open
    response = meth(req, response)
  File "c:\Python26\Lib\urllib2.py", line 510, in http_response
    'http', request, response, code, msg, hdrs)
  File "c:\Python26\Lib\urllib2.py", line 435, in error
    return self._call_chain(*args)
  File "c:\Python26\Lib\urllib2.py", line 369, in _call_chain
    result = func(*args)
  File "c:\Python26\Lib\urllib2.py", line 518, in http_error_default
    raise HTTPError(req.get_full_url(), code, msg, hdrs, fp)
urllib2.HTTPError: HTTP Error 403: Forbidden

Cela m'est arrivé sur deux systèmes différents sur des continents différents. Quelqu'un at-il une idée pourquoi cela se produit?

48
Ram Rachum

Wikipedias position est :

Récupération de données: les robots ne peuvent pas être utilisés pour récupérer du contenu en vrac pour toute utilisation pas directement lié à un approuvé tâche de bot. Cela inclut dynamiquement chargement de pages depuis un autre site Web, ce qui peut avoir pour conséquence que le site web soit sur la liste noire et définitivement refusée accès. Si vous souhaitez télécharger contenu en vrac ou miroir d'un projet, veuillez le faire en téléchargeant ou en hébergeant votre propre copie de notre base de données.

C'est pourquoi Python est bloqué. Vous êtes censé télécharger des sauvegardes de données .

Quoi qu'il en soit, vous pouvez lire des pages comme celle-ci dans Python 2:

req = urllib2.Request(url, headers={'User-Agent' : "Magic Browser"}) 
con = urllib2.urlopen( req )
print con.read()

Ou en Python 3:

import urllib
req = urllib.request.Request(url, headers={'User-Agent' : "Magic Browser"}) 
con = urllib.request.urlopen( req )
print con.read()
116
Jochen Ritzel

Pour résoudre ce problème, vous devez intercepter cette exception.

try:
    f = urllib2.urlopen('http://en.wikipedia.org/wiki/OpenCola_(drink)')
except urllib2.HTTPError, e:
    print e.fp.read()

Lorsque j'imprime le message résultant, il comprend les éléments suivants:

"Anglais

Nos serveurs connaissent actuellement un problème technique. C'est probablement temporaire et devrait être réparé bientôt . S'il vous plait, réessayez dans quelques minutes. "

10
S.Lott

Souvent, les sites Web filtrent l'accès en vérifiant si un agent utilisateur reconnu y accède. Wikipedia traite simplement votre script comme un bot et le rejette. Essayez d'usurper en tant que navigateur. Le lien suivant vous mène à un article pour vous montrer comment.

http://wolfprojects.altervista.org/changeua.php

5
Eli

Comme Jochen Ritzel l'a mentionné, Wikipedia bloque les robots.

Cependant, les robots ne seront pas bloqués s'ils utilisent l'api PHP . Pour obtenir la page Wikipedia intitulée "love":

http://en.wikipedia.org/w/api.php?format=json&action=query&titles=love&prop=revisions&rvprop=content

1
Hello World

Certains sites Web vont bloquer l'accès aux scripts pour éviter une utilisation "inutile" de leurs serveurs en lisant les en-têtes envoyés par urllib. Je ne sais pas et je ne peux pas imaginer pourquoi wikipedia le ferait ou le ferait, mais avez-vous essayé d'usurper vos en-têtes?

1
Chris Foster

J'ai fait une solution de contournement pour cela en utilisant php qui n'est pas bloqué par le site dont j'avais besoin.

on peut y accéder comme ceci:

path='http://phillippowers.com/redirects/get.php? 
file=http://website_you_need_to_load.com'
req = urllib2.Request(path)
response = urllib2.urlopen(req)
vdata = response.read()

Cela vous retournera le code html 

0
Phil