——在學完多線程爬蟲之後,我們多多少少了解了一些關於提升爬蟲速度的方法。接下來我們學習的另外一種方法多進程爬蟲。之前我學習的多線程方法來說是基於GIL雖然說速度有了明顯的提升,但是對CPU的資源利用沒有充分;然而,多進程是利用CPU核數進行的進行的操作,這需要用python中的muiltprocessing這個庫。
1、使用mulitProcessing的多進程爬蟲
++++一般情況下,我們寫這種多進程的爬蟲時,需要先獲取相應的電腦的CPU核心數,以防止使用核心過多導致電腦死機。
代碼如下:
from multiprocessing import Process,Queue
import requests
import time
link_list = []
with open('url.txt','r') as file:
file_list = file.readlines()
for each in file_list:
link = each.split('\t')[1]
link = link.replace('\n','')
link_list.append(link)
start = time.time()
class MyProcess(Process):
def __init__(self,q):
Process.__init__(self)
self.q = q
def run(self):
print('Starting ',self.pid)
while not self.q.empty():
crawler(self.q)
print('Exiting ',self.pid)
def crawler(q):
url = q.get(timeout=2)
try:
r = requests.get(url,timeout=20)
print(q.qsize(),r.status_code,url)
except Exception as e:
print(q.qsize(),url,'Error: ',e)
if __name__ == '__main__':
ProcessName = ["Process-1","Process-2","Process-3"]
workQueue = Queue(300)
for url in link_list:
workQueue.put(url)
for i in range(4):
p = MyProcess(workQueue)
p.daemon = True
p.start()
p.join()
end = time.time()
print("Process+Queue多線程爬蟲總的時間:",end-start)
print("Exiting Main Thread!")
*注意:
p.daemon = True
這句代碼的意思就是當所有的父進程關閉時,字進程就會被關閉。
2、使用pool+Queue的多進程爬蟲
++++當被操作的對象數目不大時,可以利用Process+Queue類的方法來實現這一操作,但是操作對象如果過多,上百個、上千個等等時,手動的限制進程數就太過繁瑣,此時可以使用Pool發揮進程池的功效。
++++Pool可以提供指定數量的進程供用戶來使用。當有了新的請求提交到pool中,如果池還沒有滿,就會創建一個新的進程用來執行該請求;但是如果池中的進程已經達到規定的最大值,請求就會繼續等待,知道池中的有進程結束才能夠創建新的進程。
++++現在我們使用非阻塞的方法和Queue獲取網頁數據,代碼如下:
from multiprocessing import Pool,Manager
import requests
import time
link_list = []
with open('url.txt','r') as file:
file_list = file.readlines()
for each in file_list:
link = each.split('\t')[1]
link = link.replace('\n','')
link_list.append(link)
start = 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__':
managers = Manager()
workQueue = managers.Queue(300)
for url in link_list:
workQueue.put(url)
pool = Pool(processes=3)
for i in range(4):
pool.apply_async(crawler,args=(workQueue,i))
pool.close()
pool.join()
end = time.time()
print("Pool+Queue多線程爬蟲總的時間:",end-start)
print("Exiting Main Thread!")
代碼下載地址:點擊這裏