Python 2.6 より前のバージョンでの urllib2.urlopen() のタイムアウト

StackOverflow https://stackoverflow.com/questions/2084782

  •  21-09-2019
  •  | 
  •  

質問

urllib2 ドキュメント そう言う タイムアウト パラメータは Python 2.6 で追加されました。残念ながら、私のコードベースは Python 2.5 および 2.4 プラットフォームで実行されています。

タイムアウトをシミュレートする別の方法はありますか?私がやりたいのは、コードが一定時間リモートサーバーと通信できるようにすることだけです。

おそらく代替の組み込みライブラリはあるでしょうか?(pycurl などのサードパーティをインストールしたくない)

役に立ちましたか?

解決

あなたが使用して(HTTPリクエストを含む)すべてのソケット操作のためのグローバルタイムアウトを設定することができます:

socket.setdefaulttimeout()する

このような:

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

は、この場合には、お使いのurllib2の要求は30秒後にタイムアウトとソケット例外をスローしていました。 (これは、Python 2.3で追加された)

他のヒント

かなりの刺激を使用すると、urllib2.HTTPHandlerが使用することをhttplib.HTTPConnectionクラスをオーバーライドすることができます。

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)

あなたの最善の選択は、urllib2にパッチを適用する(またはローカルバージョンをデプロイする)ことだと思います 2.6 メンテナンス ブランチからの変更

ファイルは次の場所にある必要があります /usr/lib/python2.4/urllib2.py (Linux および 2.4 の場合)

私は標準ライブラリからhttplibを使用します。それは死んでシンプルなAPIを持っていますが、ご想像の通りHTTPのみを処理します。 IIUCのurllibはは、httpものを実装するためにhttplibを使用します。

あなたは2つの場所でのタイムアウトを設定する必要があります。

import urllib2
import socket

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

さて、タイムアウトが2.4または2.6のいずれかで処理される方法は同じです。あなたは2.6でurllib2.pyファイルを開く場合はuが述べたように、それはタイムアウトし、それsocket.defaulttimeout()メソッドを使用して、ハンドルなどの余分な引数を取ることがわかりでしょうが答え1です。

あなたが本当にそのような場合には、あなたのurllib2.pyを更新する必要はありませんので。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top