Estoy recopilando estadísticas en una lista de sitios web y estoy usando solicitudes para simplificar. Aquí está mi código:
data=[]
websites=['http://google.com', 'http://bbc.co.uk']
for w in websites:
r= requests.get(w, verify=False)
data.append( (r.url, len(r.content), r.elapsed.total_seconds(), str([(l.status_code, l.url) for l in r.history]), str(r.headers.items()), str(r.cookies.items())) )
Ahora, quiero requests.get
agotar el tiempo de espera después de 10 segundos para que el ciclo no se atasque.
Esta pregunta también ha sido de interés anteriormente, pero ninguna de las respuestas es clara. Voy a poner algo de recompensa en esto para obtener una buena respuesta.
Escuché que tal vez no usar solicitudes es una buena idea, pero entonces, ¿cómo debo obtener las cosas buenas que ofrecen las solicitudes? (los de la tupla)
python
timeout
python-requests
Kiarash
fuente
fuente
Respuestas:
¿Qué pasa con el uso de eventlet? Si desea agotar el tiempo de espera de la solicitud después de 10 segundos, incluso si se reciben datos, este fragmento funcionará para usted:
fuente
eventlet.monkey_patch()
requiere?socket
módulo debe ser parcheado, así que al menos necesitarás uneventlet.monkey_patch(socket=True)
requests.get('https://github.com', timeout=5)
Establezca el parámetro de tiempo de espera :
Siempre que no establezca
stream=True
esa solicitud, esto hará que la llamada serequests.get()
agote si la conexión demora más de diez segundos o si el servidor no envía datos durante más de diez segundos.fuente
ACTUALIZACIÓN: https://requests.readthedocs.io/en/master/user/advanced/#timeouts
En nueva versión de
requests
:Si especifica un valor único para el tiempo de espera, así:
El valor del tiempo de espera se aplicará tanto a
connect
losread
tiempos de espera como a los tiempos de espera. Especifique una tupla si desea establecer los valores por separado:Si el servidor remoto es muy lento, puede indicarle a Solicitudes que esperen una respuesta para siempre, pasando Ninguno como valor de tiempo de espera y luego recuperando una taza de café.
Mi respuesta anterior (probablemente desactualizada) (que se publicó hace mucho tiempo):
Hay otras formas de superar este problema:
1. Usa la
TimeoutSauce
clase internaDe: https://github.com/kennethreitz/requests/issues/1928#issuecomment-35811896
2. Use una bifurcación de solicitudes de kevinburke: https://github.com/kevinburke/requests/tree/connect-timeout
De su documentación: https://github.com/kevinburke/requests/blob/connect-timeout/docs/user/advanced.rst
kevinburke ha solicitado que se fusione con el proyecto de solicitudes principales, pero aún no ha sido aceptado.
fuente
this won't work for you use-case
. Él quiso decir que no funciona con la transmisión de mp3 que el otro chico quiere.timeout = int(seconds)
Desde entonces
requests >= 2.4.0
, puede usar eltimeout
argumento, es decir:Nota:
fuente
Para crear un tiempo de espera puede usar señales .
La mejor manera de resolver este caso es probablemente
try-except-finally
bloque.Aquí hay un código de ejemplo:
Hay algunas advertencias sobre esto:
¡Pero todo está en la biblioteca estándar de Python! Excepto por la función de suspensión de importación, es solo una importación. Si va a utilizar tiempos de espera en muchos lugares, puede poner fácilmente TimeoutException, _timeout y singaling en una función y simplemente llamar a eso. O puede hacer un decorador y ponerlo en funciones, vea la respuesta vinculada a continuación.
También puede configurar esto como un "administrador de contexto" para que pueda usarlo con la
with
declaración:Un posible inconveniente con este enfoque de administrador de contexto es que no puede saber si el código realmente agotó el tiempo de espera o no.
Fuentes y lecturas recomendadas:
fuente
Pruebe esta solicitud con tiempo de espera y manejo de errores:
fuente
Establecer
stream=True
y usarr.iter_content(1024)
. Sí, deeventlet.Timeout
alguna manera no funciona para mí.La discusión está aquí https://redd.it/80kp1h
fuente
Esto puede ser excesivo, pero la cola de tareas distribuidas de Celery tiene un buen soporte para los tiempos de espera.
En particular, puede definir un límite de tiempo flexible que simplemente genera una excepción en su proceso (para que pueda limpiar) y / o un límite de tiempo difícil que finaliza la tarea cuando se ha excedido el límite de tiempo.
Debajo de las cubiertas, esto utiliza el mismo enfoque de señales que se menciona en su publicación "anterior", pero de una manera más útil y manejable. Y si la lista de sitios web que está monitoreando es larga, podría beneficiarse de su característica principal: todo tipo de formas de administrar la ejecución de una gran cantidad de tareas.
fuente
python-requests
sino conhttplib
(utilizado por las solicitudes de Python 2.7). El paquete pasa todo lo relacionadotimeout
directamente a httplib. Creo que nada se puede arreglar en la solicitud porque el proceso puede permanecer durante mucho tiempo en httplib.Creo que puede usar
multiprocessing
y no depender de un paquete de terceros:El tiempo de espera pasado
kwargs
es el tiempo de espera para obtener cualquier respuesta del servidor, el argumentotimeout
es el tiempo de espera para obtener la respuesta completa .fuente
tiempo de espera = (tiempo de espera de conexión, tiempo de espera de lectura de datos) o dar un único argumento (tiempo de espera = 1)
fuente
este código funciona para socketError 11004 y 10060 ......
fuente
A pesar de que la pregunta es sobre solicitudes, me parece muy fácil hacerlo con pycurl CURLOPT_TIMEOUT o CURLOPT_TIMEOUT_MS.
No se requiere roscado ni señalización:
fuente
En caso de que esté utilizando la opción
stream=True
, puede hacer esto:La solución no necesita señales ni multiprocesamiento.
fuente
Solo otra solución (la obtuve de http://docs.python-requests.org/en/master/user/advanced/#streaming-uploads )
Antes de subir, puede averiguar el tamaño del contenido:
Pero tenga cuidado, un remitente puede configurar un valor incorrecto en el campo de respuesta 'longitud de contenido'.
fuente
Si se trata de eso, cree un hilo de vigilancia que arruine el estado interno de las solicitudes después de 10 segundos, por ejemplo:
Tenga en cuenta que, según las bibliotecas del sistema, es posible que no pueda establecer una fecha límite para la resolución de DNS.
fuente
Bueno, probé muchas soluciones en esta página y seguí enfrentando inestabilidades, bloqueos aleatorios, mal rendimiento de las conexiones.
Ahora estoy usando Curl y estoy muy contento con su funcionalidad de "tiempo máximo" y con el rendimiento global, incluso con una implementación tan pobre:
Aquí, definí un parámetro de tiempo máximo de 6 segundos, que abarca tanto el tiempo de conexión como el de transferencia.
Estoy seguro de que Curl tiene un buen enlace de python, si prefiere seguir con la sintaxis pitónica :)
fuente
Hay un paquete llamado timeout-decorator que puede usar para agotar el tiempo de cualquier función de Python.
Utiliza el enfoque de señales que sugieren algunas respuestas aquí. Alternativamente, puede indicarle que use multiprocesamiento en lugar de señales (por ejemplo, si se encuentra en un entorno de subprocesos múltiples).
fuente
Estoy usando las solicitudes 2.2.1 y eventlet no funcionó para mí. En cambio, pude usar el tiempo de espera gevent ya que gevent se usa en mi servicio para gunicorn.
Tenga en cuenta que gevent.timeout.Timeout no se detecta mediante el manejo general de excepciones. Entonces, explícitamente, atrape
gevent.timeout.Timeout
o pase una excepción diferente para usarla así:with gevent.Timeout(5, requests.exceptions.Timeout):
aunque no se pasa ningún mensaje cuando se genera esta excepción.fuente
Se me ocurrió una solución más directa que es ciertamente fea pero soluciona el problema real. Va un poco así:
Puedes leer la explicación completa aquí
fuente
timeout
parámetrosrequests.get()
sin soluciones feas 2- aunque ambos no limitarán el tiempo de espera total a diferenciaeventlet.Timeout(10)