مهلة urllib2.urlopen () في إصدارات ما قبل Python 2.6
سؤال
ال توثيق urllib2 يقول ان نفذ الوقت تمت إضافة المعلمة في Python 2.6. لسوء الحظ ، تم تشغيل قاعدة الكود الخاصة بي على منصات Python 2.5 و 2.4.
هل هناك أي طريقة بديلة لمحاكاة المهلة؟ كل ما أريد فعله هو السماح للرمز بالتحدث مع الخادم البعيد لفترة زمنية ثابتة.
ربما أي مكتبة بديلة مدمجة؟ (لا تريد تثبيت الطرف الثالث ، مثل Pycurl)
المحلول
يمكنك تعيين مهلة عالمية لجميع عمليات المقبس (بما في ذلك طلبات HTTP) باستخدام:
مثله:
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 في هذه الحالة.