0

ネットワーク トラフィックを削減するために、C#/python などで指定した URL の選択した部分のみを取得することは可能ですか。

例: Web サイトをスクレイピングしたいのですが、1000 個の URL を処理する必要がありますが、Web ページのごく一部しか必要としません (100 までスキップして、次の 200 バイトをダウンロードします)。

4

1 に答える 1

2

その小さな部分を読み取ると、実際にはネットワーク トラフィック (およびサーバーの負荷も) が増加します。あなたのユース ケースでは、各リソースからその 1 つの範囲だけが本当に必要な場合はRange: bytes=0-1024、ファイル全体を手動で取得したとしても、ストリーミング API を使用して 1024 バイトで読み取りを停止 (およびソケットを閉じる) することをお勧めします。返されるバイト[100:300]を選択します。

しかし、これを行う価値がある場合もあります。たとえば、200MB のファイルの 2 番目と 54 番目のメガバイトを読み取ろうとしていたとします。200MB の 1% を保持するためだけに 200MB 全体を読みたくありませんよね?

簡単なバージョンは次のとおりですRange。リクエストでヘッダーを送信します。あなたは戻ってくるかもしれません:

  • ヘッダー付きの206応答で、Content-Range本文には必要なバイトのみが含まれています。
  • A 416は、あなたの範囲が満足できないと言っていますContent-Range
  • リソース全体が本文にあるその他の成功応答。(このケースに対処するために、「一度にすべてを取得する」API の代わりに「ストリーミング」API を使用することをお勧めします。これにより、少なくとも 54MB を超えると読み取りを停止できます。)
  • 明らかに、他のエラー。

リクエストが 406 で満たされる可能性が高いかどうかを事前に知りたい場合は、およびヘッダーHEADを取得するリクエストを行う必要があります。ただし、実際にはどちらも必要ないことに注意してください。Content-LengthAccept-Ranges

また、一部のサーバーは単純な範囲リクエストを処理しますが、必要なすべての仕様を完全に処理するわけではないことに注意してください。そのため、1 回のリクエストで両方の範囲をフェッチすると、2 つのリクエストを作成するよりもオーバーヘッドが少し大きくなるように思えるかもしれませんが、ファイル全体にフォールバックする可能性も高くなるため、実行する価値はありません。

とにかく、すべてを完全に簡単にするライブラリは知りませんが、中間レベルの HTTP ライブラリ (Python stdlib と .NET の両方に組み込まれているものを含む) を使用すると、これを比較的簡単に行うことができます。requestsPython でサードパーティ ライブラリをインタラクティブに使用する例を示します。

>>> import requests
>>> url = 'http://example.com'
>>> h = requests.head(url)
>>> h.headers['Accept-Ranges']
'bytes'
>>> h.headers['Content-Length']
'1270'
>>> r = requests.get(url, headers={'Range': 'bytes=500-600'})
>>> r.status_code
206
>>> r.headers['Content-Range']
500-600/1270
>>> len(r.text)
101
>>> r.text
' 5em auto;\n        padding: 50px;\n        background-color: #fff;\n        border-radius: 1em;\n    }\n '

HTTP 範囲が閉じていることに注意してください。つまりBytes: 500-600、500 と 600 の両方が含まれているため、長さは 101 ですが、Python のrange(500, 600)長さは 100 しかありません。ここでは、1 つずつエラーが発生しやすいです。

于 2013-10-25T19:24:44.053 に答える