外行學(xué) Python 爬蟲 第七篇 開啟多線程加快爬取速度

經(jīng)過上一篇文章外行學(xué) Python 爬蟲 第六篇 動態(tài)翻頁我們實現(xiàn)了網(wǎng)頁的動態(tài)的分頁,此時我們可以爬取立創(chuàng)商城所有的原件信息了囚衔,經(jīng)過幾十個小時的不懈努力喜滨,一共獲取了 16萬+ 條數(shù)據(jù)鳄抒,但是軟件的效率實在是有點低了知允,看了下獲取 10 萬條數(shù)據(jù)的時間超過了 56 個小時撒蟀,平均每分鐘才獲取 30 條數(shù)據(jù)。


注:軟件運行的環(huán)境是搬瓦工的虛擬主機温鸽,CPU: 2x Intel Xeon , RAM: 1024 MB

軟件的運行效率不高保屯,那么時間都花費在什么上面了,爬蟲軟件本身并不是計算密集型軟件,時間大多數(shù)花費在與遠(yuǎn)程主機的通信上了姑尺,要想提高軟件的運行效率竟终,就要減少等待時間,此時你想到了什么切蟋?沒錯就是多線程衡楞,在非計算密集型應(yīng)用中,使用多線程可以最大程度的節(jié)省資源同時提高軟件的效率敦姻,關(guān)于線程的基本應(yīng)用可以參考前面的文章 python 之進程與線程

針對多線程的修改

使用多線程后歧杏,每個線程執(zhí)行的應(yīng)該是不同的任務(wù)镰惦,如果是相同的任務(wù)那就是兩個程序而不能說是多線程了。每個線程執(zhí)行不同的任務(wù)「即爬取不同的網(wǎng)頁」犬绒,需要線程間共享數(shù)據(jù)「在本程序中需要共享待爬隊列旺入、已獲取 url 的布隆濾波器等」。因此我們需要多當(dāng)前的軟件進行修改凯力,以使待爬隊列和布隆濾波器可以在多個線程之間共享數(shù)據(jù)茵瘾。

要想在多線程之間共享待爬隊列和布隆濾波器,需要將其從當(dāng)前的實例屬性修改為類屬性咐鹤,以使其可以通過類在多個線程中訪問該屬性拗秘。關(guān)于類屬性和實例屬性可以參考 Python 類和實例 這篇文章。

將待爬隊列和布隆濾波器設(shè)置為類屬性的代碼如下:

class Crawler:
    url_queue = Queue()
    bloomfilter = ScalableBloomFilter()
    ...

在使用的過程中通過類名來訪問類屬性的值祈惶,示例代碼如下:

    def __init__(self, url_count = 1000, url = None):
        if (Crawler.max_url_count < url_count):
            Crawler.max_url_count = url_count

        Crawler.url_queue.put(url)

在多線程中雕旨,當(dāng)前的類屬性有多個線程共享,任何一個類屬性都有可能被任何線程修改捧请,因此線程之間共享數(shù)據(jù)最大的危險在于多個線程同時修改一個數(shù)據(jù)凡涩,把數(shù)據(jù)給修改亂了。由于 Queue 是一個適用于多線程編程的先進先出的數(shù)據(jù)結(jié)構(gòu)疹蛉,可以在生產(chǎn)者和消費者線程之間安全的傳遞消息或數(shù)據(jù)活箕,因此我們無需對隊列進行操作,但是布隆濾波器是非線程安全的數(shù)據(jù)可款,此時我們就需要在修改布隆濾波器的地方加上線程鎖育韩,以保證在同一時刻只有一個線程能夠修改布隆濾波器的數(shù)據(jù),代碼如下:

    def url_in_bloomfilter(self, url):
        if url in Crawler.bloomfilter:
            return True
        return False
    def url_add_bloomfilter(self, url):
        Crawler.lock.acquire()
        Crawler.bloomfilter.add(url)
        Crawler.lock.release()

在所有需要判斷 url 是否已經(jīng)爬取過的地方調(diào)用 url_in_bloomfilter筑舅,當(dāng)需要向布隆濾波器中添加 url 時調(diào)用 url_add_bloomfilter 方法座慰,保證布隆濾波器的數(shù)據(jù)不會被錯誤修改。

對爬蟲類 Crawler 修改完成后翠拣,就是真正啟動多線程的時候版仔,在 main.py 文件中將代碼修改為如下內(nèi)容:

def main():
    with open('database.conf','r') as confFile:
        confStr = confFile.read()
    conf = json.JSONDecoder().decode(confStr)
    db.init_url(url=conf['mariadb_url'])

    crawler1 = Crawler(1000, url='https://www.szlcsc.com/catalog.html')
    crawler2 = Crawler(1000, url='https://www.szlcsc.com/catalog.html')
    thread_one = threading.Thread(target=crawler1.run)
    thread_two = threading.Thread(target=crawler2.run)
    thread_one.start()
    thread_two.start()
    thread_one.join()
    thread_two.join()

以上代碼中首先建立了對數(shù)據(jù)庫的連接,然后創(chuàng)建了兩個 Crawler 類的的實例,最后創(chuàng)建了兩個線程實例蛮粮,并啟動線程益缎。

修改后的執(zhí)行結(jié)果



本次軟件開啟了兩個線程同時運行,同樣獲取 10 萬條數(shù)據(jù)然想,一共花費了 29 個小時莺奔,平均每分鐘獲取了 57.5 條數(shù)據(jù),相比單線程效率提高了 191.7%变泄,總體來說效率提高還是非常明顯的令哟。


最終在花費 50 小時 30 分鐘,從立創(chuàng)商城上獲取十六萬五千條數(shù)據(jù)后妨蛹,程序執(zhí)行完成屏富。

從立創(chuàng)商城商品目錄頁面可知立創(chuàng)商城上共計有十六萬七千個元件。程序執(zhí)行完成后共計獲取十六萬五千條數(shù)據(jù)蛙卤,可以說完成了預(yù)期設(shè)計目標(biāo)狠半。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市颤难,隨后出現(xiàn)的幾起案子神年,更是在濱河造成了極大的恐慌,老刑警劉巖行嗤,帶你破解...
    沈念sama閱讀 211,743評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件已日,死亡現(xiàn)場離奇詭異,居然都是意外死亡栅屏,警方通過查閱死者的電腦和手機捂敌,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,296評論 3 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來既琴,“玉大人占婉,你說我怎么就攤上這事「Χ鳎” “怎么了逆济?”我有些...
    開封第一講書人閱讀 157,285評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長磺箕。 經(jīng)常有香客問我奖慌,道長,這世上最難降的妖魔是什么松靡? 我笑而不...
    開封第一講書人閱讀 56,485評論 1 283
  • 正文 為了忘掉前任简僧,我火速辦了婚禮,結(jié)果婚禮上雕欺,老公的妹妹穿的比我還像新娘岛马。我一直安慰自己棉姐,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 65,581評論 6 386
  • 文/花漫 我一把揭開白布啦逆。 她就那樣靜靜地躺著伞矩,像睡著了一般。 火紅的嫁衣襯著肌膚如雪夏志。 梳的紋絲不亂的頭發(fā)上乃坤,一...
    開封第一講書人閱讀 49,821評論 1 290
  • 那天,我揣著相機與錄音沟蔑,去河邊找鬼湿诊。 笑死,一個胖子當(dāng)著我的面吹牛瘦材,可吹牛的內(nèi)容都是我干的枫吧。 我是一名探鬼主播,決...
    沈念sama閱讀 38,960評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼宇色,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了颁湖?” 一聲冷哼從身側(cè)響起宣蠕,我...
    開封第一講書人閱讀 37,719評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎甥捺,沒想到半個月后抢蚀,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,186評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡镰禾,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,516評論 2 327
  • 正文 我和宋清朗相戀三年皿曲,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片吴侦。...
    茶點故事閱讀 38,650評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡屋休,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出备韧,到底是詐尸還是另有隱情劫樟,我是刑警寧澤,帶...
    沈念sama閱讀 34,329評論 4 330
  • 正文 年R本政府宣布织堂,位于F島的核電站叠艳,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏易阳。R本人自食惡果不足惜附较,卻給世界環(huán)境...
    茶點故事閱讀 39,936評論 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望潦俺。 院中可真熱鬧拒课,春花似錦徐勃、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,757評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至扎酷,卻和暖如春檐涝,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背法挨。 一陣腳步聲響...
    開封第一講書人閱讀 31,991評論 1 266
  • 我被黑心中介騙來泰國打工谁榜, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人凡纳。 一個月前我還...
    沈念sama閱讀 46,370評論 2 360
  • 正文 我出身青樓窃植,卻偏偏與公主長得像,于是被迫代替她去往敵國和親荐糜。 傳聞我的和親對象是個殘疾皇子巷怜,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,527評論 2 349

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

  • Swift1> Swift和OC的區(qū)別1.1> Swift沒有地址/指針的概念1.2> 泛型1.3> 類型嚴(yán)謹(jǐn) 對...
    cosWriter閱讀 11,092評論 1 32
  • 瑣事記 1.漁家·賣得鮮魚二百錢 [清代] 鄭燮 賣得鮮魚二百錢, 糴糧炊飯放歸船暴氏。 拔來濕葦燒難著延塑, 曬在垂楊古...
    Pheeb閱讀 222評論 0 0
  • 早上起了個大早,興致勃勃準(zhǔn)備去檢查身體了答渔。臨行前关带,先在家稱了下體重,哇塞沼撕,比昨天輕了近2斤宋雏,這真是個好兆頭哇。 還...
    宋相如閱讀 1,420評論 0 0
  • 有時候务豺,一個人情緒不好磨总,想找個人說說話,但是笼沥,你會發(fā)現(xiàn)舍败,其實大家都挺忙的,你也還真的挺閑的……慢慢的敬拓,不再去打擾邻薯,...
    西瓜_cbaa閱讀 174評論 0 0