有没有办法使用部分下载功能通过 HTTP 下载巨大且仍在增长的文件?
似乎这段代码每次执行时都会从头开始下载文件:
import urllib
urllib.urlretrieve ("http://www.example.com/huge-growing-file", "huge-growing-file")
我想要:
- 仅获取新写入的数据
- 仅当源文件变小(例如已旋转)时才从头开始下载。
可以使用范围标头进行部分下载,以下将请求选定的字节范围:
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.'
使用此标头,您可以恢复部分下载。在您的情况下,您所要做的就是跟踪已下载的大小并请求新的范围。
请记住,服务器需要接受此标头才能使其正常工作。
使用 TCP 套接字和原始 HTTP 很容易做到这一点。相关的请求标头是“范围”。
示例请求可能如下所示:
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 也可以做到!)但我不熟悉一个。
如果我正确理解您的问题,则文件在下载过程中不会更改,但会定期更新。如果这是问题,rsync就是答案。
如果文件不断更新,包括在下载期间,您需要修改 rsync 或 bittorrent 程序。他们将文件拆分为单独的块,并独立下载或更新这些块。当您从第一次迭代到达文件末尾时,重复以获取附加的块;根据需要继续。效率较低,只能重复 rsync。