获取HTTP的urllib2.urlopen返回值的套接字

Flo*_*yer 5 python urllib urllib2

我正在尝试使用urllib2进行文件的异步下载,但没有成功找到套接字(或其fileno)以等待HTTP请求的新数据.这是我已经尝试过的.

>>> from urllib2 import urlopen
>>> from select import select
>>> r = urlopen('http://stackoverflow.com/')
>>> select([r], [], [])
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python2.6/socket.py", line 307, in fileno
    return self._sock.fileno()
AttributeError: HTTPResponse instance has no attribute 'fileno'
>>> r.fileno()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python2.6/socket.py", line 307, in fileno
    return self._sock.fileno()
AttributeError: HTTPResponse instance has no attribute 'fileno'
>>> r.fp.fileno()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python2.6/socket.py", line 307, in fileno
    return self._sock.fileno()
AttributeError: HTTPResponse instance has no attribute 'fileno'
>>> select([r.fp], [], [])
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python2.6/socket.py", line 307, in fileno
    return self._sock.fileno()
AttributeError: HTTPResponse instance has no attribute 'fileno'
>>> 
Run Code Online (Sandbox Code Playgroud)

agf*_*agf 3

请参阅http://www.velocityreviews.com/forums/t512553-re-urllib2-urlopen-broken.html

问题在于 urlib2 已更改为将 HTTPResponse 对象包装在 socket._fileobject 中以获得更多文件方法。除了(如上所述)HTTPResponse 没有 fileno() 方法,因此当 _fileobject 尝试使用它时,它会崩溃。

解决方案

向 HTTPResponse 添加适当的方法:

def fileno(self):
    return self.fp.fileno()
Run Code Online (Sandbox Code Playgroud)

或者,也可以使用urllib.urlopen代替urrlib2.urlopen.

对于这个问题有一个错误报告;它已在 Python 3 和 Python 2.7 中修复。