سؤال

ال توثيق 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 ثانية ويرمي استثناء المقبس. (تمت إضافة هذا في بيثون 2.3)

نصائح أخرى

مع تهيج كبير ، يمكنك تجاوز فئة httplib.httpconnection التي يستخدمها urllib2.httphandler.

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 من المكتبة القياسية. إنه يحتوي على واجهة برمجة تطبيقات بسيطة ميتة ، ولكنها تعالج HTTP فقط كما قد تخمن. يستخدم iiuc urllib httplib لتنفيذ أشياء http.

يجب عليك تعيين مهلة في مكانين.

import urllib2
import socket

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

حسنًا ، يتم التعامل مع المهلة في 2.4 أو 2.6 هي نفسها. إذا قمت بفتح ملف urllib2.py في 2.6 ، فسترى أن الأمر يتطلب وسيطة إضافية مثل مهلة وتتعامل معها باستخدام طريقة Socket.DefaultTimeout () كما هو مذكور هي الإجابة 1.

لذلك لا تحتاج حقًا إلى تحديث urllib2.py في هذه الحالة.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top