文/諸葛io CEO 孔淼
在《一看就明白的爬蟲入門講解:基礎理論篇(上篇)》分享了爬蟲入門中的"我們的目的是什麼"、"內容從何而來"、"瞭解網路請求"這三部分的內容,這一篇我繼續分享以下內容:
- 一些常見的限制方式
- 嘗試解決問題的思路
- 效率問題的取捨
一、一些常見的限制方式
上述都是講的都是一些的基礎的知識,現在我就列一些比較常見的限制方式,如何突破這些限制這些抓取資料:
Basic Auth
一般會有使用者授權的限制,會在headers的Autheration欄位裡要求加入;
Referer
通常是在訪問連結時,必須要帶上Referer欄位,伺服器會進行驗證,例如抓取京東的評論;
User-Agent
會要求真是的裝置,如果不加會用程式語言包裡自有User-Agent,可以被辨別出來;
Cookie
一般在使用者登入或者某些操作後,服務端會在返回包中包含Cookie資訊要求瀏覽器設定Cookie,沒有Cookie會很容易被辨別出來是偽造請求;
也有本地透過JS,根據服務端返回的某個資訊進行處理生成的加密資訊,設定在Cookie裡面;
Gzip
請求headers裡面帶了gzip,返回有時候會是gzip壓縮,需要解壓;
Java加密操作
一般都是在請求的資料包內容裡面會包含一些被java進行加密限制的資訊,例如新浪微博會進行SHA1和RSA加密,之前是兩次SHA1加密,然後傳送的密碼和使用者名稱都會被加密;
其他欄位
因為http的headers可以自定義地段,所以第三方可能會加入了一些自定義的欄位名稱或者欄位值,這也是需要注意的。
真實的請求過程中,其實不止上面某一種限制,可能是幾種限制組合在一次,比如如果是類似RSA加密的話,可能先請求伺服器得到Cookie,然後再帶著Cookie去請求伺服器拿到公鑰,然後再用js進行加密,再傳送資料到伺服器。所以弄清楚這其中的原理,並且耐心分析很重要。
二、嘗試解決問題的思路
首先大的地方,加入我們想抓取某個資料來源,我們要知道大概有哪些路徑可以獲取到資料來源,基本上無外乎三種:
PC端網站;
針對移動裝置響應式設計的網站(也就是很多人說的H5, 雖然不一定是H5);
移動App;
原則是能抓移動App的,最好抓移動App,如果有針對移動裝置最佳化的網站,就抓針對移動裝置最佳化的網站,最後考慮PC網站。
因為移動App基本都是API很簡單,而移動裝置訪問最佳化的網站一般來講都是結構簡單清晰的HTML,而PC網站自然是最複雜的了;
針對PC端網站和移動網站的做法一樣,分析思路可以一起講,移動App單獨分析。
1.網站型別的分析首先是網站類的,使用的工具就是Chrome,建議用Chrome的隱身模式,分析時不用頻繁清楚cookie,直接關閉視窗就可以了。
具體操作步驟如下:
輸入網址後,先不要回車確認,右鍵選擇審查元素,然後點選網路,記得要勾上preserve log選項,因為如果出現上面提到過的重定向跳轉,之前的請求全部都會被清掉,影響分析,尤其是重定向時還加上了Cookie;
接下來觀察網路請求列表,資原始檔,例如css,圖片基本都可以忽略,第一個請求肯定就是該連結的內容本身,所以檢視原始碼,確認頁面上需要抓取的內容是不是 在HTML標籤裡面,很簡單的方法,找到自己要找的內容,看到父節點,然後再看原始碼裡面該父節點裡面有沒有內容,如果沒有,那麼一定是非同步請求,如果是 非非同步請求,直接抓該連結就可以了。
分析非同步請求,按照網路列表,略過資原始檔,然後點選各個請求,觀察是否在返回時包含想要的內容,有幾個方法:
內容比較有特點,例如人的屬性資訊,物品的價格,或者微博列表等內容,直接觀察可以判斷是不是該非同步請求;
知道非同步載入的內容節點或者父節點的class或者id的名稱,找到js程式碼,閱讀程式碼得到非同步請求;
確認非同步請求之後,就是要分析非同步請求了,簡單的,直接請求非同步請求,能得到資料,但是有時候非同步請求會有限制,所以現在分析限制從何而來。
針對分析對請求的限制,思路是逆序方法:
先 找到最後一個得到內容的請求,然後觀察headers,先看post資料或者url的某個引數是不是都是已知資料,或者有意義資料,如果發現不確定的先帶 上,只是更改某個關鍵欄位,例如page,count看結果是不是會正常,如果不正常,比如多了個token,或者某個欄位明顯被加密,例如使用者名稱密碼, 那麼接下來就要看JS的程式碼,看到底是哪個函式進行了加密,一般會是原生js程式碼加密,那麼看到程式碼,直接加密就行,如果是類似RSA加密,那麼就要看公 鑰是從何而來,如果是請求得到的,那麼就要往上分析請求,另外如果是發現請求headers裡面有陌生欄位,或者有Cookie也要往上看請 求,Cookie在哪一步設定的;
接下來找到剛剛那個請求未知來源的資訊,例如Cookie或者某個加密需要的公鑰等等,看看上面某個請求是不是已經包含,依次類推。
2.App的分析
然後是App類的,使用的工具是Charles,手機和電腦在一個區域網內,先用Charles配置好埠,然後手機設定代理,ip為電腦的ip,埠為設定的埠,然後如果手機上請求網路內容時,Charles會顯示相應地請求,那麼就ok了,分析的大體邏輯基本一致,限制會相對少很多,但是也有幾種情況需要注意:
加密,App有時候也有一些加密的欄位,這個時候,一般來講都會進行反編譯進行分析,找到對應的程式碼片段,逆推出加密方法;
gzip壓縮或者編碼,編碼的辨別度較高,有時候資料被gzip壓縮了,不過Charles都是有自動解密的;
https證照,有的https請求會驗證證照,Charles提供了證照,可以在官網找到,手機訪問,然後信任新增就可以。
三、效率問題的取捨
一般來講在抓取大量資料,例如全網抓取京東的評論,微博所有人的資訊,微博資訊,關注關係等等,這種上十億到百億次設定千億次的請求必須考慮效率,否者一天只有86400秒,那麼一秒鐘要抓100次,一天也才864w次請求,也需要100多天才能到達十億級別的請求量。
涉及到大規模的抓取,一定要有良好的爬蟲設計,一般很多開源的爬蟲框架也都是有限制的,因為中間涉及到很多其他的問題,例如資料結構,重複抓取過濾的問題, 當然最重要的是要把頻寬利用滿,所以分散式抓取很重要,接下來我會有一篇專門講分散式的爬蟲設計,分散式最重要的就是中間訊息通訊,如果想要抓的越多越 快,那麼對中間的訊息系統的吞吐量要求也越高。
但是對於一些不太大規模的抓取就沒要用分散式的一套,比較消耗時間,基本只要保證單機器的頻寬能夠利用滿就沒問題,所以做好併發就可以,另外對於資料結構也 要有一定的控制,很多人寫程式,記憶體越寫越大,抓取越來越慢,可能存在的原因就包括,一個是用了記憶體存一些資料沒有進行釋放,第二個可能有一些hashset的判斷,最後判斷的效率越來越低,比如用bloomfilter替換就會最佳化很多。