python之多進程和多協成爬蟲

——在學完多線程爬蟲之後,我們多多少少了解了一些關於提升爬蟲速度的方法。接下來我們學習的另外一種方法多進程爬蟲。之前我學習的多線程方法來說是基於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!")

代碼下載地址:點擊這裏

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章