2010-01-18 15 views
28

urllib2 documentation कहता है कि टाइमआउट पैरामीटर पायथन 2.6 में जोड़ा गया था। दुर्भाग्यवश मेरा कोड बेस पायथन 2.5 और 2.4 प्लेटफॉर्म पर चल रहा है।पूर्व पायथन 2.6 संस्करणों में urllib2.urlopen() के लिए टाइमआउट

क्या टाइमआउट अनुकरण करने का कोई वैकल्पिक तरीका है? मैं बस इतना करना चाहता हूं कि कोड को निश्चित समय के लिए रिमोट सर्वर से बात करने दें।

शायद कोई वैकल्पिक निर्मित लाइब्रेरी? (, 3 पार्टी को स्थापित नहीं करना चाहते pycurl की तरह)

उत्तर

57

आप का उपयोग करके सभी सॉकेट परिचालन (HTTP अनुरोध सहित) के लिए एक वैश्विक समाप्ति सेट कर सकते हैं:

socket.setdefaulttimeout()

इस तरह:

import urllib2 
import socket 
socket.setdefaulttimeout(30) 
f = urllib2.urlopen('http://www.python.org/') 
इस मामले में

, अपने urllib2 अनुरोध का समय समाप्त होगा 30 सेकंड के बाद और एक सॉकेट अपवाद फेंक दें। (यह पायथन 2.3 में जोड़ा गया था)

+0

में टाइमआउट का समर्थन करता है 'urllib2 मॉड्यूल को Python 3.0 में urllib.request और urllib.error नामक कई मॉड्यूल में विभाजित किया गया है। लेकिन बाकी कोड काफी सरल हैं। – MewX

2

मुझे लगता है कि तुम्हारा सबसे अच्छा विकल्प पैच करने के लिए है (या तैनात की एक स्थानीय संस्करण) the change from the 2.6 maintenance branch

के साथ अपने urllib2 फ़ाइल (linux पर /usr/lib/python2.4/urllib2.py में होना चाहिए और 2.4)

+1

socket.settimeout() के बारे में क्या? क्या इससे मदद मिलेगी? – rubayeet

+0

मुझे लगता है कि यह हो सकता है, मुझे कुछ समय पहले एक ही समस्या थी, और किसी कारण से मैं इसे काम नहीं कर सका। हालांकि, मेरे पास कोई याद नहीं है जहां कोड हो सकता है, इसलिए जांच नहीं कर सकता:/ – Kimvais

1

मैं मानक पुस्तकालय से httplib का उपयोग करता हूं। इसमें एक मृत सरल एपीआई है, लेकिन जैसा कि आप अनुमान लगा सकते हैं केवल http को संभालता है। आईआईयूसी urllib http सामान को लागू करने के लिए httplib का उपयोग करता है।

+2

दुर्भाग्य से हॉस्पिटलबिल केवल 2.6 – rubayeet

0

ठीक है, जिस तरह से टाइमआउट को 2.4 या 2.6 में संभाला जाता है वही है। यदि आप 2.6 में urllib2.py फ़ाइल खोलते हैं तो आप देखेंगे कि यह टाइमआउट के रूप में अतिरिक्त तर्क लेता है और socket.defaulttimeout() विधि का उपयोग करके इसे संभालता है जैसा कि बताया गया है उत्तर 1 है।

तो आपको वास्तव में अपने urllib2 को अपडेट करने की आवश्यकता नहीं है उस मामले में .py।

4

काफी जलन के साथ, आप 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) 
1

आपको दो स्थानों पर टाइमआउट सेट करना होगा।

import urllib2 
import socket 

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

स्वतंत्र रूप से दोनों काम करते हैं। हालांकि टाइमआउट = 30 स्वयं ही काम करता है। यह मेरे लिए सबसे अच्छा जवाब था, इसलिए मैंने आपके -1 को हटा दिया। यदि आप अपने उत्तर का शीर्षक किसी चीज़ पर संशोधित करते हैं "आप एक या दोनों स्थानों में टाइमआउट सेट करना चुन सकते हैं"। इसके अलावा मुख्य प्रश्न पायथन के संस्करण के मुद्दे को हल करता है। – ruralcoder

संबंधित मुद्दे