请求 response.iter_content() 获取不完整的文件(1024MB 而不是 1.5GB)?

Posted

技术标签:

【中文标题】请求 response.iter_content() 获取不完整的文件(1024MB 而不是 1.5GB)?【英文标题】:requests response.iter_content() gets incomplete file ( 1024MB instead of 1.5GB )? 【发布时间】:2014-07-01 22:49:49 【问题描述】:

您好,我一直在使用此代码 sn-p 从网站下载文件,目前小于 1GB 的文件都很好。但我注意到一个 1.5GB 的文件不完整

# s is requests session object
r = s.get(fileUrl, headers=headers, stream=True)

start_time = time.time()
with open(local_filename, 'wb') as f:
    count = 1
    block_size = 512
    try:
        total_size = int(r.headers.get('content-length'))
        print 'file total size :',total_size
    except TypeError:
        print 'using dummy length !!!'
        total_size = 10000000

    for chunk in r.iter_content(chunk_size=block_size):

        if chunk:  # filter out keep-alive new chunks

            duration = time.time() - start_time
            progress_size = int(count * block_size)
            if duration == 0:
                duration = 0.1
            speed = int(progress_size / (1024 * duration))
            percent = int(count * block_size * 100 / total_size)
            sys.stdout.write("\r...%d%%, %d MB, %d KB/s, %d seconds passed" %
                            (percent, progress_size / (1024 * 1024), speed, duration))

            f.write(chunk)
            f.flush()
            count += 1

使用最新请求 2.2.1 python 2.6.6, centos 6.4 文件下载总是停止在 66.7% 1024MB,我错过了什么? 输出:

file total size : 1581244542
...67%, 1024 MB, 5687 KB/s, 184 seconds passed

iter_content() 返回的生成器似乎认为所有块都已检索并且没有错误。顺便说一句,异常部分没有运行,因为服务器确实在响应头中返回了内容长度。

【问题讨论】:

注意“b” = 位,而“B” = 字节(这可能是你的意思) @Jonathon 好的 ... orz,我更新了帖子 s.get(...) 中的s 是什么? @Lego s 是请求会话对象...。我从中下载的站点需要身份验证,我省略了这些代码 @Shuman,你解决问题了吗?这里也一样.... 【参考方案1】:

请仔细检查您是否可以通过wget 和/或任何常规浏览器下载文件。可能是对服务器的限制。正如我所见您的代码可以下载大文件(大于 1.5Gb)

更新:请尝试反转逻辑 - 而不是

if chunk: # filter out keep-alive new chunks                                                                                                                                                                                                         
    f.write(chunk)                                                                                                                                                                                                                                   
    f.flush()

试试

if not chunk:
   break

f.write(chunk)                                                                                                                                                                                                                                   
f.flush()

【讨论】:

刚刚在firefox 29中再次检查,手动下载作品,但通过代码它不起作用。总是停在 1024 MB。【参考方案2】:

如果你使用 Nginx 作为文件系统,你可以检查 nginx 配置文件看看你是否设置了

proxy_max_temp_file_size 3000m;

或者不。

默认情况下,此大小为1G。所以只能得到1024MB

【讨论】:

【参考方案3】:

我想你忘了关闭req

从请求作者说, “如果您发现自己在使用 stream=True 时部分读取了请求正文(或根本不读取它们),您应该在 with 语句中发出请求以确保它始终关闭:”

http://2.python-requests.org//en/latest/user/advanced/#body-content-workflow.

【讨论】:

以上是关于请求 response.iter_content() 获取不完整的文件(1024MB 而不是 1.5GB)?的主要内容,如果未能解决你的问题,请参考以下文章

HTTP请求行、请求头、请求体详解

options请求问题

网络请求之GETPOST请求

简单请求和复杂请求

HTTP请求行请求头请求体以及响应行响应头响应体

关于HTTP请求头