前面说的multiprocessing里面的Process动态生成多个进程,如果限制数量过大就繁琐了,现在就可以使用Pool进程的功效。
在使用Pool前,我们先了解一下阻塞和非阻塞两个概念。
阻塞和非阻塞关注的是程序在等待调用结果时的状态。阻塞要等到回调结果出来,在有结果之前,当前进程会被挂起。非阻塞为添加进程后,不一定非要等待结果出来就可以添加其它的进程。
我们现在开始使用Pool的非阻塞和Queue来获取网页数据:
import multiprocessing import pool,Manager
import time
import requests
link_list=[]
with open('eqwaak.txt','r') as file:
file_list=file.readlines()
for eachone in file_list:
link=eachone.split('\t')[1]
link=link.replace('\n','')
link_list.append(link)
strat=time.time()
def crawler(q,index):
Process_id='Process-'+str(index)
while not q.empty():
url=q.get(timeout=2)
try:r=requests.get(url,timeout=20)
print(Process_id,q.qsize(),r.status_code,url)
except Exception as e:
print(Process_id,q.qsize(),url,'Error',e)
if __name__ == '__main__':
manager=Manager()
workQueue=manager.Queue(1000)
for url in link_list:
workQueue.put(url)
pool=pool(prscesses=3)
for i in range(4):
pool.apply_async(crawler,args=(workQueue,i))
print('started ')
pool.close()
pool.join()
end=time.time()
print('Pool+Queue多进程爬虫的时间:',end-strat)
print('END')
如果我们要将线程池Pool和Queue结合起来,Queue就需要改变,用到前面multiprocessing里面的Manger,使用manger=Manger()和workQueue=manager.Queue(1000)来创建列表:
pool=Pool(processe=3)
for i in range(4):
pool.apply_async(crawler,args=(workQueue,i))
上面我们使用的是非阻塞方法,换成阻塞也简单:将pool.apply_async(target=func,args=(args)改为pool.apply(target=func,args=(args))就好了。