Frage

Die urllib2 Dokumentation sagt, dass timeout Parameter hinzugefügt wurde in Python 2.6. Leider 2.5 meine Code-Basis auf Python wurde ausgeführt und 2.4-Plattformen.

Gibt es eine andere Möglichkeit, den Timeout zu simulieren? Alles, was ich tun möchte, ist damit der Code den Remote-Server für eine bestimmte Zeit sprechen.

Vielleicht eine Alternative Bibliothek-in gebaut? (Nicht will, 3rd-Party installieren, wie pycurl)

War es hilfreich?

Lösung

Sie eine globale Timeout für alle Socket-Operationen (einschließlich HTTP-Anfragen) eingestellt kann mit:

socket.setdefaulttimeout()

wie folgt aus:

import urllib2
import socket
socket.setdefaulttimeout(30)
f = urllib2.urlopen('http://www.python.org/')

in diesem Fall Ihre urllib2 Anfrage würde nach 30 Sekunden Timeout und eine Socket-Ausnahme aus.

(dies wurde in Python 2.3 hinzugefügt)

Andere Tipps

Mit erheblichen Irritationen, können Sie die httplib.HTTPConnection Klasse überschreiben, dass die urllib2.HTTPHandler Anwendungen.

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)

Ich denke, die beste Wahl zu Patch ist (oder eine lokale Version bereitstellen) Ihr urllib2 mit der Wechsel von dem 2.6 Wartung Zweig

Die Datei in /usr/lib/python2.4/urllib2.py (auf Linux und 2.4) sollte

Ich verwende httplib aus der Standardbibliothek. Es hat eine tote einfache API, aber nur Griffe http wie Sie sich vorstellen können. IIUC urllib httplib verwendet die HTTP Sachen zu implementieren.

Sie müssen an zwei Stellen festgelegt Timeout.

import urllib2
import socket

socket.setdefaulttimeout(30)
f = urllib2.urlopen('http://www.python.org/', timeout=30)

Nun, die Art und Weise Timeout wird in beide 2.4 behandelt oder 2.6 ist das gleiche. Wenn Sie die Datei urllib2.py in 2.6 öffnen u würde sehen, dass es ein zusätzliches Argument als Timeout und Griffe nimmt es die socket.defaulttimeout () Methode verwendet wird, wie erwähnt ist die Antwort 1.

So was Sie wirklich brauchen nicht aktualisieren Sie Ihre urllib2.py in diesem Fall.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top