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)
请参阅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 中修复。