No meu script, requests.get
nunca retorna:
import requests
print ("requesting..")
# This call never returns!
r = requests.get(
"http://www.some-site.com",
proxies = {'http': '222.255.169.74:8080'},
)
print(r.ok)
Quais poderiam ser os possíveis motivos? Qualquer remédio? Qual é o tempo limite padrão get
usado?
python
get
python-requests
Nawaz
fonte
fonte
proxies={'http': 'http://222.255.169.74:8080'}
. Pode ser por isso que ele não está sendo concluído sem um tempo limite.Respostas:
O tempo limite padrão é
None
, o que significa que ele aguardará (travará) até que a conexão seja fechada.O que acontece quando você passa um valor de tempo limite?
fonte
None
significa infinito (ou "espere até que a conexão seja fechada"). Se eu mesmo passar o tempo limite, ele retorna!print(requests.request.__doc__)
em IPython é mais do que eu estava procurando. Eu estava me perguntando quais outros argumentos opcionaisrequest.get()
existiam.Da documentação dos pedidos :
Acontece muito comigo que o request.get () leva muito tempo para retornar, mesmo que
timeout
seja 1 segundo. Existem algumas maneiras de superar esse problema:1. Use a
TimeoutSauce
classe internaDe: https://github.com/kennethreitz/requests/issues/1928#issuecomment-35811896
2. Use uma bifurcação de solicitações de kevinburke: https://github.com/kevinburke/requests/tree/connect-timeout
De sua documentação: https://github.com/kevinburke/requests/blob/connect-timeout/docs/user/advanced.rst
OBSERVAÇÃO: A alteração foi mesclada ao projeto principal de Solicitações .
3. Usando
evenlet
ousignal
conforme já mencionado na pergunta semelhante: Tempo limite para solicitações python.get resposta inteirafonte
Eu queria um tempo limite padrão facilmente adicionado a um monte de código (presumindo que o tempo limite resolva seu problema)
Esta é a solução que peguei em um tíquete enviado ao repositório de solicitações.
crédito: https://github.com/kennethreitz/requests/issues/2011#issuecomment-477784399
A solução está no último par de linhas aqui, mas mostro mais código para um melhor contexto. Gosto de usar uma sessão para repetir o comportamento.
então você pode fazer algo assim:
fonte
Reviu todas as respostas e chegou à conclusão que o problema ainda existe. Em alguns sites, as solicitações podem travar infinitamente e usar o multiprocessamento parece ser um exagero. Esta é minha abordagem (Python 3.5+):
ATUALIZAR
Se você receber um aviso de depreciação sobre o uso conn_timeout e read_timeout, verificação perto da parte inferior ESTE referência para como usar a estrutura de dados ClientTimeout. Uma maneira simples de aplicar essa estrutura de dados de acordo com a referência vinculada ao código original acima seria:
fonte
Corrigir a função "enviar" documentada irá consertar isso para todos os pedidos - mesmo em muitas bibliotecas dependentes e sdk's. Ao corrigir as libs, certifique-se de corrigir as funções suportadas / documentadas, não o TimeoutSauce - caso contrário, você pode acabar perdendo silenciosamente o efeito do seu patch.
Os efeitos de não haver nenhum tempo limite são bastante graves, e o uso de um tempo limite padrão quase nunca pode interromper nada - porque o próprio TCP também tem tempos limite padrão.
fonte
No meu caso, o motivo de "requests.get never Return" é porque a
requests.get()
tentativa de conectar ao host resolveu primeiro com ipv6 . Se algo deu errado ao conectar esse ipv6 e travar, ele tentará novamente o ipv4 apenas se eu definir explicitamentetimeout=<N seconds>
e atingir o tempo limite.Minha solução é fazer um monkey-patching no python
socket
para ignorar o ipv6 (ou ipv4 se o ipv4 não funcionar), ou esta resposta ou esta resposta funcionam para mim.Você deve estar se perguntando por que o
curl
comando funciona, porquecurl
conecte o ipv4 sem esperar que o ipv6 seja concluído. Você pode rastrear as syscalls de soquete com ostrace -ff -e network -s 10000 -- curl -vLk '<your url>'
comando. Para python, ostrace -ff -e network -s 10000 -- python3 <your python script>
comando pode ser usado.fonte