Ich versuche, mich mit Python auf einer Website anzumelden und Informationen von mehreren Webseiten zu sammeln. Dabei wird die folgende Fehlermeldung angezeigt:
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
Ich habe verwendet time.sleep()
und es funktioniert, aber es scheint unintelligent und unzuverlässig. Gibt es eine andere Möglichkeit, diesem Fehler auszuweichen?
Hier ist mein 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
quelle
quelle
sleep
.Antworten:
Das Empfangen eines Status 429 ist kein Fehler . Der andere Server fordert Sie "freundlich" auf, die Spam-Anfragen zu beenden. Offensichtlich war Ihre Anforderungsrate zu hoch und der Server ist nicht bereit, dies zu akzeptieren.
Sie sollten nicht versuchen, dies "auszuweichen" oder sogar zu versuchen, die Server-Sicherheitseinstellungen zu umgehen, indem Sie versuchen, Ihre IP zu fälschen. Sie sollten einfach die Antwort des Servers respektieren, indem Sie nicht zu viele Anfragen senden.
Wenn alles richtig eingerichtet ist, haben Sie zusammen mit der 429-Antwort auch einen "Retry-after" -Header erhalten. Dieser Header gibt die Anzahl der Sekunden an, die Sie warten sollten, bevor Sie einen weiteren Anruf tätigen. Der richtige Weg, um mit diesem "Problem" umzugehen, besteht darin, diesen Header zu lesen und Ihren Prozess für so viele Sekunden auszuschalten.
Weitere Informationen zum Status 429 finden Sie hier: http://tools.ietf.org/html/rfc6585#page-3
quelle
HTTPError as my_exception
ist siemy_exception.headers
zumindest für urllib2 in verfügbar.Das Schreiben dieses Codes hat mein Problem behoben:
requests.get(link, headers = {'User-agent': 'your bot 0.1'})
quelle
Wie MRA sagte, sollten Sie nicht versuchen, einem auszuweichen,
429 Too Many Requests
sondern entsprechend damit umgehen. Abhängig von Ihrem Anwendungsfall haben Sie mehrere Möglichkeiten:1) Schlaf deinen Prozess . Der Server enthält normalerweise einen
Retry-after
Header in der Antwort mit der Anzahl der Sekunden, die Sie warten sollen, bevor Sie es erneut versuchen. Denken Sie daran, dass das Schlafen eines Prozesses Probleme verursachen kann, z. B. in einer Aufgabenwarteschlange, in der Sie die Aufgabe stattdessen zu einem späteren Zeitpunkt wiederholen sollten, um den Mitarbeiter für andere Dinge freizugeben.2) Exponentielles Backoff . Wenn der Server Ihnen nicht sagt, wie lange Sie warten sollen, können Sie Ihre Anfrage mit zunehmenden Pausen dazwischen wiederholen. In der beliebten Task-Warteschlange Sellerie ist diese Funktion direkt integriert .
3) Token-Eimer . Diese Technik ist nützlich, wenn Sie im Voraus wissen, wie viele Anfragen Sie in einer bestimmten Zeit stellen können. Jedes Mal, wenn Sie auf die API zugreifen, rufen Sie zuerst ein Token aus dem Bucket ab. Der Eimer wird mit konstanter Geschwindigkeit nachgefüllt. Wenn der Bucket leer ist, müssen Sie warten, bevor Sie die API erneut aufrufen. Token-Buckets werden normalerweise am anderen Ende (der API) implementiert. Sie können sie jedoch auch als Proxy verwenden, um zu vermeiden, dass Sie jemals einen erhalten
429 Too Many Requests
. Die rate_limit- Funktion von Celery verwendet einen Token-Bucket-Algorithmus.Hier ist ein Beispiel für eine Python / Sellerie-App mit exponentiellem Backoff und geschwindigkeitsbegrenzendem / Token-Bucket:
quelle
Eine andere Problemumgehung besteht darin, Ihre IP-Adresse mithilfe eines öffentlichen VPN- oder Tor-Netzwerks zu fälschen. Dies würde die Ratenbegrenzung auf dem Server auf IP-Ebene voraussetzen.
Es gibt einen kurzen Blog-Beitrag, der zeigt, wie man tor zusammen mit urllib2 verwendet:
http://blog.flip-edesign.com/?p=119
quelle