3

CURL がフェッチするデータの量を制限する方法はありますか? 50kb のページからデータをスクリーン スクレイピングしていますが、必要なデータはページの上部 1/4 にあるため、実際にはページの最初の 10kb のみを取得する必要があります。

監視する必要があるデータが大量にあり、その結果、この帯域幅の約 5 GB しか関連しない場合、1 か月あたり 60 GB 近くのデータを転送することになるため、質問しています。

PHP を使用してデータを処理していますが、データ取得のアプローチは柔軟で、CURL、WGET、fopen などを使用できます。

私が検討している1つのアプローチは

$fp = fopen("http://www.website.com","r");
fseek($fp,5000);
$data_to_parse = fread($fp,6000);

上記は、www.website.com から 6kb のみを転送することを意味するのでしょうか、それとも fopen が www.website.com をメモリにロードするということは、50kb 全体を転送することを意味するのでしょうか?

4

4 に答える 4

4

HTTP RANGE リクエストを試してください:

GET /largefile.html HTTP/1.1
Range: bytes=0-6000

サーバーが範囲要求をサポートしている場合、Content-Range ヘッダーと要求されたバイト範囲を含む 206 Partial Content 応答コードを返します (サポートしていない場合は、200 とファイル全体を返します)。範囲リクエストのわかりやすい説明については、http://benramsey.com/archives/206-partial-content-and-range-requests/を参照してください。

PHP を使用してファイルを送信する場合の再開可能なダウンロードも参照してください。.

于 2009-10-08T16:48:31.200 に答える
4

これは、実際には CURL の質問よりも HTTP に近いものです。

ご想像のとおり、fopen を使用すると、ページ全体がダウンロードされます。オフセット 5000 でシークするかどうかは関係ありません。

HTML RFC ( http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html )に記載されているように、部分的な HTTP GET 要求を使用することをお勧めします。

リクエスト メッセージに Range ヘッダー フィールドが含まれている場合、GET メソッドのセマンティクスは「部分的な GET」に変更されます。部分的な GET は、セクション 14.35 で説明されているように、エンティティの一部のみが転送されることを要求します。部分的な GET メソッドは、クライアントが既に保持しているデータを転送せずに、部分的に取得されたエンティティを完了できるようにすることで、不要なネットワークの使用を減らすことを目的としています。

範囲を使用した部分的な GET リクエストの詳細については、 http ://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.35.2 で説明しています。

于 2009-10-08T16:37:08.913 に答える
2

CURL を使用して探していることを達成することもできます。

CURLOPT_WRITEFUNCTIONのドキュメントを見ると、CURL からデータを読み取ることができるたびに呼び出されるコールバックを登録できます。次に、受信したバイト数をカウントし、6,000 バイトを超えて受信した場合は、0 を返して残りの転送を中止できます。

libcurlのドキュメントでは、コールバックについてもう少し詳しく説明しています。

この関数は、保存する必要があるデータを受信するとすぐに libcurl によって呼び出されます。実際に処理されたバイト数を返します。その量が関数に渡された量と異なる場合、ライブラリにエラーが通知され、転送が中止され、CURLE_WRITE_ERROR が返されます。

コールバック関数には、すべての呼び出しでできるだけ多くのデータが渡されますが、仮定を立てることはできません。1 バイトの場合もあれば、数千の場合もあります。

于 2009-10-08T17:43:37.877 に答える
0

呼び出しでページ全体をダウンロードしますが、fopenそのページから 6kb しか読み取れません。

PHPマニュアルから:

次の条件のいずれかが満たされると、読み取りはすぐに停止します。

  • lengthバイトが読み取られました
于 2009-10-08T16:35:34.673 に答える