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)

Était-ce utile?

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:

socket.setdefaulttimeout()

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.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top