python爬取豆瓣兩千萬圖書簡介信息:(四)多進(jìn)程并發(fā)

這是全部的調(diào)試過程,我已經(jīng)整理成為筆記药版,這里分享給大家:
python爬取豆瓣兩千萬圖書簡介信息:(一)目標(biāo)API分析
python爬取豆瓣兩千萬圖書簡介信息:(二)簡單python請求urllib2
python爬取豆瓣兩千萬圖書簡介信息:(三)異常處理
python爬取豆瓣兩千萬圖書簡介信息:(四)多進(jìn)程并發(fā)
python爬取豆瓣兩千萬圖書簡介信息:(五)數(shù)據(jù)庫設(shè)計(jì)
python爬取豆瓣兩千萬圖書簡介信息:(六)數(shù)據(jù)庫操作類
python爬取豆瓣兩千萬圖書簡介信息:(七)代理IP
python爬取豆瓣兩千萬圖書簡介信息:(八)總結(jié)

多進(jìn)程并發(fā)

我寫的python爬取數(shù)據(jù)程序,爬取的目標(biāo)很明確毁涉,就是爬取豆瓣API的所能提供的 兩千萬圖書簡介信息她混。

計(jì)劃是用python發(fā)起網(wǎng)絡(luò)請求拳话,然后解析數(shù)據(jù)歹茶,并將數(shù)據(jù)放到mysql數(shù)據(jù)庫中夕玩。

如果是簡單的弄個(gè)2kw的for循環(huán)等著依次執(zhí)行你弦,那平均2s一次的請求,會(huì)將時(shí)間拉長到你懷疑人生燎孟。

串行執(zhí)行的路走不通禽作,那就必然會(huì)想到并發(fā)執(zhí)行。在別的程序語言中揩页,多線程是一種很好的并發(fā)策略旷偿。然而,Python由于有全鎖局的存在(同一時(shí)間只能有一個(gè)線程執(zhí)行)爆侣,并不能利用多核優(yōu)勢萍程。所以,如果程序的多線程進(jìn)程是CPU密集型的累提,那多線程并不能帶來效率上的提升尘喝,相反還可能會(huì)因?yàn)榫€程的頻繁切換,導(dǎo)致效率下降斋陪;如果是IO密集型,多線程進(jìn)程可以利用IO阻塞等待時(shí)的空閑時(shí)間執(zhí)行其他線程置吓,提升效率无虚。

我想要的是,同一瞬時(shí)時(shí)間內(nèi)衍锚,盡可能的多開網(wǎng)絡(luò)請求友题,這樣就能提高單位時(shí)間內(nèi),從豆瓣接口內(nèi)爬取數(shù)據(jù)的效率戴质。多線程由于要等待網(wǎng)絡(luò)請求返回的時(shí)間度宦,在這里并不適用。所以我這里采用的是多進(jìn)程的思路告匠。

其實(shí)在python網(wǎng)絡(luò)并發(fā)過程中戈抄,有多協(xié)程的方法來提示效率。但協(xié)程是一種用戶態(tài)的輕量級線程后专。它無法利用多核資源:協(xié)程的本質(zhì)是個(gè)單線程,它不能同時(shí)將 單個(gè)CPU 的多個(gè)核用上,協(xié)程需要和進(jìn)程配合才能運(yùn)行在多CPU上.其效率相對來講划鸽,還是低于多進(jìn)程的方式。

我的思路是戚哎,同時(shí)開200個(gè)到400個(gè)進(jìn)程裸诽,將2kw圖書分配給這幾百個(gè)進(jìn)程。幾百個(gè)進(jìn)程同時(shí)執(zhí)行型凳,自然效率上會(huì)高很多丈冬。當(dāng)然,我自己的mac的CPU也就8核心的配置甘畅。多進(jìn)程也就是能把這8個(gè)核心的利用率提高一點(diǎn)點(diǎn)而已埂蕊。但是实夹,由于我的每一次請求數(shù)據(jù),大多耗時(shí)在網(wǎng)絡(luò)請求中粒梦,所以亮航,這樣使用多進(jìn)程,反而能在某種意義上匀们,提高了相應(yīng)的效率缴淋。

我單次網(wǎng)絡(luò)請求,加上代理ip泄朴,讀取&解析重抖,以及存入數(shù)據(jù)庫,總共耗時(shí)在3s左右祖灰。我開到了200個(gè)進(jìn)程钟沛,總速度大概在5w條/小時(shí)(這里是指有效記錄,會(huì)有一定概率的網(wǎng)絡(luò)請求異常以及空id的數(shù)據(jù)局扶,這部分大概是有效數(shù)據(jù)的三分之一恨统,總的并發(fā)數(shù)據(jù)量應(yīng)該在6.6w條/小時(shí))。大約每秒13條(事先沒有統(tǒng)計(jì)每秒發(fā)出的請求次數(shù)三妈,事實(shí)上我也沒有地方放此數(shù)據(jù))畜埋。

而于之前相比,我開20個(gè)進(jìn)程畴蒲,平均一小時(shí)7k條有效記錄悠鞍,(大概是每秒1.9條)已經(jīng)快上好多好多了。

下面是代碼:

#!/usr/bin/env python
# -*- coding:utf-8 -*-
import Crawler #我的單次爬取程序
import multiprocessing
import SqlOperation #我的數(shù)據(jù)庫操作類
import time

#我的每個(gè)進(jìn)程內(nèi)模燥,執(zhí)行id的順序
def worker(num):
    thread_index = SqlOperation.get_thread_index_id(num)
    #查詢當(dāng)前第 num 個(gè)進(jìn)程已經(jīng)爬取到最大 id  
    process_index = num*50000+1000000
    # print str(process_index) + ':' + str(thread_index)
    if process_index < thread_index:
        process_index = thread_index        
    #獲取當(dāng)前第 num 個(gè)進(jìn)程咖祭,應(yīng)該開始爬去數(shù)據(jù)的起始 id  
    Crawler.start_crawler(process_index, num)
    #開始爬取數(shù)據(jù),進(jìn)程為第 num 個(gè)蔫骂,起始id為 process_index

done_id_arr = [1, 2, 3, 4, 6, 7, 8, 9, 10, 12, 13, 14, 15, 17, 18, 19, 20, 23, 25, 26, 27, 28, 30, 32, 34, 36, 38, 39, 40, 43, 44, 52, 64, 70, 74, 84, 86, 87, 98, 102, 116, 119]
#已完成爬取數(shù)據(jù)的進(jìn)程id數(shù)組么翰,從數(shù)據(jù)里查到的,但因?yàn)槊看螁?dòng)程序纠吴,此處只執(zhí)行一次硬鞍,就直接硬編碼,沒有寫自動(dòng)獲取的方法

if __name__ == '__main__':
    jobs = []
    Crawler.ips = Crawler.get_ip_arr()
    #獲取代理ip組
    # print Crawler.ips
    # Crawler.test_ip(1000007)
    for i in range(11, 200):
        if i in done_id_arr:
            # 如果 第 i 個(gè)進(jìn)程的數(shù)據(jù)已經(jīng)爬完了戴已,即 i 在 done_id_arr中固该,
            # 說明此進(jìn)程沒有開的必要了,可節(jié)省相應(yīng)資源
            pass
        else:
            # 單開進(jìn)程糖儡,爬取第 i 個(gè)id組的數(shù)據(jù)
            p = multiprocessing.Process(target=worker, args=(i,))
            jobs.append(p)
            p.start()

執(zhí)行效率前面已經(jīng)說過了伐坏,有效數(shù)據(jù)大概在5w條/小時(shí)。這段程序大概開了四天多握联,最后的數(shù)據(jù)總量是 5645271條有效記錄桦沉。(當(dāng)然數(shù)據(jù)并不是一次就爬成的每瞒,加上之前的調(diào)試異常捕獲,調(diào)試數(shù)據(jù)庫纯露,調(diào)試代理ip剿骨,這些零零碎碎有十幾w的數(shù)據(jù)量,然后程序穩(wěn)定后埠褪,沒有動(dòng)自己跑浓利,連續(xù)不間斷的運(yùn)行時(shí)間大概有三天多)〕伲總的來說贷掖,還是有些成就感的。

屏幕快照 2017-11-08 下午2.03.57.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末渴语,一起剝皮案震驚了整個(gè)濱河市苹威,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌驾凶,老刑警劉巖牙甫,帶你破解...
    沈念sama閱讀 217,734評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異狭郑,居然都是意外死亡腹暖,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,931評論 3 394
  • 文/潘曉璐 我一進(jìn)店門翰萨,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人糕殉,你說我怎么就攤上這事亩鬼。” “怎么了阿蝶?”我有些...
    開封第一講書人閱讀 164,133評論 0 354
  • 文/不壞的土叔 我叫張陵雳锋,是天一觀的道長。 經(jīng)常有香客問我羡洁,道長玷过,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,532評論 1 293
  • 正文 為了忘掉前任筑煮,我火速辦了婚禮辛蚊,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘真仲。我一直安慰自己袋马,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,585評論 6 392
  • 文/花漫 我一把揭開白布秸应。 她就那樣靜靜地躺著虑凛,像睡著了一般碑宴。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上桑谍,一...
    開封第一講書人閱讀 51,462評論 1 302
  • 那天延柠,我揣著相機(jī)與錄音,去河邊找鬼锣披。 笑死贞间,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的盈罐。 我是一名探鬼主播榜跌,決...
    沈念sama閱讀 40,262評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼盅粪!你這毒婦竟也來了钓葫?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,153評論 0 276
  • 序言:老撾萬榮一對情侶失蹤票顾,失蹤者是張志新(化名)和其女友劉穎础浮,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體奠骄,經(jīng)...
    沈念sama閱讀 45,587評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡豆同,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,792評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了含鳞。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片影锈。...
    茶點(diǎn)故事閱讀 39,919評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖蝉绷,靈堂內(nèi)的尸體忽然破棺而出鸭廷,到底是詐尸還是另有隱情,我是刑警寧澤熔吗,帶...
    沈念sama閱讀 35,635評論 5 345
  • 正文 年R本政府宣布辆床,位于F島的核電站,受9級特大地震影響桅狠,放射性物質(zhì)發(fā)生泄漏讼载。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,237評論 3 329
  • 文/蒙蒙 一中跌、第九天 我趴在偏房一處隱蔽的房頂上張望咨堤。 院中可真熱鬧,春花似錦晒他、人聲如沸吱型。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,855評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽津滞。三九已至铝侵,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間触徐,已是汗流浹背咪鲜。 一陣腳步聲響...
    開封第一講書人閱讀 32,983評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留撞鹉,地道東北人疟丙。 一個(gè)月前我還...
    沈念sama閱讀 48,048評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像鸟雏,于是被迫代替她去往敵國和親享郊。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,864評論 2 354

推薦閱讀更多精彩內(nèi)容