Estou tentando usar Python para fazer login em um site e reunir informações de várias páginas da web e recebo o seguinte erro:
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
Usei time.sleep()
e funciona, mas parece pouco inteligente e confiável, existe alguma outra maneira de evitar esse erro?
Este é meu código:
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
fonte
fonte
sleep
.Respostas:
Receber um status 429 não é um erro , é o outro servidor "gentilmente" pedindo que você pare de enviar solicitações de spam. Obviamente, sua taxa de solicitações tem sido muito alta e o servidor não está disposto a aceitar isso.
Você não deve tentar "se esquivar" disso, ou mesmo tentar burlar as configurações de segurança do servidor tentando falsificar seu IP; você deve simplesmente respeitar a resposta do servidor, não enviando muitas solicitações.
Se tudo estiver configurado corretamente, você também receberá um cabeçalho "Tentar novamente depois" junto com a resposta 429. Este cabeçalho especifica o número de segundos que você deve esperar antes de fazer outra chamada. A maneira adequada de lidar com esse "problema" é ler este cabeçalho e colocar o processo em espera por tantos segundos.
Você pode encontrar mais informações sobre o status 429 aqui: http://tools.ietf.org/html/rfc6585#page-3
fonte
HTTPError as my_exception
, ele está disponível emmy_exception.headers
, pelo menos para urllib2.Escrever este trecho de código corrigiu meu problema:
requests.get(link, headers = {'User-agent': 'your bot 0.1'})
fonte
Como disse o MRA, você não deve tentar se esquivar de um,
429 Too Many Requests
mas lidar com ele de acordo. Você tem várias opções, dependendo do seu caso de uso:1) Durma seu processo . O servidor geralmente inclui um
Retry-after
cabeçalho na resposta com o número de segundos que você deve esperar antes de tentar novamente. Lembre-se de que suspender um processo pode causar problemas, por exemplo, em uma fila de tarefas, onde você deve repetir a tarefa mais tarde para liberar o trabalhador para outras coisas.2) Backoff exponencial . Se o servidor não informar quanto tempo você deve esperar, você pode repetir a solicitação usando pausas crescentes no meio. A popular fila de tarefas do Celery tem esse recurso integrado .
3) Balde de token . Essa técnica é útil se você sabe com antecedência quantas solicitações pode fazer em um determinado momento. Cada vez que você acessa a API, primeiro você busca um token do intervalo. O balde é reabastecido a uma taxa constante. Se o balde estiver vazio, você sabe que terá que esperar antes de acessar a API novamente. Os depósitos de token geralmente são implementados na outra extremidade (a API), mas você também pode usá-los como um proxy para evitar a obtenção de um
429 Too Many Requests
. O recurso rate_limit do Celery usa um algoritmo de token bucket.Aqui está um exemplo de um aplicativo Python / Celery usando backoff exponencial e limitação de taxa / token bucket:
fonte
Outra solução alternativa seria falsificar seu IP usando algum tipo de VPN pública ou rede Tor. Isso pressupõe a limitação de taxa no servidor no nível de IP.
Há uma breve postagem no blog que demonstra uma maneira de usar tor junto com urllib2:
http://blog.flip-edesign.com/?p=119
fonte
fonte