2011-04-06 12 views
12

que estoy usando Python's urllib2 para enviar un mensaje HTTP:cuelga detecta con Python urllib2.urlopen

import socket, urllib, urllib2 

socket.setdefaulttimeout(15)  

postdata = urllib.urlencode({'value1' : 'a string', 'value2' : 'another string'}) 
headers = { 
    'User-Agent': 'Agent', 
    'Content-Type': 'application/x-www-form-urlencoded', 
    'Accept': 'text/html, */*', 
} 

try: 
    request = urllib2.Request('http://www.example.com', postData, headers) 
    response = urllib2.urlopen(request) 
except urllib2.HTTPError, e: 
    # Handle here 
except urllib2.URLError, e: 
    # Handle here 
except httplib.HTTPException, e: 
    # Handle here 

De vez en cuando un problema de red da lugar a la llamada a urlopen no volver nunca. Vemos otros errores (incluidos los tiempos de espera) manejados correctamente por el bloque except y tenemos una llamada a socket.setdefaulttimeout() pero todavía hay casos en que el urlopen nunca volverá.

Sé que nunca volverá porque tenemos algunas líneas de registro en nuestro código real que se llaman antes y después, y cuando este problema ocurre, solo se realizan las llamadas anteriores y el script se cuelga para siempre.

¿Cuál es la mejor manera de detectar/manejar esto?

+0

¿Está modificando el tiempo de espera del socket predeterminado que no funciona para usted? – jathanism

+0

Tengo el mismo problema contigo, ¿lo has resuelto? – ajaxhe

Respuesta

9

Puede utilizar las señales, establezca primero un controlador para su señal

import signal 
... 
def handler(signum, frame): 
    print 'Signal handler called with signal', signum 
... 
signal.signal(signal.SIGALRM, handler) 

y poner una alarma justo antes de la llamada urlopen

signal.alarm(5) 
response = urllib2.urlopen(request) 
signal.alarm(0) # Disable the signal 

después de 5 segundos (o el tiempo que desee) el sistema operativo llamará al controlador si la alarma no está desactivada (si nunca vuelve a abrir). Más información sobre el módulo de señal: http://docs.python.org/library/signal.html

+1

... y luego en el controlador puedo lanzar una excepción que será capturada por el bloque try/except externo. – DavidM

+2

Esto NO funciona en Windows ('signal.alarm()' no es compatible) –

+1

@Sebastien, [aquí] (http://stackoverflow.com/questions/644073/signal-alarm-replacement-in-windows-python) puede encontrar una discusión sobre signal.alarm() en sistemas Windows – Manuel

Cuestiones relacionadas