0

「こんにちは」という単語をグーグル検索したいとしましょう。次に、Google の最初の 100 ページのすべてのリンクにアクセスし、そのリンクされたページの HTML をダウンロードします。1 ページあたり 10 件の結果があるため、約 1,000 件のリンクをクリックする必要があります。

これは、単一のプロセスで行う方法です。

from selenium import webdriver
driver=webdriver.Firefox()
driver.get('http://google.com')

# do the search
search = driver.find_element_by_name('q')
search.send_keys('hello')
search.submit()

# click all the items
links_on_page = driver.find_elements_by_xpath('//li/div/h3/a')
for item in links_on_page:
    item.click()
    # do something on the page
    driver.back()

# go to the next page
driver.find_element_by_xpath('//*[@id="pnnext"]')

これを 100 ページで行うには、明らかに非常に長い時間がかかります。(たとえば) 3 つのドライバーを開き、それぞれがページを「チェックアウト」するように、負荷を分散するにはどうすればよいでしょうか。例えば:

  • ドライバー #1 はページ 1 をチェックアウトします。ページ 1 を開始します。
  • ドライバー #2 は、ページ 1 がチェックアウトされていることを確認し、ページ #2​​ に移動します。ページ 2 を開始します。
  • ドライバー #3 は、ページ 1 がチェックアウトされていることを確認し、ページ #2​​ に移動します。2ページ目も同様。3ページ目から。
  • ドライバー #1 はページ 1 で作業を終了し、ページ 4 を開始します。

これがどのように機能するかの原則は理解していますが、これを機能させる基本的な実装を取得するための実際のコードは何でしょうか?

4

2 に答える 2

0

おそらくmultiprocessing Pool. そのためには、ページ番号でパラメーター化されたメソッドを記述します。

def get_page_data(page_number):
    # Fetch page data
    ...
    # Parse page data
    ...
    for linked_page in parsed_links:
        # Fetch page source and save to file
        ...

次に、Pool適切と思われる多くのプロセスを使用します (この数を決定するには、おそらくいくつかの実験が必要になります)。

from multiprocessing import Pool

if __name__ == '__main__':
    pool = Pool(processes=4)
    pool.map(get_page_data, range(1,101))

これにより、4 つのプロセスが開始され、それぞれが Google からページを取得し、次にリンク先の各ページを取得します。

于 2012-05-18T23:52:43.450 に答える
0

質問に直接答えるのではなく、単一のプロセスでコードを使用できるようにする手段を提案することで、異なるスレッド/プロセス間の同期の問題を回避します...

すべての操作を同じプロセス内に保持するために、非同期ネットワーク操作を可能にする Twisted などのフレームワークを使用することをお勧めします。あなたのコードでは、HTML コードの解析にかかる時間は、ページを取得するために必要な完全なネットワーク操作よりもはるかに短い時間である可能性があります。したがって、非同期 IO を使用すると、同時にいくつかの要求を開始し、応答が到着したときにのみ結果を解析できます。実際には、ページが返されるたびに、プロセスは実行ループで「アイドリング」している可能性があります。

于 2012-05-19T01:50:07.453 に答える