如何使用 Python urllib2 下载分块数据
Posted
技术标签:
【中文标题】如何使用 Python urllib2 下载分块数据【英文标题】:How to download chunked data with Pythons urllib2 【发布时间】:2014-08-15 03:19:33 【问题描述】:我正在尝试使用 Python 2 从服务器下载一个大文件:
req = urllib2.Request("https://myserver/mylargefile.gz")
rsp = urllib2.urlopen(req)
data = rsp.read()
服务器使用“Transfer-Encoding: chunked”发送数据,我只得到一些二进制数据,无法通过 gunzip 解包。
我必须遍历多个 read() 吗?还是多个请求?如果是这样,它们的外观如何?
注意:我正在尝试仅使用 Python 2 标准库来解决问题,而不使用 urllib3 或 requests 等其他库。这甚至可能吗?
【问题讨论】:
【参考方案1】:来自 urllib2.urlopen 上的 python 文档:
一个警告:read() 方法,如果省略 size 参数或 负数,直到数据流结束才能读取;没有 确定来自套接字的整个流的好方法 在一般情况下阅读。
所以,循环读取数据:
req = urllib2.Request("https://myserver/mylargefile.gz")
rsp = urllib2.urlopen(req)
data = rsp.read(8192)
while data:
# .. Do Something ..
data = rsp.read(8192)
【讨论】:
我的印象是,这仅适用于下载未使用 transfer-encoding=chunked 发送的文件。 嗯,你是对的。我看到了一个没有答案的类似问题:***.com/questions/15115606/… 抱歉,我不知道如何通过它。唯一的答案使用 curl。 好的,我会尝试 curl,与 Python 相比,登录 cookie 有点麻烦,但总比没有好。谢谢!【参考方案2】:如果我没记错的话,以下内容对我有用 - 不久前:
data = ''
chunk = rsp.read()
while chunk:
data += chunk
chunk = rsp.read()
每个read
读取一个块 - 所以请继续阅读,直到没有更多内容出现。
还没有准备好支持这一点的文档……还没有。
【讨论】:
不幸的是,这对我不起作用: content = '' while True: chunk = rsp.read() if not chunk break content += chunk f.write(content)does not work
不幸的是,这是一个非常无用的声明 :) 是否还有内容缺失?
对不起:在“完全像以前一样”的意义上“不起作用”。 IE。数据不完整,gunzip 无法读取。我假设 urllib2 只是不支持分块传输编码。【参考方案3】:
我也有同样的问题。
我发现“Transfer-Encoding: chunked”经常与“Content-Encoding: gzip”。
所以也许我们可以得到压缩的内容并解压它。
它对我有用。
import urllib2
from StringIO import StringIO
import gzip
req = urllib2.Request(url)
req.add_header('Accept-encoding', 'gzip, deflate')
rsp = urllib2.urlopen(req)
if rsp.info().get('Content-Encoding') == 'gzip':
buf = StringIO(rsp.read())
f = gzip.GzipFile(fileobj=buf)
data = f.read()
【讨论】:
以上是关于如何使用 Python urllib2 下载分块数据的主要内容,如果未能解决你的问题,请参考以下文章