Skip to main content
 首页 » 编程设计

python之如果未提供 Content-Length,则使用 python 正确下载文件

2025年05月04日9EasonJim

如果 http 响应不包含 Content-Length header ,我如何使用 python 正确下载文件?

我遇到了 Appengine 的 send_blob() 函数的问题,由于某种原因,它没有在更大的 (20mb+) blob 上添加 Content-Length header 。

我现在正在使用 urllib.urlretrieve() 但有时它不会下载整个文件。 我现在正在做的是在下载文件之前发送内容长度,这样我就可以在继续之前检查文件的大小是否正确。

我不确定是否有更好的方法。

其中一个文件的标题:

HTTP/1.1 200 OK 
Cache-Control: no-cache 
Content-Type: application/octet-stream 
Expires: Fri, 01 Jan 1990 00:00:00 GMT 
Date: Fri, 30 Sep 2011 19:41:34 GMT 
Server: Google Frontend 
Transfer-Encoding: Identity 
Connection: close 

我只是尝试使用 wget 通过 wget --server-response --continue 下载一个文件, header 是:

  HTTP/1.1 200 OK 
  Cache-Control: no-cache 
  Content-Type: application/octet-stream 
  Expires: Fri, 01 Jan 1990 00:00:00 GMT 
  Date: Wed, 05 Oct 2011 14:08:13 GMT 
  Server: Google Frontend 
  Transfer-Encoding: chunked 
Length: unspecified [application/octet-stream] 

请您参考如下方法:

如果服务器没有给出所请求数据长度的指示,向您发送了一些数据,然后关闭了连接,则 HTTP 客户端必须假定所有数据都已成功传输。

只有使用额外的非 HTTP 信息,例如有效负载格式中的校验和或其他错误更正,应用程序才能确定发生错误,并使用 HTTP Range header (即 Range: bytes=NNNN-)在后续客户端请求中恢复传输。

如果服务器不支持Range头,如果服务器在任何时候发送响应头Accept-Ranges: none,你可能会得出结论,那么只要我知道您无法对损坏的服务器实现求助,只能定期重试请求,希望它最终提供通过错误检测的响应。

脚注:在提供 blob 内容时,Content-Length header 丢失对我来说并不奇怪。许多数据库 API 不允许在不实际检索整个内容的情况下测试 blob 的长度。我怀疑这是因为 SQL 引擎本身不支持此测试。