2011-11-09 37 views
3

函数urllib2.urlopen冻结。所以我的问题很简单:python urllib2.urlopen即使设置了超时也无限制地冻结脚本

  • 为什么urlopen冻结我的脚本永远即使超时设置?
  • 如何在URL中访问数据(在这种情况下是:http://api.own3d.tv/live?channel=FnaticTV),而不会导致我的Python进程永久冻结?

这是是冻结的部分(在own3d.py):

# Try three times to make contact 
while True: 
    try: 
     # Connect to API 

     # Right here! It freezes here 
     connection = urllib2.urlopen(request, timeout=10) 

     xmlstring = connection.read() 
    except URLError as e: 
     tries += 1 
     if tries >= 3: 
      sys.stderr.write(
         'own3dStreamsUpdater: Fatal error: Repeated timeouts') 
      exit() 

这是堆栈跟踪后,我的一个KeyboardInterrupt

 
Traceback (most recent call last): 
    File "", line 1, in 
    File "honsapp/own3dStreamsUpdater.py", line 53, in updateStreamInfo 
    streamInfo = getStreamInfo(stream) 
    File "honsapp/own3d.py", line 98, in getStreamInfo 
    connection = urllib2.urlopen(request, timeout=10) 
    File "/usr/local/lib/python2.7/urllib2.py", line 126, in urlopen 
    return _opener.open(url, data, timeout) 
    File "/usr/local/lib/python2.7/urllib2.py", line 394, in open 
    response = self._open(req, data) 
    File "/usr/local/lib/python2.7/urllib2.py", line 412, in _open 
    '_open', req) 
    File "/usr/local/lib/python2.7/urllib2.py", line 372, in _call_chain 
    result = func(*args) 
    File "/usr/local/lib/python2.7/urllib2.py", line 1199, in http_open 
    return self.do_open(httplib.HTTPConnection, req) 
    File "/usr/local/lib/python2.7/urllib2.py", line 1170, in do_open 
    r = h.getresponse(buffering=True) 
    File "/usr/local/lib/python2.7/httplib.py", line 1027, in getresponse 
    response.begin() 
    File "/usr/local/lib/python2.7/httplib.py", line 407, in begin 
    version, status, reason = self._read_status() 
    File "/usr/local/lib/python2.7/httplib.py", line 365, in _read_status 
    line = self.fp.readline() 
    File "/usr/local/lib/python2.7/socket.py", line 447, in readline 
    data = self._sock.recv(self._rbufsize) 
KeyboardInterrupt 

编辑

我让我的脚本跑了一晚。我不知道它究竟有多长了(虽然超过五分钟),但剧本终于放弃了,给了我一个堆栈跟踪:

 
Traceback (most recent call last): 
    File "honsapp/own3dStreamsUpdater.py", line 260, in 
    newInfo() 
    File "honsapp/own3dStreamsUpdater.py", line 172, in newInfo 
    result = updateStreamInfo(stream) 
    File "honsapp/own3dStreamsUpdater.py", line 53, in updateStreamInfo 
    streamInfo = getStreamInfo(stream) 
    File "/root/Dropbox/Projects/honstreams/honsapp/own3d.py", line 98, in getStreamInfo 
    connection = urllib2.urlopen(request, timeout=10) 
    File "/usr/local/lib/python2.7/urllib2.py", line 126, in urlopen 
    return _opener.open(url, data, timeout) 
    File "/usr/local/lib/python2.7/urllib2.py", line 394, in open 
    response = self._open(req, data) 
    File "/usr/local/lib/python2.7/urllib2.py", line 412, in _open 
    '_open', req) 
    File "/usr/local/lib/python2.7/urllib2.py", line 372, in _call_chain 
    result = func(*args) 
    File "/usr/local/lib/python2.7/urllib2.py", line 1199, in http_open 
    return self.do_open(httplib.HTTPConnection, req) 
    File "/usr/local/lib/python2.7/urllib2.py", line 1170, in do_open 
    r = h.getresponse(buffering=True) 
    File "/usr/local/lib/python2.7/httplib.py", line 1027, in getresponse 
    response.begin() 
    File "/usr/local/lib/python2.7/httplib.py", line 407, in begin 
    version, status, reason = self._read_status() 
    File "/usr/local/lib/python2.7/httplib.py", line 371, in _read_status 
    raise BadStatusLine(line) 
httplib.BadStatusLine: '' 

回答

4

这个脚本根本不会冻结,但它是一个很好的例子,说明你为什么不应该在疲倦时编码。应该尝试连接API三次的循环将会持续下去,因为我忘记了将break放在那里。

这个问题是如此愚蠢,我不会责怪你删除它。

固定码:

# Try three times to make contact 
while True: 
    try: 
     # Connect to API 
     connection = urllib2.urlopen(request, timeout=10) 
     xmlstring = connection.read() 
     break 
    except URLError as e: 
     tries += 1 
     if tries >= 3: 
      sys.stderr.write(
         'own3dStreamsUpdater: Fatal error: Repeated timeouts') 
      exit() 
+2

你可能已经通过DOS的网站让网站管理员非常生气:) –

4

您确认的urlopen()调用挂起?因为如果调用成功,while循环不会终止。

+0

的确。也许如果你打印xmlstring,你可能会看到有价值的输出。 –

+0

我不明白你们的意思。栈跟踪清楚地表明,它冻结的地方,等待我的KeyboardInterrupt,在'connection = urllib2.urlopen(request,timeout = 10)'行中。如何更改该行下面的任何代码可能会有所作为?另外,我用更多的信息更新了我的问题。 – Hubro

+1

stacktrace只声明你中断它的地方在urlopen()调用中 - 这并不令人惊讶,因为循环中只有两条语句,而urlopen()可能是较慢的语句。 Andrew建议你在循环中加入打印语句吗? – Cito

相关问题