當用python爬取大量網(wǎng)頁獲取想要的數(shù)據(jù)時,最重要的問題是爬蟲中斷問題,python這種腳本語言,一中斷
進程就會退出,怎么在中斷后繼續(xù)上次爬取的任務就至關重要了。這里就重點剖析這個中斷問題。
這里只是講講我個人的思路。
可能有的中斷原因
- ip被封,這種情況在爬取非靜態(tài)頁面的時候非常容易發(fā)生(評論頁)。
- 網(wǎng)絡連接超時。(有服務器端問題和本地網(wǎng)絡問題)
- 大量頁面的頁面解析規(guī)則不一樣,很容易我們的爬蟲解析html發(fā)生異常導致進程退出(數(shù)組下標越界)。
- 有些爬取來很順利,但是總有某條數(shù)據(jù)的處理規(guī)則和別的不一樣,導致程序出錯。
解決思路
第一個問題: 簡單點的用動態(tài)代理池就能解決,在爬取大量數(shù)據(jù)的時候,為了速度不受影響,建議使用一些緩
存的中間件將有效的代理 ip 緩存起來,并定時更新。這里推薦 github 這個倉庫
https://github.com/jhao104/proxy_pool , 它會做ip有效性驗證并將ip放入redis,不過實現(xiàn)過于復雜
了,還用到了db,個人覺得最好自己修改一下。困難點的就是它會使用別的請求來進行判斷當前的ip是否
是爬蟲,當我們過于聚焦我們的爬蟲請求而忽略了其他的請求時,可能就會被服務器判定為爬蟲,進而這個ip
會被列入黑名單,而且你換了ip一樣也會卡死在這里。這種方式呢,簡單點就用 selenium + chrome 一個一個
去爬,不過速度太慢了。還是自己去分析吧,也不會過復雜的。
第二個問題: 網(wǎng)絡連接超時是大概率會遇到的問題,有可能是在爬取的時候本地網(wǎng)絡波動,也有可能是爬
取的服務端對ip做了限制,在爬取到了一定量級的時候做一些延遲的操作,使得一些通用的http庫超時
(urllib)。不過如果是服務端動的手腳一般延遲不會太高,我們只需要人為的設置一個高一點的
timeout即可(30 秒),最好在爬取開始的時候就對我們要用的爬取庫進行一層封裝,通用起來才好改
動。
第三個問題: 在解析大量靜態(tài)頁面的時候,有些靜態(tài)頁面的解析規(guī)則不一樣,所以我們就必須得做好斷點
續(xù)爬的準備了(PS: 如果簡單的忽略錯誤可能會導致大量數(shù)據(jù)的丟失,這就不明智了)。那么在調試的過
程中斷點續(xù)爬有個解決方案,就是生產者和消費者分離,生產者就是產生待爬url的爬蟲,消費者就是爬取
最終數(shù)據(jù)的爬蟲。最終解析數(shù)據(jù)就是消費者爬蟲了。他們通過消息中間件連接,生產者往消息中間件發(fā)送待
爬取的目標信息,消費者從里面取就行了,還間接的實現(xiàn)了個分布式爬取功能。由于現(xiàn)在的消費中間件都有
ack機制,一個消費者爬取鏈接失敗會導致消息消費失敗,進而分配給其他消費者消費。所以消息丟失的
概率極低。不過這里還有個tips, 消費者的消費超時時間不能太長,會導致消息釋放不及時。還有要開啟
消息中間價的數(shù)據(jù)持久化功能,不然消息產生過多而消費不及時會撐爆機器內存。那樣就得不償失了。
第四個問題:這種情況只能try except catch住了,不好解決,如果單獨分析的話會耗費點時間。但在
大部分數(shù)據(jù)(99%)都正常的情況下就這條不正常拋棄就行了。主要有了第三個問題的解決方案再出現(xiàn)這
種偶爾中斷的問就方便多了。
希望能幫到各位。