0

让我们假设我想在谷歌上搜索“你好”这个词。然后,我想访问 Google 前 100 个页面上的每个链接,并下载该链接页面的 HTML。由于每页有 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 页上完成。我将如何分配负载,这样我可以(例如)打开三个驱动程序,每个驱动程序都会“签出”一个页面。例如:

  • 驱动程序 #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 回答