Pergunta

o Documentação URLLIB2 diz que tempo esgotado O parâmetro foi adicionado no Python 2.6. Infelizmente, minha base de código está em execução nas plataformas Python 2.5 e 2.4.

Existe alguma maneira alternativa de simular o tempo limite? Tudo o que quero fazer é permitir que o código fale ao servidor remoto por um período fixo de tempo.

Talvez alguma biblioteca interna alternativa? (Não quero instalar a 3ª festa, como pycurl)

Foi útil?

Solução

Você pode definir um tempo limite global para todas as operações de soquete (incluindo solicitações HTTP) usando:

socket.setdefaulttimeout()

assim:

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

Nesse caso, sua solicitação de urllib2 teria tempo limite após 30 segundos e lançaria uma exceção de soquete. (Isso foi adicionado no Python 2.3)

Outras dicas

Com uma irritação considerável, você pode substituir a classe httplib.httpconnection que o urllib2.httphandler usa.

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)

Eu acho que sua melhor escolha é corrigir (ou implantar uma versão local de) seu urllib2 com A mudança do ramo de manutenção 2.6

O arquivo deve estar em /usr/lib/python2.4/urllib2.py (no Linux e 2.4)

Eu uso httplib da biblioteca padrão. Ele tem uma API simples, mas apenas lida com o HTTP, como você pode imaginar. O iiuc urllib usa httplib para implementar o material HTTP.

Você deve definir o tempo limite em dois lugares.

import urllib2
import socket

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

Bem, a maneira como o tempo limite é tratado em 2.4 ou 2.6 é o mesmo. Se você abrir o arquivo urllib2.py em 2.6, veria que ele leva um argumento extra como o tempo limite e o lida usando o método Socket.DefaultTimeout (), conforme mencionado, é a resposta 1.

Portanto, você realmente não precisa atualizar seu urllib2.py nesse caso.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top