Cuando llega el tiempo de espera urllib2.request
, se produce una excepción de urllib2.URLError
. ¿Cuál es la manera pitónica de volver a intentar establecer una conexión?Cómo reintentar urllib2.request cuando falla?
Respuesta
Yo usaría un decorador retry. Hay otros por ahí, pero este funciona bastante bien. He aquí cómo usted puede utilizarlo:
@retry(urllib2.URLError, tries=4, delay=3, backoff=2)
def urlopen_with_retry():
return urllib2.urlopen("http://example.com")
Esto volverá a intentar la función si se eleva URLError
. Consulte el enlace de arriba para la documentación de los parámetros, pero básicamente lo intentará de nuevo un máximo de 4 veces, con un retardo de retroceso exponencial que se duplica cada vez, p. 3 segundos, 6 segundos, 12 segundos.
Este es un fragmento realmente genial. ¿Conoces una alternativa, pero como administrador de contexto? –
Hmm, creo que probablemente podría volver a escribirlo como un administrador de contexto con bastante facilidad, pero no tengo uno de manera informal. – jterrace
No es fácil de hacer, ya que no hay una manera fácil de capturar el bloque dentro de la instrucción with. Necesitas una profunda introspección. –
para reintentar el tiempo de espera se puede coger la excepción como @Karl Barker suggested in the comment:
assert ntries >= 1
for _ in range(ntries):
try:
page = urlopen(request, timeout=timeout)
break # success
except URLError as err:
if not isinstance(err.reason, socket.timeout):
raise # propagate non-timeout errors
else: # all ntries failed
raise err # re-raise the last timeout error
# use page here
Hay algunas bibliotecas por ahí que se especializan en esto.
Uno es backoff, que está diseñado con una sensibilidad particularmente funcional. Los decoradores reciben callables arbitrarios que devuelven generadores que producen valores de retardo sucesivos. Un retroceso exponencial simple con un tiempo máximo de reintentos de 32 segundos se podría definir como:
@backoff.on_exception(backoff.expo,
urllib2.URLError,
max_value=32)
def url_open(url):
return urllib2.urlopen("http://example.com")
Otra es retrying que tiene una funcionalidad muy similar pero una API donde reintento parámetros se especifican a modo de args de palabras clave predefinidas.
- 1. Obtener encabezados de solicitud para Urllib2.Request?
- 2. ¿Qué errores/excepciones debo manejar con urllib2.Request/urlopen?
- 3. Qué hace urllib2.Request (<url>) y cómo lo imprimo/lo veo
- 4. Cómo procesar WebResponse cuando .NET lanza WebException ((400) Bad Request)?
- 5. ¿Cómo imprimir más cuando falla la aserción?
- 6. ¿Cómo se permite a NHibernate reintentar transacciones bloqueadas cuando se usa sesión por solicitud?
- 7. tenedor: reintentar: Recurso temporalmente no disponible
- 8. Recuperar Número de mensaje JMS reintentar
- 9. Reintentar manualmente el trabajo en Delayed_job
- 10. Reintentar llamadas al método de manera genérica
- 11. reintentar una ruta migratoria fallado la migración
- 12. Disminución con urllib2
- 13. Cuando un objeto RAII falla al construir
- 14. Cómo detener las tareas de copia de MSBuild reintentar automáticamente
- 15. Diseñe mensajes personalizados cuando la validación falla
- 16. Python URLLib/URLLib2 POST
- 17. urllib2 leído a Unicode
- 18. urllib2 a la cadena
- 19. urllib2 y json
- 20. urllib2 con cookies
- 21. Node.js Https request Error
- 22. Python - urllib2 y cookielib
- 23. POST Request (Javascript)
- 24. node.js POST request
- 25. ¿Cómo encontrar un motivo cuando mkdir falla en PHP?
- 26. Cómo depurar un programa cuando falla sin excepción?
- 27. ¿Cómo manejar Realloc cuando falla debido a la memoria?
- 28. Usando JSON POST Request
- 29. http post request erlang
- 30. PHP SOAP HTTP Request
Esta pregunta debería responder la tuya: http://stackoverflow.com/questions/2712524/handling-urllib2s-timeout-python –
No pregunté cómo atrapar la expection. Quería saber si hay una forma pitónica de intentar establecer la conexión. – iTayb
Lo siento, asumí que el problema estaba en detectar que se había alcanzado el tiempo de espera, no en restablecer la conexión. ¿No podría llamar a urlopen() en el bloque de excepción? –