如何使用 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 下载分块数据的主要内容,如果未能解决你的问题,请参考以下文章

Python3.X如何下载安装urllib2包 ?

python urllib2模块 在哪里下载?

python爬虫_urllib2库的基本使用

python爬虫_urllib2库的基本使用

Python urllib2 进度挂钩

python urllib2 下载大小