J'essaie d'utiliser Python pour me connecter à un site Web et recueillir des informations à partir de plusieurs pages Web et j'obtiens l'erreur suivante:
Traceback (most recent call last): File "extract_test.py", line 43, in <module> response=br.open(v) File "/usr/local/lib/python2.7/dist-packages/mechanize/_mechanize.py", line 203, in open return self._mech_open(url, data, timeout=timeout) File "/usr/local/lib/python2.7/dist-packages/mechanize/_mechanize.py", line 255, in _mech_open raise response mechanize._response.httperror_seek_wrapper: HTTP Error 429: Unknown Response Code
Je l'ai utilisé time.sleep()
et cela fonctionne, mais cela semble inintelligent et peu fiable, y a-t-il un autre moyen d'éviter cette erreur?
Voici mon code:
import mechanize
import cookielib
import re
first=("example.com/page1")
second=("example.com/page2")
third=("example.com/page3")
fourth=("example.com/page4")
## I have seven URL's I want to open
urls_list=[first,second,third,fourth]
br = mechanize.Browser()
# Cookie Jar
cj = cookielib.LWPCookieJar()
br.set_cookiejar(cj)
# Browser options
br.set_handle_equiv(True)
br.set_handle_redirect(True)
br.set_handle_referer(True)
br.set_handle_robots(False)
# Log in credentials
br.open("example.com")
br.select_form(nr=0)
br["username"] = "username"
br["password"] = "password"
br.submit()
for url in urls_list:
br.open(url)
print re.findall("Some String")
python
http
mechanize
http-status-code-429
Aous1000
la source
la source
sleep
.Réponses:
Recevoir un statut 429 n'est pas une erreur , c'est l'autre serveur "gentiment" qui vous demande d'arrêter les demandes de spam. De toute évidence, votre taux de requêtes a été trop élevé et le serveur n'est pas disposé à accepter cela.
Vous ne devez pas chercher à «esquiver» cela, ni même essayer de contourner les paramètres de sécurité du serveur en essayant d'usurper votre adresse IP, vous devez simplement respecter la réponse du serveur en n'envoyant pas trop de requêtes.
Si tout est configuré correctement, vous aurez également reçu un en-tête "Retry-after" avec la réponse 429. Cet en-tête spécifie le nombre de secondes que vous devez attendre avant d'effectuer un autre appel. La bonne façon de traiter ce "problème" est de lire cet en-tête et de mettre votre processus en veille pendant autant de secondes.
Vous pouvez trouver plus d'informations sur le statut 429 ici: http://tools.ietf.org/html/rfc6585#page-3
la source
HTTPError as my_exception
, il est disponible dansmy_exception.headers
, au moins pour urllib2.L'écriture de ce morceau de code a résolu mon problème:
requests.get(link, headers = {'User-agent': 'your bot 0.1'})
la source
Comme MRA l'a dit, vous ne devriez pas essayer d'esquiver un
429 Too Many Requests
mais plutôt le gérer en conséquence. Vous avez plusieurs options en fonction de votre cas d'utilisation:1) Mettez votre processus en veille . Le serveur inclut généralement un en-
Retry-after
tête dans la réponse avec le nombre de secondes que vous êtes censé attendre avant de réessayer. Gardez à l'esprit que la mise en veille d'un processus peut causer des problèmes, par exemple dans une file d'attente de tâches, où vous devriez plutôt réessayer la tâche plus tard pour libérer le worker pour d'autres choses.2) Réduction exponentielle . Si le serveur ne vous dit pas combien de temps attendre, vous pouvez réessayer votre demande en augmentant les pauses entre les deux. La tâche populaire file d' attente Céleri a cette fonctionnalité intégrée à droite dans .
3) Seau à jetons . Cette technique est utile si vous savez à l'avance combien de demandes vous êtes en mesure de faire dans un temps donné. Chaque fois que vous accédez à l'API, vous récupérez d'abord un jeton dans le compartiment. Le seau est rempli à un débit constant. Si le compartiment est vide, vous savez que vous devrez attendre avant de toucher à nouveau l'API. Les buckets de jetons sont généralement implémentés à l'autre extrémité (l'API), mais vous pouvez également les utiliser comme proxy pour éviter d'obtenir un fichier
429 Too Many Requests
. La fonctionnalité rate_limit de Celery utilise un algorithme de seau à jetons.Voici un exemple d'application Python / Celery utilisant une interruption exponentielle et un compartiment de limitation de débit / de jetons:
la source
Une autre solution de contournement serait d'usurper votre adresse IP en utilisant une sorte de réseau VPN public ou Tor. Cela supposerait la limitation de débit sur le serveur au niveau IP.
Il y a un bref article de blog montrant une façon d'utiliser tor avec urllib2:
http://blog.flip-edesign.com/?p=119
la source
la source