那些年我們寫過的爬蟲

從寫nodejs的第一個爬蟲開始陸陸續續寫了好幾個爬蟲,從爬拉勾網上的職位信息到爬豆瓣上的租房帖子,再到去爬知乎上的妹子照片什麼的,爬蟲為我打開了一扇又一扇新世界的大門。除了漲了很多姿勢之外,與網管鬥智斗勇也是一個比較有意思的事情。雖然很多東西都是淺嘗輒止,但萬事都有個由淺入深的過程嘛(天真臉~~)。

一隻爬蟲的模樣

爬蟲?應該是長這樣的吧:

其實,並沒有那麼萌。

所謂爬蟲,就是把目標網站的信息收集起來的一種工具。基本流程跟人訪問網站是一樣的,打開鏈接>>獲取信息>>打開鏈接……這個循環用編程實現,就是爬蟲了。普通網站訪問的時候,返回值是一個html文本,這時候需要解析html文本獲取所需信息,比如可以用cheerio這種類jQuery的操作dom的方式去解析html文本;而使用ajax動態生成內容的網站,可以直接去請求相應的介面,從而直接獲得數據。爬蟲爬的,就是這些url或者介面,慢慢地爬呀爬,直到世界盡頭~~~

爬蟲與網管

獲取信息是爬蟲的核心,但是最有技術含量的卻不在於此。爬蟲路上的第一個大敵,就是網管了。由於太多人利用爬蟲去剽竊別人的成果,所以爬蟲在生產內容的網站都不受待見。就想農民伯伯辛辛苦苦種大的大白菜,自然是不希望被豬拱了。網管叔叔們通常會根據爬蟲的特徵來辨別爬蟲,大體上有這麼幾個方面:

  • 檢查請求頭。一些很初級的爬蟲只是單純得發請求,連最基本的user agent之類的請求頭都沒有,看見這種請求,不用說也知道是爬蟲了。除了user agent,Referer也是一個通常被用來檢查爬蟲的欄位。
  • 判斷用戶行為。很多網站在未登錄狀態的時候會經常返回登錄頁面讓用戶登錄,用戶登錄之後通過統計用戶訪問行為就可以判斷出用戶是不是人,比如在短時間內進行了大量的訪問,這顯然不是人力所能做到的了。
  • 判斷IP的訪問量。如果一個ip在短時間內進行了大量的訪問,顯然,這也不是人乾的事。尤其是同一IP出現高並發的情況,這種會加重伺服器負荷甚至搞垮伺服器的爬蟲,絕對是網管的眼中釘肉中刺。
  • 根據瀏覽器行為判斷。瀏覽器在打開網頁的時候會自動將網頁中的圖片、css、js等資源載入下來,但是爬蟲卻只是獲取了網頁的文本,並不會自動載入相關的資源,通過這一特徵也能很好區分爬蟲。比如說在網頁中加入一個會自動發請求的js文件,伺服器端如果接收不到這個請求就可以認為是爬蟲在訪問了。但是這招對利用瀏覽器內核寫成的爬蟲或者是高級爬蟲來說就不管用了。

通常網管們比較常用的是就是前3種方式的組合,第4點需要開發改動前後端代碼,這對身為運維的網管叔叔們來說,給開發提需求可不容易啊。但如果在開發階段就已經考慮到防火防盜防爬蟲的話,那就會對介面進行加密或是校驗了。雖然說前端代碼都是裸奔的,但是假如有意去混淆js的話,想要破解出加密演算法也不是那麼簡單的。校驗就跟普通的應付csrf攻擊的做法也相差無幾,在頁面中嵌入伺服器端返回的隨機數,介面調用時校驗這個隨機數即可。

智斗網管

但是俗話說,你有張良計,我有過牆梯。即使網管叔叔好像做了很多反爬蟲的工作,但是人民群眾的智商是無限的。

什麼,你要檢查請求頭?你要什麼樣的header,我這裡都有!根據IP判斷?花幾十塊買了一堆高匿代理伺服器呢。判斷用戶行為?呵呵,我有一堆小號呀~

具體來說:

  • 偽造header。這實在太簡單了,隨便打開一個瀏覽器F12,把請求的header都複製一遍,不要太完整哦。
  • 多用戶爬蟲。提前註冊好一堆小號,登錄之後F12分析cookie,找出賬號相關的cookie,將cookie按賬號存到數組中不斷輪換即可。在有csrf防禦策略的網站上,還需要分析token的來源,在請求的時候帶上預埋的token即可。例如知乎就在網頁中預埋了一個_xsrf,在請求的時候要帶上這個自定義頭才可以獲得請求的許可權。
  • 多IP爬蟲。這個就稍微複雜一些,主要是高匿代理IP比較難搞到手。網上的免費代理不少,能用的不多。要麼掏錢,要麼就做一個爬蟲來爬取可用的代理伺服器吧。
  • 介面參數解密。這種情況下,參數被加密成一個密碼字元串,伺服器端通過解密演算法來還原參數,也就是說每次請求的參數都是不同的。這裡的關鍵在於找到加密演算法和鑰匙,而前端的js通常也會被混淆加密,所以這種情況是最複雜的。目前我還沒遇到這種情況,所以就不多說了。

一隻爬蟲的修養

如果一隻爬蟲動不動就幾百個並發,這吃相就難看了。所以我們通常會控制一下並發和爬取間隔,盡量不干擾伺服器的正常運轉。這就是一隻爬蟲的修養了。

流程式控制制方面你可以使用集成的async庫,也可以手動管理流程,時刻考慮異常情況就可以寫出最貼合你要求的控制流程了。現在es7從語言上加入了async、await語法糖,手動編碼的代碼也非常優雅了。

附錄

1)知乎圖片爬蟲

這個是受不了一個曾經很火的帖子誘惑而寫的(長得好看,但沒有男朋友是怎樣的體驗? ),這個爬蟲可以爬取任一話題下所有回答中的圖片並下載到本地目錄下,你們感受下:

如你所見,大部分妹子長得並沒有很好看。。。。但是!質量不行,我還有數量呀~~~

其實並不是很有動力寫這種爬蟲,不過看到答案中一個傢伙寫了一個爬蟲,但是卻只能爬第一頁。。。這是什麼感覺?就好像是拉鏈還沒拉下來,片子卻播完了!忍不住,就寫了一個可以下載所有答案的爬蟲,然後還用資料庫和json兩種方式儲存了一下數據。剛看的資料庫,學以致用!源碼和相應說明均在文後有給出。

2)豆瓣小組爬蟲

這個是我在豆瓣上找房子的時候寫的簡單爬蟲,這個爬蟲的吃相比較難看!。!因為沒有控制並發。。。因為租房帖子的更新非常快,所以就爬取了最新的10頁(250條)帖子,主要邏輯就是對標題進行關鍵詞的篩選,將符合條件的帖子輸出到網頁中(這裡用json文件來示範了)。結果大概長這個樣子:

3)拉勾網爬蟲

這個是在換工作的時候寫的一個很簡單的爬蟲,主要是想統計一下不同崗位的需求情況、公司分布,本來還想要結合地圖做分布圖、熱力圖什麼的,最後也是不了了之。只是簡單地用echart做了一個圖表就完事了,太簡陋!拉鉤是ajax介面返回數據的,而且沒有加密,實在是太好爬了!反爬蟲的策略是基於IP的,單個ip訪問頻繁就會被封哦,要注意!

PS:上面提到的爬蟲都在我的 github 上了,求star!

PPS:水平有限,代碼寫得比較粗糙,大家看看就好。。。


推薦閱讀:

從零開始寫Python爬蟲 --- 2.4 爬蟲實踐:代理的爬取和驗證
1000家公司五年的新浪微博採集

TAG:前端开发 | Nodejs | 爬虫 |