1. 程式人生 > >python爬蟲——多程序multiprocessing

python爬蟲——多程序multiprocessing

其實多程序相對來說不是特別適合用來做爬蟲,因為多程序比較適用於計算密集型,而爬蟲是IO密集型,因此多程序爬蟲對速度的提升不是特別明顯,但是將爬蟲改為多程序比較簡單,只需簡單的幾行程式碼即可搞定,所以在修改我的爬蟲提升效率時,我最先實現的是多程序爬蟲。(然而速度真心還是慢,我多執行緒+協程的程式跑的晚,卻早已經結束工作了,多程序的還在苦戰…)
下面我通過例項來進行介紹。
我爬取的資料是外文資料庫的摘要資訊,總共有幾百萬條記錄,因此我首先將抓取得到的url列表檔案進行分割,減小對記憶體的壓力,免得全部載入佔用記憶體過高(昨天看了關於迭代器的內容,感覺如果使用迭代器的話,效果會更好一點,減少很多記憶體壓力,等我試水成功後再更新)。由於很多小夥伴可能沒有訪問外文資料庫的許可權,因此我在此不把url資料上傳,對抓取的html頁面進行分析的內容也不放上來。主要介紹如何改造原有程式碼為多程序爬蟲。

#python2環境,3下差別不大
import requests
from bs4 import BeautifulSoup
import multiprocessing
import json
import datetime
import sys
reload(sys)
sys.setdefaultencoding('utf-8')
path = sys.path[0] + '/data/'

多程序需要匯入multiprocessing包。

def main():
    f = open(path + 'springerThesissList.txt', 'r')
    urlList = f.readlines() 
    pool = multiprocessing.Pool(3
) #建立程序池,數字為你cpu的核數,括號內可以為空,程式會自動設定為cpu最大核數。 pool.map(getThesis, urllist) #將url傳入getThesis函式 def getThesis(url): """this is your code of scrap the url"""
if __name__ == '__main__':
    stime = datetime.datetime.now()
    print stime
    main()
    etime = datetime.datetime.now()
    print
etime print etime - stime

getThesis(url)函式為抓取url下內容的函式,可自定義。
通過main()函式中的短短兩行程式碼,我們就可以將爬蟲改造成多程序爬蟲了,但是上面的方法有一個問題,就是得到的檔案中會有這樣一種情況:當前行的內容還未寫入完畢,下一行的內容就已寫入。原因是多程序是併發執行函式,你在程序池中設立的數目為3,則就有三個程序同時進行抓取,並訪問檔案寫入資料,這樣就會出現上面的問題。可以通過下面的方法進行解決。

def main():
    listf = open(path + 'springerThesisList.txt', 'r')
    urlList = listf.readlines()
    pool = multiprocessing.Pool(3)
    for url in urllist:
        result = pool.apply_async(getThesis, (url, ), callback = jsonDump)
    pool.close()
    pool.join()
    if result.successful():
        print "successful"

jsonDump函式為我自定義的寫入json資料的函式。此處將其作為回撥函式對getThesis函式的返回結果進行處理。因此getThesis函式與之前的也略有不同,之前不需要該函式有返回值,但是在此處則需將其進行修改,在函式末尾加入一行程式碼,返回此函式抓取到的資料。因為在函式中我使用了try except來增強程式碼的容錯性,因此返回值有可能為空,因此在jsonDump函式中,需要先判斷dic是否為空。

outf = open(path + 'springerThesis.json', 'a')
def jsonDump(dic):
    if dic:
        json.dump(dic, outf, ensure_ascii=False)
        outf.write('\n')
def getThesis(url):
    """this is your code of scrap the url"""
    #×××
    #×××
    return dic

到此為止,基本上講清楚瞭如何在爬蟲中使用多程序。有問題歡迎評論交流。
接下來我會介紹如何在爬蟲中使用多執行緒和協程來提高爬蟲的速度。