使用部分下载(HTTP)下载文件

时间:2009-11-25 18:10:03

标签: python http partial

有没有办法使用部分下载功能通过HTTP下载庞大且仍在增长的文件?

这段代码似乎每次执行都会从头开始下载文件:

import urllib
urllib.urlretrieve ("http://www.example.com/huge-growing-file", "huge-growing-file")

我想:

  1. 仅获取新写入的数据
  2. 仅在源文件变小(例如已旋转)时从头开始下载。

3 个答案:

答案 0 :(得分:42)

可以使用范围标题进行部分下载,以下内容将请求选定的字节范围:

req = urllib2.Request('http://www.python.org/')
req.headers['Range'] = 'bytes=%s-%s' % (start, end)
f = urllib2.urlopen(req)

例如:

>>> req = urllib2.Request('http://www.python.org/')
>>> req.headers['Range'] = 'bytes=%s-%s' % (100, 150)
>>> f = urllib2.urlopen(req)
>>> f.read()
'l1-transitional.dtd">\n\n\n<html xmlns="http://www.w3.'

使用此标题可以恢复部分下载。在您的情况下,您所要做的就是跟踪已下载的尺寸并请求新的范围。

请记住,服务器需要接受此标头才能生效。

答案 1 :(得分:2)

使用TCP套接字和原始HTTP非常容易。相关的请求标题是“Range”。

示例请求可能如下所示:

mysock = connect(("www.example.com", 80))
mysock.write(
  "GET /huge-growing-file HTTP/1.1\r\n"+\
  "Host: www.example.com\r\n"+\
  "Range: bytes=XXXX-\r\n"+\
  "Connection: close\r\n\r\n")

其中XXXX表示您已检索的字节数。然后,您可以从服务器读取响应标头和任何内容。如果服务器返回如下标题:

Content-Length: 0

你知道你已经拥有了整个文件。

如果您希望作为HTTP客户端特别好,可以查看“Connection:keep-alive”。也许有一个python库可以完成我所描述的所有内容(甚至urllib2也可以做到!)但我对它不熟悉。

答案 2 :(得分:-1)

如果我正确理解您的问题,该文件在下载过程中不会更改,但会定期更新。如果这是问题,rsync就是答案。

如果文件不断更新,包括下载期间,则需要修改rsync或bittorrent程序。他们将文件拆分为单独的块,并单独下载或更新块。当您从第一次迭代到达文件的末尾时,重复以获取附加的块;必要时继续。效率较低,可以反复进行rsync。

相关问题