1

シンプルなWebスパイダーを作成しています。URLを受け入れ、HTMLをダウンロードして、残りのURLを抽出するだけです。次に、新しいURLごとにこのプロセスを繰り返します。また、同じURLに2回アクセスしないようにし、同時ダウンロードの数を制限しています。

すべての一意のURLが使い果たされた後(数日、数週間、または死んで消えるまで実行される可能性があります)、UIを更新したり、単にアプリケーションを終了したりするなどのアクションを実行したいと思います。

問題は、最後のスレッドの実行が終了したことを検出する方法がわからないことです。

このスレッドの問題は解決されましたか?私は問題を間違って見ていますか?

1つの考えは、すべての子が終了する(参加する)まで、各スレッドを存続させることでした。問題は、スレッドの数が指数関数的に増加することです。このような長時間実行されるプロセスの場合、OSリソースをすぐに使い果たしてしまいます。

4

1 に答える 1

2

私たちが話している言語がわからないので、一般的に話します。

URLごとに、そこから生成される「子」ページの数を追跡するデータ構造が必要です。URLがスパイダーされているときはいつでも、「親」データ構造になります。新しいページが見つかるたびに、は親のツリーカウントに追加されます。ページがスパイダーされるたびに、親のツリー数が減少します。複数のスレッドが更新するため、これは同期して実行する必要があります。

実際には、URL構造全体を保存したい場合があります。ルートURL「http://foo.x/」には「/1.html」と「/2.html」へのリンクがあるため、children-countは2です。ルートURLにはnull親があり、「1」と「2」があります。 "ルートの親があります。「1.html」がスパイダーされると、ルートの子カウントが1に減少します。ただし、「1.html」内に3つのリンクがある場合、ルートのカウントは4に増加します。ツリーを追跡する場合次に、「1.html」の子の数は3になります。次に、「1.html」の子の1つがスパイダーされると、「1.html」の数は2になり、ルートURLの数は3になります。

あなたは確かにあなたが言及するようにスレッドを維持して後で参加することを望まないでしょう-あなたのスレッド数は爆発的に増加します。スレッドプールを使用して、同じスレッドでスパイダーできるように、それぞれがURLツリーに関連付けられたノードを持つスパイダーにURLを送信する必要があります。

URLがスパイダーされ、子の数が0になると、ツリー全体がスパイダーされたことがわかり、URLを作業リストから削除して、完了リストに移動できます。繰り返しますが、これらのリストは複数のスレッドが動作するため、同期する必要があります。

これがいくらか役立つことを願っています。

于 2012-05-24T13:59:20.953 に答える