21

部分ダウンロード機能を使用して、HTTP経由で巨大でまだ成長しているファイルをダウンロードする方法はありますか?

このコードは、実行するたびにファイルを最初からダウンロードするようです。

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

私は…したい:

  1. 新しく書き込んだデータだけを取得するには
  2. ソースファイルが小さくなった場合(たとえば、ローテーションされた場合)にのみ、最初からダウンロードします。
4

3 に答える 3

43

範囲ヘッダーを使用して部分的なダウンロードを行うことができます。以下は、選択した範囲のバイトを要求します。

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.'

このヘッダーを使用すると、部分的なダウンロードを再開できます。あなたの場合、あなたがしなければならないことは、すでにダウンロードされたサイズを追跡し、新しい範囲を要求することだけです.

これが機能するには、サーバーがこのヘッダーを受け入れる必要があることに注意してください。

于 2009-11-25T18:18:55.433 に答える
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 クライアントとして特に使いたい場合は、「接続: キープアライブ」を調べることができます。おそらく、私が説明したすべてを実行する python ライブラリが存在するでしょう (おそらく urllib2 でさえ実行可能です!) が、私はそれに慣れていません。

于 2009-11-25T18:24:41.713 に答える
-1

あなたの質問を正しく理解できれば、ファイルはダウンロード中に変更されませんが、定期的に更新されます。それが問題なら、rsyncが答えです。

ダウンロード中も含めてファイルが継続的に更新されている場合は、rsync または bittorrent プログラムを変更する必要があります。ファイルを個別のチャンクに分割し、チャンクを個別にダウンロードまたは更新します。最初の繰り返しからファイルの最後に到達したら、追加されたチャンクを取得するために繰り返します。必要に応じて続行します。効率が悪い場合は、rsync を繰り返し実行できます。

于 2009-11-25T18:21:24.947 に答える