前情提要:Python爬蟲初體驗(2):多線程的應(yīng)用及爬取中的實際問題
從來沒想過,寫一個功能較為完備的爬蟲代碼,要花好幾天的時間……
這次算是增長了許多編程經(jīng)驗。
好的廢話不多說,進入正題
上次的代碼中,由于部分XKCD漫畫有特殊格式(還有 404 彩蛋),而我的代碼中 try-except 結(jié)構(gòu)只處理了連接超時的問題,沒有對漫畫本身的格式變化進行處理,導(dǎo)致線程意外中斷。雖然最后寫了重試下載,但是它和上面的一樣,有個致命問題:如果是漫畫格式的問題,它會陷入無限死循環(huán)。
所以這次對以上問題進行了規(guī)避式處理:將所有步驟寫進 try 里面。并且,代碼仍然采用重試機制,如果重試仍然有錯誤出現(xiàn),那么記錄這個漫畫編號,程序運行結(jié)束后手動下載這些特殊的漫畫。
……
那么這次的新知識,就是所謂的線程鎖和線程同步。
線程鎖:使用 mutex = threading.Lock() 將線程鎖的變量賦值給 mutex,之后在?mutex 中分別用 acquire() 和 release() 方法來上鎖/解鎖。這樣做是為了避免幾個線程同時訪問變量造成混亂。
調(diào)用 acquire() 后,接下來代碼中的變量將只能由當(dāng)前線程訪問,其余線程會被阻塞,直到使用 release(),其余線程才能訪問這些變量。例如,我要對全局變量 count 進行讀取和 +1 操作,不上鎖時,可能第 1,2 個線程在 +1 時,第 3,4 個線程在讀取,就會造成數(shù)據(jù)不統(tǒng)一的問題。所以這種情況一定要上鎖確保訪問安全。
線程同步:如果我們希望子線程全部結(jié)束后,能繼續(xù)執(zhí)行主線程,那么需要用到 join() 方法。
def func_1():
# do something_1
thread_list = []
for i in range(5):
thread_list.append(threading.Thread(target=func_1))
thread_list[i].start()
for i in range(5):
thread_list[i].join()
# do something_2
對于線程 t,調(diào)用 t.join() 使得主線程在這個線程執(zhí)行完之后才繼續(xù)進行下一步操作。
(知識參考了liudemeng:Python中線程與互斥鎖這篇文章)
然后!
還是一樣的方法去搞……
哎。幾天下來都沒弄好,不知道這次又會怎樣……
……
果然還是出問題了qwq
前兩個線程倒是下載完了,后面三個線程居然在中途全部卡死,這是什么意思???
最后一直卡在 874 號漫畫上……然后就沒動靜了……
……
經(jīng)過我一番分析,原來有一行下載的代碼寫的是
picres = requests.get("http:" + picurl)
第一次寫爬蟲的時候就提到了:不能直接使用 requests.get(),以防超時卡死!!!
這里疏忽了沒有改,導(dǎo)致后三個線程下載中途均出現(xiàn)了 Read Timeout(讀取超時)然后卡死的現(xiàn)象
然后一直卡在那里,程序就這樣 GG 咯 (0.0)\\
……
哎!第四次了。這次應(yīng)該會成功吧。
為了加快速度,把線程數(shù)從 5 改成了 6;為了得到不能批量下載的漫畫編號,最后記錄了一個 log 文件,記下了編號和總耗時。
……
……
Nice,這次的程序終于沒問題了!并且?guī)讉€特殊漫畫的編號也保存了下來
最后看到,耗時接近 1 小時;2173張/h 的速度,相比于原來 300張/h (50張漫畫 10分鐘)的速度要提高了不少。一個是因為啟用了多線程,另一個是讀取超時的時間從原來的 10s 變?yōu)榱?4s。
簡單總結(jié)一下。
這次的爬蟲體驗收獲還是很大,不僅是學(xué)到的知識得到了運用,同時發(fā)現(xiàn)了許多新的問題,特別是之前沒有考慮過的問題:例如讀取超時的處理,錯誤類型的判斷,錯誤的處理,意外發(fā)生時的應(yīng)對策略,等等。
于是,耗時 5?天的這個爬蟲終于走到了一個新的里程碑處。開心!
下一步,可以再深挖一下多線程的應(yīng)用,也可以開始準(zhǔn)備圖像處理的練習(xí)了。事情還是很多的。
……
最近生活上還需要多多調(diào)整心態(tài)。可以想想那些比我強的同學(xué)是怎么做的。
……
今天又拖到了 11 點過,說好的 11 點睡覺呢!!
不說了趕緊滾去睡覺~
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯(lián)系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
