用python下载大zip文件
Posted
技术标签:
【中文标题】用python下载大zip文件【英文标题】:Download big zip file with python 【发布时间】:2012-04-24 20:07:11 【问题描述】:我有多个返回 zip 文件的 URL。大多数文件,我可以使用 urllib2 库下载如下:
request = urllib2.urlopen(url)
zip_file = request.read()
我遇到的问题是其中一个文件的大小为 35Mb(压缩),我永远无法使用此库完成下载。我可以正常使用wget和浏览器下载它。
我曾尝试像这样以块的形式下载文件:
request = urllib2.urlopen(url)
buffers = []
while True:
buffer = request.read(8192)
if buffer:
buffers.append(buffer)
else:
break
final_file = ''.join(buffers)
但这也没有完成下载。没有引发错误,因此很难调试正在发生的事情。不幸的是,我无法在此处发布 url / 文件的示例。
有什么建议/意见吗?
【问题讨论】:
如果没有更多信息或重现它的 URL,很难调试。但是,为什么不直接使用final_file = request.read()
?您上面的代码正在构建一个字符串数组,它将所有数据存储在内存中,因此我认为没有任何理由使代码复杂化以一次读取块。
How do I download a zip file in python using urllib2? 的可能重复项
@benhoyt 这是我的第一次尝试,但没有成功。这就是为什么我试图将文件分成块
Stream large binary files with urllib2 to file的可能重复
与 Masi 建议的不同,但可能与 @ChristopheD 相同。至少,问题和建议的解决方案似乎非常接近
【参考方案1】:
这是从我的应用程序中复制/粘贴的,它会下载它自己的更新安装程序。它以块为单位读取文件并立即将块保存在磁盘上的输出文件中。
def DownloadThreadFunc(self):
try:
url = self.lines[1]
data = None
req = urllib2.Request(url, data, )
handle = urllib2.urlopen(req)
self.size = int(handle.info()["Content-Length"])
self.actualSize = 0
name = path.join(DIR_UPDATES, url.split("/")[-1])
blocksize = 64*1024
fo = open(name, "wb")
while not self.terminate:
block = handle.read(blocksize)
self.actualSize += len(block)
if len(block) == 0:
break
fo.write(block)
fo.close()
except (urllib2.URLError, socket.timeout), e:
try:
fo.close()
except:
pass
error("Download failed.", unicode(e))
如果需要,我使用self.size
和self.actualSize
在 GUI 线程中显示下载进度,并使用self.terminate
从 GUI 按钮取消下载。
【讨论】:
这很完美!非常感谢。但是你能告诉我为什么我的简化版不起作用吗? 不知道。但我有点怀疑这种结构:if buffer:
。我喜欢将块直接存储到磁盘,这样在输出文件中也可以看到进度。
我明白你的意思。我尝试了您的代码版本,也将文件仅存储在内存中,并且效果也很好。会不会是我的初始缓冲区大小(太小)?
我认为可能是这种情况。你的代码什么时候卡住了?文件是否已经下载到内存中?添加一些关于您已经下载了多少、数据大小等的调试打印输出。
我没有使用“如果不阻止”,它工作正常。似乎是块大小太小了。这是唯一的区别。还是谢谢!以上是关于用python下载大zip文件的主要内容,如果未能解决你的问题,请参考以下文章
使用 python ftplib 下载二进制格式的 zip 文件
CentOS 安装 opencv, 解决 Python cv2 module 问题(终极解决方法)
CentOS 安装 opencv, 解决 Python cv2 module 问题(终极解决方法)