2

私はPythonで書かれた非常に基本的なマルチスレッドのWebクローラーを作成しており、次のように、ページをクロールしてURLを抽出する関数にWhileループを使用しています。

def crawl():
    while True:
        try:
            p = Page(pool.get(True, 10))
        except Queue.Empty:
            continue

        # then extract urls from a page and put new urls into the queue

(完全なソースコードは別の質問にあります:マルチスレッドのPython Webクローラーがスタックしました)

ここで理想的には、Whileループに条件を追加して、次の場合にwhileループを終了させます。

  1. プール(URLを格納するQueueオブジェクト)は空であり、;

  2. すべてのスレッドがブロックされ、キューからURLを取得するのを待機しています(つまり、新しいURLをプールに入れているスレッドがないため、待機し続けることは意味がなく、プログラムがスタックします)。

たとえば、次のようになります。

#thread-1.attr == 1 means the thread-1 is blocking. 0 means not blocking

while not (pool.empty() and (thread-1.attr == 1 and thread-2.attr == 1 and ...)):
    #do the crawl stuff

ですから、他のアクティブなスレッドが何をしているのか、または他のアクティブなスレッドの属性のステータスや値をチェックするためのスレッドがないのではないかと思います。

threading.Event()の公式ドキュメントを読みましたが、それでも理解できません。

ここの誰かが私に道を教えてくれることを願っています:)

どうもありがとうございます!

マーカス

4

2 に答える 2

1

あなたは最初からあなたが望むものを実装することを試みることができます、今私の頭に浮かぶさまざまな解決策があります:

  • threading.enumerate( )を使用して、まだ生きているスレッドがあるかどうかを確認します。
  • プールに返されるスレッドaがまだ生きていることを通知するスレッドプールを実装してみてください。これには、サードパーティのWebサイトをクロールするスレッドの数を制限するという利点もあります(たとえば、ここを確認してください)。

車輪の再発明をしたくない場合は、スレッドプールを実装する既存のライブラリを使用するか、グリーンスレッドを使用してスレッドプールも提供するgeventを確認することもできます。次のようなものを使用して、これに似たものを実装しました。

while 1:
    try:
        url = queue.get_nowait()
    except Empty:
        # Check that all threads are done.
        if pool.free_count() == pool.size:
            break
    ...

クロールの終了をマークし、メインループが存在し、スレッドが終了するのを待つセンチネルオブジェクトをキューに書き込むこともできます(たとえば、プールを使用)。

while 1:
    try:
        url = queue.get_nowait()
        # StopIteration mark that no url will be added to the queue anymore.
        if url is StopIteration:
             break
    except Empty:
        continue
    ...
pool.join()

あなたはあなたが好むものを選ぶことができます、そしてうまくいけばこれは役に立ちました。

于 2013-01-21T15:45:04.290 に答える
0

このソリューションを検討してください:Twistedを使用したWebクローラー。その質問への答えが言うように、私はあなたがhttp://scrapy.org/を見ることもお勧めします

Pythonでのマルチスレッド(スレッドを直接使用する)は厄介なので、それを避けて、ある種のメッセージパッシングまたはreactorベースのプログラミングを使用します。

于 2013-01-21T15:37:30.207 に答える