让我们假设我想在Google搜索“hello”这个词。然后,我想转到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页上完成。我如何分配负载,以便我可以(例如)打开三个驱动程序,每个驱动程序将“检出”一个页面。例如:
我理解这将如何工作的原理,但实际的代码是什么才能实现这个工作的基本实现?
答案 0 :(得分: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获取一个页面,然后获取它链接到的每个页面。
答案 1 :(得分:0)
不直接回答您的问题,但提出可能使您的代码在单个进程中可用的途径,从而避免不同线程/进程之间的同步问题......
您可能最好使用Twisted这样的框架来启用异步网络操作,以便将所有操作保持在同一个进程中。在您的代码中,HTML代码的解析可能比获取页面所需的完整网络操作花费的时间少得多。因此,使用异步IO,您可以同时启动几个请求,并仅在响应到达时解析结果。实际上,每次返回页面时,您的进程很可能在runloop中“空闲”。