Web ページの一部を取得する
-
20-09-2019 - |
質問
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 から 6 kb のみを転送することを意味しますか、それとも www.website.com をメモリにロードして 50 kb 全体を転送することを意味しますか?
解決
また、あなたが同様にCURLを使用して探しているものを達成できる可能性があります。
あなたは CURLOPT_WRITEFUNCTION のあなたのためのドキュメントを見ればデータはCURLからの読み取りのために利用可能であるときに呼び出されるコールバックを登録することができます。あなたは、受信したバイト数を数えることができる、そしてあなたが6000バイト以上を受け取ったときには、転送の残りを中止する0を返すことができます。
libcurlののドキュメントには、もう少しコールバックを記述する>この関数は、すぐにする必要がある受信データがあるとのlibcurlによって呼び出されます 保存されました。バイト数を返します。 実際に世話を。その量の場合 あなたに渡された金額とは異なり この関数は、それがにエラーを通知します ライブラリとそれが転送を中止します そして、CURLE_WRITE_ERRORを返します。
コールバック関数が渡されます 全部でできるだけ多くのデータ 起動しますが、あなたはおそらく作ることができません いずれかの仮定。これは、1つのバイトであってもよいし、 それは何千もあります。
他のヒント
これは実際には CURL の質問というよりも HTTP の質問です。
ご想像のとおり、fopen を使用するとページ全体がダウンロードされます。オフセット 5000 でシークするかどうかは関係ありません。
目的を達成するための最良の方法は、HTML RFC (http://www.w3.org/プロトコル/rfc2616/rfc2616-sec9.html):
リクエストメッセージに範囲ヘッダーフィールドが含まれている場合、GETメソッドのセマンティクスは「部分GET」に変更されます。セクション14.35で説明されているように、エンティティの一部のみが転送されるという部分的なGETリクエスト。部分的なGETメソッドは、既にクライアントが保持しているデータを転送せずに部分的に再取得されたエンティティを完了できるようにすることにより、不必要なネットワーク使用量を削減することを目的としています。
Range を使用した部分的な GET リクエストの詳細については、以下で説明します。http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.35.2
HTTP RANGEリクエストを試してください:
GET /largefile.html HTTP/1.1
Range: bytes=0-6000
場合サーバは範囲要求に、それは(それがない場合、それは200と全体のファイルを返します)206のContent-Rangeヘッダを持つ部分コンテンツ応答コードとバイトのあなたの要求された範囲を返しますサポートしています。 http://benramsey.com/archives/206-partial-見ますコンテンツおよびレンジ・リクエスト/ の範囲要求の素敵な説明のために。
ファイルを送信するためにPHPを使用した場合、ページ全体がダウンロードされます。 fopen
呼び出しても、そのページからは 6kb しか読み取られません。
PHPマニュアルより:
次の条件のいずれかが満たされるとすぐに読み取りが停止します。
- 長さ バイトが読み取られました