那些年我們寫過的爬蟲
從寫nodejs的第一個爬蟲開始陸陸續續寫了好幾個爬蟲,從爬拉勾網上的職位信息到爬豆瓣上的租房帖子,再到去爬知乎上的妹子照片什么的,爬蟲為我打開了一扇又一扇新世界的大門。除了漲了很多姿勢之外,與網管斗智斗勇也是一個比較有意思的事情。雖然很多東西都是淺嘗輒止,但萬事都有個由淺入深的過程嘛(天真臉~~)
一只爬蟲的模樣
爬蟲?應該是長這樣的吧:
其實,沒有那么萌啦。
所謂爬蟲,就是把目標網站的信息收集起來的一種工具。基本流程跟人訪問網站是一樣的,打開鏈接>>獲取信息>>打開鏈接……這個循環用編程實現,就是爬蟲了。專業一點的說法就是,發起請求>>解析響應數據。普通網站訪問的時候,返回值是一個html文本,這時候需要解析html文本獲取所需信息,比如可以用cheerio這種類jQuery的操作dom的方式去解析html文本;而使用ajax動態生成內容的網站,可以直接去請求相應的接口,從而直接獲得數據。爬蟲爬的,就是這些url或者接口,慢慢地爬呀爬,直到世界盡頭~~~
爬蟲與網管
獲取信息是爬蟲的核心,但是最有技術含量的卻不在于此。爬蟲路上的第一個大敵,就是網管了。由于太多人利用爬蟲去剽竊別人的成果,所以爬蟲在生產內容的網站都不受待見。就想農民伯伯辛辛苦苦種大的大白菜,自然是不希望被豬拱了。網管叔叔們通常會根據爬蟲的特征來辨別爬蟲,大體上有這么幾個方面:
1) 檢查請求頭。一些很初級的爬蟲只是單純得發請求,連最基本的user agent之類的請求頭都沒有,看見這種請求,不用說也知道是爬蟲了。除了user agent,Referer也是一個通常被用來檢查爬蟲的字段。
2) 判斷用戶行為。很多網站在未登錄狀態的時候會經常返回登錄頁面讓用戶登錄,用戶登錄之后通過統計用戶訪問行為就可以判斷出用戶是不是人,比如在短時間內進行了大量的訪問,這顯然不是人力所能做到的了。
3) 判斷IP的訪問量。如果一個ip在短時間內進行了大量的訪問,顯然,這也不是人干的事。尤其是同一IP出現高并發的情況,這種會加重服務器負荷甚至搞垮服務器的爬蟲,絕對是網管的眼中釘肉中刺。
4) 根據瀏覽器行為判斷。瀏覽器在打開網頁的時候會自動將網頁中的圖片、css、js等資源加載下來,但是爬蟲卻只是獲取了網頁的文本,并不會自動加載相關的資源,通過這一特征也能很好區分爬蟲。比如說在網頁中加入一個會自動發請求的js文件,服務器端如果接收不到這個請求就可以認為是爬蟲在訪問了。但是這招對利用瀏覽器內核寫成的爬蟲或者是高級爬蟲來說就不管用了。
通常網管們比較常用的是就是前3種方式的組合,第4點需要開發改動前后端代碼,這對身為運維的網管叔叔們來說,給開發提需求可不容易啊。 但如果在開發階段就已經考慮到防火防盜防爬蟲的話,那就會對接口進行加密或是校驗了。雖然說前端代碼都是裸奔的,但是假如有意去混淆js的話,想要破解出加密算法也不是那么簡單的。校驗就跟普通的應付csrf攻擊的做法也相差無幾,在頁面中嵌入服務器端返回的隨機數,接口調用時校驗這個隨機數即可。
智斗網管
但是俗話說,你有張良計,我有過墻梯。 即使網管叔叔好像做了很多反爬蟲的工作,但是人民群眾的智商是無限的。
什么,你要檢查請求頭?你要什么樣的header,我這里都有!根據IP判斷?花幾十塊買了一堆高匿代理服務器呢。判斷用戶行為?呵呵,我有一堆小號呀~
具體來說:
1)偽造header。這實在太簡單了,隨便打開一個瀏覽器F12,把請求的header都復制一遍,不要太完整哦。
2)多用戶爬蟲。提前注冊好一堆小號,登錄之后F12分析cookie,找出賬號相關的cookie,將cookie按賬號存到數組中不斷輪換即可。在有csrf防御策略的網站上,還需要分析token的來源,在請求的時候帶上預埋的token即可。例如知乎就在網頁中預埋了一個_xsrf,在請求的時候要帶上這個自定義頭才可以獲得請求的權限。
3)多IP爬蟲。這個就稍微復雜一些,主要是高匿代理IP比較難搞到手。網上的免費代理不少,能用的不多。要么掏錢,要么就做一個爬蟲來爬取可用的代理服務器吧。
4)接口參數解密。這種情況下,參數被加密成一個密碼字符串,服務器端通過解密算法來還原參數,也就是說每次請求的參數都是不同的。這里的關鍵在于找到加密算法和鑰匙,而前端的js通常也會被混淆加密,所以這種情況是最復雜的。目前我還沒遇到這種情況,所以就不多說了。
一只爬蟲的修養
如果一只爬蟲動不動就幾百個并發,這吃相就難看了。所以我們通常會控制一下并發和爬取間隔,盡量不干擾服務器的正常運轉。這就是一只爬蟲的修養了。
流程控制方面你可以使用集成的async庫,也可以手動管理流程,時刻考慮異常情況就可以寫出最貼合你要求的控制流程了。現在es7從語言上加入了async、await語法糖,手動編碼的代碼也非常優雅了。
附錄
1)知乎圖片爬蟲 :這個是受不了一個曾經很火的帖子誘惑而寫的,這個爬蟲可以爬取任一話題下所有回答中的圖片并下載到本地目錄下,你們感受下:
如你所見,大部分妹子長得并沒有很好看。。。。(心酸淚奔)
但是!質量不行,我還有數量呀:
其實并不是很有動力寫這種爬蟲,不過看到答案中一個家伙寫了一個爬蟲,但是卻只能爬第一頁。。。這是什么感覺?就好像是拉鏈還沒拉下來,片子卻播完了!忍不住,就寫了一個可以下載所有答案的爬蟲,然后還用數據庫和json兩種方式儲存了一下數據。剛看的數據庫,學以致用!源碼和相應說明均在文后有給出。
2)豆瓣小組爬蟲: 這個是我在豆瓣上找房子的時候寫的簡單爬蟲,這個爬蟲的吃相比較難看!。!因為沒有控制并發。。。因為租房帖子的更新非常快,所以就爬取了最新的10頁(250條)帖子,主要邏輯就是對標題進行關鍵詞的篩選,將符合條件的帖子輸出到網頁中(這里用json文件來示范了)。結果大概長這個樣子:
3)拉勾網爬蟲: 這個是在換工作的時候寫的一個很簡單的爬蟲,主要是想統計一下不同崗位的需求情況、公司分布,本來還想要結合地圖做分布圖、熱力圖什么的,最后也是不了了之。只是簡單地用echart做了一個圖表就完事了,太簡陋!拉鉤是ajax接口返回數據的,而且沒有加密,實在是太好爬了!反爬蟲的策略是基于IP的,單個ip訪問頻繁就會被封哦,要注意!
來自:http://www.cnblogs.com/qieguo/p/5859927.html