解析部分を実装したWebクローラーを構築しています。ここで、取得した URI を効率的なデータ構造に格納したいと考えています。何を使えばいいの??解析には Jena ライブラリを使用しています。
5 に答える
一般に、Webクロールアプリケーションでは、URLを管理してスパイダートラップ(「ブラックホール」と呼ばれることもあります)を破棄し、同じページへの頻繁なアクセスを破棄する必要があります。また、URLをページコンテンツのグローバル識別子として使用します。
しかし、もう1つの興味深い瞬間は、同じURLへのアクセスを2回破棄するのは間違っていることです(Webページのコンテンツは時間の経過とともに変更される可能性があるため)。
したがって、これらの要件を満たすための最良の方法は、ある種の優先キューを使用し、各URLをタプルに関連付けることです:{url、hash(url) }。新しいURLを取得したら(ハッシュを計算するだけで、データベースレコードに同じハッシュがある場合は、このURLに低い優先度を設定して、優先度キューに入れます)。
Webクローラーは、アクセスするURLの優先キューを要求します。したがって、優先度が最も高いURLを持つページのみが主にアクセスされます。
ニーズに最適な独自のハッシュ関数を作成できます(たとえば、URL文字列からパラメータを削除し、残りの文字列からハッシュを計算します)。
URIが2回クロールされないように、重複を自動的に破棄したいと思いますか?次に、 HashSetを提案します。
重複は自動的に破棄され、最適な場合でも挿入の複雑さは一定です。デフォルトのクラスjava.net.URIint hashCode()
ではなく独自のクラスを使用してURIを表す場合、URI文字列のテキストベースのハッシュを返すには、URIクラスのメソッドをオーバーライドする必要があることに注意してください。Objectのデフォルトのメソッドは、コンテンツが同一であっても、オブジェクトごとに一意のハッシュコードを作成します。
クローラーは通常、 を使用しQueue
て検査対象の URI を保持し、 を使用しSet
て重複をチェックしてから、前述のキューに URI を挿入し、検査後に URI をセットに入れます。
リンクの数がメモリ内に収まる場合はLinkedList
、キューHashSet
としてもセットとしてもできます。それ以外の場合は、外部データベースを両方の目的で使用するか、キュー サーバー (ActiveMQ など) をキューとして使用し、データベースをセットとして使用できます。
処理する URI のキューと、既に処理された URI を Redis (http://redis.io/) に保存します。Redis は、リスト (URI のキュー) やハッシュ (マップ) などのさまざまなデータ構造をネイティブにサポートする、非常に高速な半永続的なキー値ストアです。そうすれば、これらのデータ構造は Java アプリケーションの再起動後も存続します。また、Redis 経由の通信にあまり問題なく、アプリの複数のインスタンスを実行することもできます。
ハッシュ。
例: URL: scheme://domain:port/path?query_string#fragment_id.
URL を文字列として解析した後、URL を次のように保存します。
ハッシュ['スキーム'] =スキーム;
ハッシュ['ドメイン'] = ドメイン;
ハッシュ['ポート'] = ポート;
ハッシュ['パス'] = パス;
hash['query_string'] = query_string;
ハッシュ['fragment_id'] = fragment_id;