クローラーのクロール速度に大きく依存します。シングル スレッドのクローラーを使用している場合、平均して 1 秒あたり 1 ページよりも優れた処理を行うことはできません。したがって、 HashSetを使用して、アクセスした URL を保存できます。または、アクセスした URL に関する情報を保存する場合は、 を使用できますDictionary<string, UrlInfo>
。ここで、UrlInfo
は、アクセスした各 URL について保持したい情報を含む、定義したクラスです。
1 日あたり 86,400 秒で、HashSet
orDictionary
はかなりの数日分のデータを保存します。
しかし、おそらく同じ画像を複数回ダウンロードしたくないでしょう。したがって、私が「オフライン」または「クロール - プロセス - クロール」モデルと呼んでいるものの方が適しているかもしれません。仕組みは次のとおりです。
クロールを開始すると、特定した数千のページにアクセスします。ページをダウンロードし、リンクを抽出して、それらのリンクをログ ファイルに書き込みます。画像が見つかったら、それらをダウンロードして保存します。アクセスするすべてのページもファイルに書き込まれます。
これらのページにアクセスし終わったら、クローラーを停止します。アクセスしたページと見つけたリンクの 2 つのリストがファイルに保存されました。
訪問したリンクを並べ替えて、以前に訪問したページのリストとマージします。そのファイルは、時間の経過とともにかなり大きくなる可能性があります。
抽出したリンクのリストを並べ替え、重複を削除します。次に、これらのリンクを、既にアクセスしたページのリストと照合します。これはマージで最も簡単です。リンクが既にアクセスされている場合は、破棄します。それ以外の場合は、次のクロール セッションで使用されるファイルに書き込みます。
これは単純なデータベースの場合は簡単ですが、データベースが非常に大きくなることに注意してください。データベースを使用すると、クロール-プロセス-クロールする必要はありません。代わりに、抽出した各リンクをデータベースに対してチェックし、すぐに保存または破棄することができます。
ただし、データベースにかなりの負荷がかかることを理解しておいてください。クロールに関する私の経験では、平均して、Web ページには 100 を超えるリンクが含まれています (<a href="...">
つまり、画像は含まれません。シングル スレッドのクローラーで、少なくとも 1 秒間に 100 回、そのデータベースにアクセスすることになります。
遭遇するもう 1 つの問題は、見つけたすべての URL にアクセスできるわけではないということです。時間が経つにつれて、平均的な Web ページから抽出した 100 個のリンクのうち、10 個が今まで見たことのない新しいリンクであることがわかりました。つまり、読んだページごとに、まだ読んでいないページがさらに 10 ページ見つかります。最終的には、画像に誘導する可能性が低い URL を除外する何らかの方法が必要になります。
アクセスした URL を追跡するもう 1 つの方法は、ブルーム フィルターを使用することです。私はこれらを Web クローラーで非常に効果的に使用しました。