délai d'attente pour urllib2.urlopen () en pré Python versions 2.6
Question
Le documentation urllib2 dit que délai d'attente paramètre a été ajouté en Python 2.6. Malheureusement, ma base de code a été exécuté sur Python 2.5 et 2.4 plates-formes.
Y at-il autre façon de simuler le délai d'attente? Tout ce que je veux faire est de permettre le code de parler le serveur distant pour un montant fixe de temps.
Peut-être une solution de rechange intégrée dans la bibliothèque? (Vous ne voulez pas installer 3ème partie, comme pycurl)
La solution
vous pouvez définir un délai global pour toutes les opérations de socket (y compris les requêtes HTTP) en utilisant:
comme ceci:
import urllib2
import socket
socket.setdefaulttimeout(30)
f = urllib2.urlopen('http://www.python.org/')
dans ce cas, votre demande de urllib2 n'expire au bout de 30 secondes et lancer une exception prise. (Ce qui a été ajouté en Python 2.3)
Autres conseils
Avec une grande irritation, vous pouvez remplacer la classe httplib.HTTPConnection que le urllib2.HTTPHandler utilise.
def urlopen_with_timeout(url, data=None, timeout=None):
# Create these two helper classes fresh each time, since
# timeout needs to be in the closure.
class TimeoutHTTPConnection(httplib.HTTPConnection):
def connect(self):
"""Connect to the host and port specified in __init__."""
msg = "getaddrinfo returns an empty list"
for res in socket.getaddrinfo(self.host, self.port, 0,
socket.SOCK_STREAM):
af, socktype, proto, canonname, sa = res
try:
self.sock = socket.socket(af, socktype, proto)
if timeout is not None:
self.sock.settimeout(timeout)
if self.debuglevel > 0:
print "connect: (%s, %s)" % (self.host, self.port)
self.sock.connect(sa)
except socket.error, msg:
if self.debuglevel > 0:
print 'connect fail:', (self.host, self.port)
if self.sock:
self.sock.close()
self.sock = None
continue
break
if not self.sock:
raise socket.error, msg
class TimeoutHTTPHandler(urllib2.HTTPHandler):
http_request = urllib2.AbstractHTTPHandler.do_request_
def http_open(self, req):
return self.do_open(TimeoutHTTPConnection, req)
opener = urllib2.build_opener(TimeoutHTTPHandler)
opener.open(url, data)
Je pense que le meilleur choix est de patch (ou déployer une version locale de) votre urllib2 avec le changement de la branche de maintenance 2.6
Le fichier doit être dans /usr/lib/python2.4/urllib2.py
(sur Linux et 2.4)
J'utilise httplib de la bibliothèque standard. Il a une API simple mort, mais ne gère que http comme vous pouvez le deviner. IIUC urllib utilise httplib pour mettre en œuvre les choses http.
Vous devez définir le délai à deux endroits.
import urllib2
import socket
socket.setdefaulttimeout(30)
f = urllib2.urlopen('http://www.python.org/', timeout=30)
Eh bien, le délai d'attente est gérée de façon soit 2.4 ou 2.6 est le même. Si vous ouvrez le fichier urllib2.py 2.6 u verriez que cela prend un argument supplémentaire comme délai d'attente et gère à l'aide de la méthode socket.defaulttimeout () comme mentionné est la réponse 1.
Donc, vous avez vraiment besoin de mettre à jour votre urllib2.py pas dans ce cas.