7

Wgetのマニュアルで次の一文が目に留まりました

wget --spider --force-html -i bookmarks.html

This feature needs much more work for Wget to get close to the functionality of real web spiders.

wget のスパイダー オプションに関連する次のコード行が見つかりました。

src/ftp.c
780:      /* If we're in spider mode, don't really retrieve anything.  The
784:      if (opt.spider)
889:  if (!(cmd & (DO_LIST | DO_RETR)) || (opt.spider && !(cmd & DO_LIST)))
1227:      if (!opt.spider)
1239:      if (!opt.spider)
1268:      else if (!opt.spider)
1827:          if (opt.htmlify && !opt.spider)

src/http.c
64:#include "spider.h"
2405:  /* Skip preliminary HEAD request if we're not in spider mode AND
2407:  if (!opt.spider
2428:      if (opt.spider && !got_head)
2456:      /* Default document type is empty.  However, if spider mode is
2570:           * spider mode.  */
2571:          else if (opt.spider)
2661:              if (opt.spider)

src/res.c
543:  int saved_sp_val = opt.spider;
548:  opt.spider       = false;
551:  opt.spider       = saved_sp_val;  

src/spider.c
1:/* Keep track of visited URLs in spider mode.
37:#include "spider.h"
49:spider_cleanup (void)

src/spider.h
1:/* Declarations for spider.c

src/recur.c
52:#include "spider.h"
279:      if (opt.spider)
366:              || opt.spider /* opt.recursive is implicitely true */
370:             (otherwise unneeded because of --spider or rejected by -R) 
375:                   (opt.spider ? "--spider" : 
378:                     (opt.delete_after || opt.spider
440:      if (opt.spider) 

src/options.h
62:  bool spider;           /* Is Wget in spider mode? */

src/init.c
238:  { "spider",           &opt.spider,            cmd_boolean },

src/main.c
56:#include "spider.h"
238:    { "spider", 0, OPT_BOOLEAN, "spider", -1 },
435:       --spider                  don't download anything.\n"),
1045:  if (opt.recursive && opt.spider)

抽象的にではなく、コードの違いを確認したいと思います。コード例が大好きです。

Web スパイダーと Wget のスパイダーのコードの違いは?

4

4 に答える 4

33

本物のクモは大変な作業です

WWW 全体のスパイダーを作成するのはかなりの作業です。

  • 各スパイダー コンピューターは、接続帯域幅を効率的に使用するために、数千のサーバーからデータを並行して受信する必要があります。(非同期ソケット入出力)。
  • WWW 上の膨大な量の情報をカバーするには、並列にスパイダーする複数のコンピューターが必要です (クラスター化; 作業の分割)。
  • スパイダー Web サイトには礼儀正しくする必要があります。
    • robots.txt ファイルを尊重します。
    • 大量の情報をすばやく取得しないでください。サーバーに過負荷がかかります。
    • 本当に必要のないファイルをフェッチしないでください (たとえば、iso ディスク イメージ、ソフトウェア ダウンロード用の tgz パッケージなど)。
  • Cookie/セッション ID を処理する必要があります。多くのサイトでは、一意のセッション ID を URL に添付して、クライアント セッションを識別しています。サイトにアクセスするたびに、新しいセッション ID とページの新しい仮想世界 (同じコンテンツを持つ) を取得します。このような問題のため、初期の検索エンジンは動的コンテンツを無視していました。最新の検索エンジンは、問題の内容と対処方法を学習しています。
  • 問題のあるデータを検出して無視する必要があります: 一見無限の量のデータを提供する接続や、終了するには遅すぎる接続です。
  • リンクをたどる以外に、サイトマップを解析してページの URL を取得したい場合があります。
  • どの情報が重要で、頻繁に変更され、他のページよりも頻繁に更新されるかを評価することができます。注: WWW 全体のスパイダーは大量のデータを受信します --- その帯域幅に対して料金が発生します。HTTP HEAD リクエストを使用して、ページが変更されたかどうかを推測することができます。
  • 受け取るだけでなく、情報を処理して保存したい。Google は、単語ごとにその単語を含むページをリストするインデックスを作成します。個別のストレージ コンピューターとそれらを接続するためのインフラストラクチャが必要になる場合があります。従来のリレーショナル データベースは、WWW 全体を格納/インデックス化するためのデータ ボリュームとパフォーマンス要件に対応できていません。

これは大変な作業です。しかし、あなたのターゲットが WWW 全体を読むより控えめな場合は、いくつかの部分をスキップすることができます。wiki などのコピーをダウンロードしたいだけの場合は、wget の仕様に取り掛かります。

注: そんなに大変な作業だと思わない場合は、Google が (基本的な Linux カーネルの上に) コンピューティング ホイールのほとんどをどのように再発明して優れたスパイダーを構築したかを読んでみてください。いくら手抜きしても大変な作業です。

3 つの点について、技術的な注意点をいくつか追加させてください。

並列接続・非同期ソケット通信

並列プロセスまたはスレッドで複数のスパイダー プログラムを実行できます。ただし、ネットワーク接続を十分に活用するには、約 5000 ~ 10000 の並列接続が必要です。そして、この量の並列プロセス/スレッドは、あまりにも多くのオーバーヘッドを生み出します。

より良い解決策は、非同期入力/出力です。ノンブロッキング モードでソケットを開き、epoll または select を使用して、データを受信した接続のみを処理することにより、1 つの単一スレッドで約 1000 の並列接続を処理します。Linux カーネル 2.4 以降、Linux はスケーラビリティの優れたサポートを備えており (メモリ マップド ファイルを調べることもお勧めします)、以降のバージョンで継続的に改善されています。

注: 非同期 I/O を使用すると、「高速言語」を使用するよりもはるかに役立ちます。C で記述された 1000 プロセスを実行するよりも、Perl で記述された 1000 接続用の epoll 駆動プロセスを記述する方が適切です。 perl で書かれたプロセスで 100Mb 接続を飽和させます。

元の回答から: このアプローチのマイナス面は、非同期形式で HTTP 仕様を自分で実装する必要があることです (これを行う再利用可能なライブラリについては知りません)。これは、最新の HTTP/1.1 プロトコルよりも単純な HTTP/1.0 プロトコルを使用する方がはるかに簡単です。いずれにしても、通常のブラウザーでは HTTP/1.1 の利点を享受できない可能性があるため、これは開発コストを節約するのに適した場所かもしれません。

5 年後に編集: 今日、この作業を支援するために利用できる無料/オープン ソースのテクノロジが多数あります。個人的には、 node.jsの非同期http 実装が気に入っています--- これにより、上記の元の段落で述べたすべての作業を省くことができます。もちろん、今日では、スパイダーに必要な他のコンポーネント用にすぐに利用できるモジュールも多数あります。ただし、サードパーティ製モジュールの品質はかなり異なる場合があることに注意してください。どんなものを使っているかチェックする必要があります。【エイジング情報】最近、node.js を使用してスパイダーを作成しましたが、リンクとデータ抽出のための HTML 処理のための npm モジュールの信頼性が不十分であることがわかりました。この仕事のために、私はこの処理を別のプログラミング言語で書かれたプロセスに「外注」しました。しかし、状況は急速に変化しており、このコメントを読む頃には、この問題はすでに過去のものになっている可能性があります...

作業を複数のサーバーに分割する

1 台のコンピューターでは、WWW 全体をスパイダーするのに追いつくことはできません。作業を複数のサーバーに分散し、それらの間で情報を交換する必要があります。各サーバーに特定の「ドメイン名の範囲」を割り当てることをお勧めします。スパイダー コンピューターへの参照を使用して、ドメイン名の中央データベースを保持します。

受信した Web ページから URL をバッチで抽出します。ドメイン名に従って並べ替えます。重複を削除し、責任のあるスパイダー コンピューターに送信します。そのコンピューターで、既に取得された URL のインデックスを保持し、残りの URL を取得します。

各スパイダー コンピューターで取得されるのを待機する URL のキューを保持している場合、パフォーマンスのボトルネックは発生しません。しかし、これを実装するにはかなりのプログラミングが必要です。

基準を読む

いくつかの標準 (HTTP/1.x、Robots.txt、Cookies) について言及しました。時間をかけてそれらを読み、実装してください。知っているサイトの例に従うだけでは、間違いを犯し (サンプルに関係のない標準の部分を忘れる)、これらの追加機能を使用するサイトで問題が発生します。

HTTP/1.1 標準ドキュメントを読むのは面倒です。しかし、誰かが本当にその細部を必要としていて、今それを使用しているので、すべての細部がそれに追加されました.

于 2009-05-12T12:47:11.703 に答える
4

コメントの元の作成者が何を参照していたのか正確にはわかりませんが、wget は単一の実行スレッドしか使用していないように見えるため (少なくともあなたが示したものから)、スパイダーとして遅いと推測できます。

heritrixなどの「本物の」スパイダーは、多くの並列処理とトリックを使用してクロール速度を最適化すると同時に、クロールしている Web サイトに優しくします。これは通常、1 つのサイトへのヒットを 1 秒あたり 1 回程度に制限し、同時に複数の Web サイトをクロールすることを意味します。

繰り返しますが、これはすべて、私が一般的にクモについて知っていることと、あなたがここに投稿したことに基づいた単なる推測です.

于 2009-04-17T21:34:40.207 に答える
1

インターネットをスパイダーする方法については詳しく説明しませんが、wget のコメントは、まだ深刻な課題である 1 つの Web サイトをスパイダーすることに関するものだと思います。

  • スパイダーとして、URL が date=1/1/1900 から 1/2/1900 のように変更されたという理由だけで、再帰的なクロールに入るのではなく、停止するタイミングを把握する必要があります。
  • URL Rewrite を整理するというさらに大きな課題です (Google や他の会社がこれをどのように処理するかはまったくわかりません)。十分にクロールするのはかなり大きな挑戦ですが、あまりクロールしません。そして、いくつかのランダムなパラメーターとコンテンツのランダムな変更を使用して、URL Rewrite を自動的に認識するにはどうすればよいでしょうか?
  • 少なくともある程度までは Flash / Javascript を解析する必要があります
  • ベースタグのようないくつかのクレイジーな HTTP の問題を考慮する必要があります。ほとんどの Web サイトが XHTML ではなく、ブラウザーの構文が非常に柔軟であることを考えると、HTML の解析も簡単ではありません。

これらのうちどれだけが wget で実装または考慮されているかはわかりませんが、httrack を見て、このタスクの課題を理解することをお勧めします。

いくつかのコード例を提供したいと思いますが、これは大きなタスクであり、適切なスパイダーはサードパーティ ライブラリなしで約 5000 loc になります。

+ それらのいくつかは @yaakov-belch によってすでに説明されているので、再度入力するつもりはありません

于 2009-05-13T20:09:51.310 に答える