2017-10-19 134 views
-1

我想分析一個包含多個頁面的網站。Python多處理 - 按需使用工作人員

我不知道頁數。 這是原來的代碼:

 next_button=soup.find_all('a',{'class':"btn-page_nav right"}) 
     while next_button: 
      link=next_button[0]['href'] 
      resp=requests.get('webpage+link) 
      soup=BeautifulSoup(resp.content) 
      table=soup.find('table',{'class':'js-searchresults'}) 
      body=table.find('tbody') 
      rows=body.find_all('tr') 
      function(rows) 
      next_button=soup.find_all('a',{'class':"btn-page_nav right"}) 

它工作正常,function(rows)是解析每個頁面的一部分的功能。

我想要做的是使用multiprocessing解析這些頁面。我想過使用3名工人的pool,以便我可以一次處理3頁,但我無法弄清楚如何實施它。

一種解決方案是這樣的:

rows_list=[] 
next_button=soup.find_all('a',{'class':"btn-page_nav right"}) 
while next_button: 
    link=next_button[0]['href'] 
    resp=requests.get('webpage+link) 
    soup=BeautifulSoup(resp.content) 
    table=soup.find('table',{'class':'js-searchresults'}) 
    body=table.find('tbody') 
    rows=body.find_all('tr') 
    rows_list.append(rows) 
    next_button=soup.find_all('a',{'class':"btn-page_nav right"}) 

等待程序遍歷所有頁面,然後:

pool=multiprocessing.Pool(processes=4) 
pool.map(function,rows_list) 

但我不認爲這會提高性能太多了,我希望主進程遍歷頁面,一旦打開頁面,就將其發送給工作人員。 這個怎麼辦?一個虛擬的例子:

pool=multiprocessing.Pool(processes=4) 

next_button=soup.find_all('a',{'class':"btn-page_nav right"}) 
while next_button: 
    link=next_button[0]['href'] 
    resp=requests.get('webpage+link) 
    soup=BeautifulSoup(resp.content) 
    table=soup.find('table',{'class':'js-searchresults'}) 
    body=table.find('tbody') 
    rows=body.find_all('tr') 

    **pool.send_to_idle_worker(rows)** 

    next_button=soup.find_all('a',{'class':"btn-page_nav right"}) 

回答

0

你可以使用concurrent包,而不是multiprocessing。例如:

import concurrent.futures 

with concurrent.futures.ProcessPoolExecutor() as executor: 
    while next_button: 
     rows = ... 
     executor.submit(function, rows) 
     next_button = ... 

可以與勞動者與executor = ProcessPoolExecutor(max_workers=10)任意數量實例化executor,但如果不給,max_workers將默認達您計算機上的內核。 Further details in the python docs

0

您能用Pool.apply_async()代替Pool.map()嗎? Apply_async不會阻止並允許主程序繼續處理更多行。它也不需要你的主程序準備好所有的數據進行映射。您只需將一個塊作爲參數傳遞給apply_async()