基於C#.NET的高端智能化網絡爬蟲(一)(反爬蟲哥必看)


前兩天朋友發給我了一篇文章,是攜程網反爬蟲組的技術經理寫的,大概講的是如何用他的超高智商通過(挑釁、憐憫、嘲諷、猥瑣)的方式來完美碾壓爬蟲開發者。今天我就先帶大家開發一個最簡單低端的爬蟲,突破攜程網超高智商的反爬蟲技術。

基於C#.NET的高端智能化網絡爬蟲(一)(反爬蟲哥必看)一、什么是爬蟲?

很多人說我們這些搞軟件的人,總喜歡把虛擬世界里的事物跟現實中的東西扯上關系。這點我真不否認,脫離了現實,我們偉大的創舉還有何意義?

“爬蟲”就是個例子,它對於我們開發人員而言,就是一段用來自動化采集網站數據的程序,結果跟現實中的蟲子扯上了關系。聽說是Google工程師提出來的,有質疑請聯系Larry Page。

基於C#.NET的高端智能化網絡爬蟲(一)(反爬蟲哥必看)

二、為什么需要開發爬蟲?

在這個數據橫流的互聯網時代,創業型公司如雨后春筍般的崛起,而大數據則可以幫他們迅速生產垂直化數據資料庫,提供給用戶使用。同時也讓老板們更容易看清未來的方向,制定發展策略。

這些大數據從哪兒能弄來呢?當然是從每個行業里的龍頭老大那里,做老大就是這么不容易。這圖里一部分是行業老大,有些我也沒聽說過,僅供參考:

基於C#.NET的高端智能化網絡爬蟲(一)(反爬蟲哥必看)

京東的價格、攜程的評論、亞馬遜的書、淘寶的信用、支付寶的訂單等。這些數據采集下來都很龐大,那究竟要這些數據有什么用呢?

  • 直接用於機器學習,分析用戶的興趣愛好和行為。

  • 獲取淘寶店鋪信用,直接用於新平台的用戶信用及身份驗證。

  • 獲取各個商城物品價格,為用戶提供市場場最低價。

  • 獲取酒店、圖書的(價格、簡介、評論),做垂直化平台的基礎數據庫。

基於C#.NET的高端智能化網絡爬蟲(一)(反爬蟲哥必看)

請原諒我用攜程舉例:設想我們要做一個高端的垂直化酒店平台,就拿北京來說,酒店接近10000家。要是全部都手動篩選、錄入這些信息,需要花費的人力、時間是極其恐怖的事。當然最難的應該是將人工搜集的數據標准化。怎樣才能把攜程網的酒店數據弄下來作為我們的基礎資料庫呢?

基於C#.NET的高端智能化網絡爬蟲(一)(反爬蟲哥必看)如果利用爬蟲技術,事情就有了很好解決方案。我們只需要編寫一個7*24小時運行的分布式爬蟲,自動化采集攜程網酒店數據,將國內外所有高端酒店(圖片、簡介、評分、用戶評論)全部抓取下來。再通過數據清洗,使內容標准化,讓這些數據成為我們的基礎資料庫就行了。看到這里內心是不是已經有點小激動?

三、開發爬蟲需要哪些技術?

由此可見,爬蟲技術已經成為我們每個開發人員最基本的技能,同時也是步入中高級開發不得不涉足的內容。為什么這么說呢?因為開發一個像樣的爬蟲,需要你了解的東西還真不少:

  • 學習任意一門開發語言:C#、NodeJs、Python、Java、C++。

  • 學習網頁前端腳本語言:Javascript、HTML、CSS。

  • 學習HTTP協議、正則表達式、數據庫、代理切換等相關知識。

  • 學習多線程並發抓取、任務調度、消息隊列、分布式爬蟲、圖像識別、模擬鍵鼠、NoSql。

基於C#.NET的高端智能化網絡爬蟲(一)(反爬蟲哥必看)

我仿佛看到了你一臉懵懂的表情!你真的沒有看錯,這些技術只是冰山一角。不過也不用擔心,初中級的爬蟲只需要學會前三點就可以了。要想開發出更高級的爬蟲,第四點是必須會的,同時為了追求極致的性能,還需要研究開源瀏覽器內核的相關項目,此處暫省略十萬字。

四、開發一個最簡單的爬蟲

下面我用C#.NET來寫一個非常簡單的爬蟲,我們的爬蟲之所以被封殺,肯定是因為對方找到了運行特征。因此只需要修改爬蟲的運行方式及特征,讓其操作與普通用戶的相似就可以了。一般爬蟲會有哪些特征和運行方式呢?

  • User-Agent:主要用來將我們的爬蟲偽裝成瀏覽器。

  • Cookie:主要用來保存爬蟲的登錄狀態。

  • 連接數:主要用來限制單台機器與服務端的連接數量。

  • 代理IP:主要用來偽裝請求地址,提高單機並發數量。

基於C#.NET的高端智能化網絡爬蟲(一)(反爬蟲哥必看)

通常來說,只要我們控制好了上面這4個東西,反爬蟲組那邊就較難找到我們的運行特征。還是拿攜程網來舉個例子,抓取他們的酒店數據,因為這些酒店信息本身屬於公開的內容,我們也不用於商業運作的目的,只是為了想見識一下他們反爬蟲經理所描述的猥瑣程度。

爬蟲工作的方式可以歸納為兩種:深度優先、廣度優先。

深度優先就是一個連接一個連接的向內爬,處理完成后再換一下一個連接,這種方式對於我們來說缺點很明顯。廣度優先就是一層一層的處理,非常適合利用多線程並發技術來高效處理,因此我們也用廣度優先的抓取方式。

首先我們用Visual Studio 2015創建一個控制台程序,定義一個簡單的SimpleCrawler類,里面只包含幾個簡單的事件:

基於C#.NET的高端智能化網絡爬蟲(一)(反爬蟲哥必看)

接着我們創建一個OnStart的事件對象:

基於C#.NET的高端智能化網絡爬蟲(一)(反爬蟲哥必看)

然后我們創建一個OnCompleted事件對象:

基於C#.NET的高端智能化網絡爬蟲(一)(反爬蟲哥必看)

最后我們再給它增加一個異步方法,通過User-Agent將爬蟲偽裝成了Chrome瀏覽器,代碼中每行我基本都加了注釋,學過.NET的朋友一看就明白,這里就不再重復解釋了:

基於C#.NET的高端智能化網絡爬蟲(一)(反爬蟲哥必看)

就如你所見,一個支持並發執行、可偽裝成Chrome瀏覽器、支持Cookie狀態保存、支持代理切換的簡單爬蟲就完成了。

為了加快爬蟲的速度,我又增加了Gzip解壓縮的功能,由於不太便於截圖,大家可以在源代碼里查看。現在我們用這個爬蟲抓取一下攜程網的酒店數據,看看效果如何。

攜程的酒店是按城市歸類的,從每個城市又鏈接到了下屬所有酒店,國內的城市大約有300多個,僅北京一個市的酒店數據就有9000多個,所以我要先抓下邊這頁面里的城市名稱及城市URL地址。

基於C#.NET的高端智能化網絡爬蟲(一)(反爬蟲哥必看)
在控制台里寫下爬蟲的抓取代碼:

基於C#.NET的高端智能化網絡爬蟲(一)(反爬蟲哥必看)
代碼都很簡單,眼睛犀利的朋友肯定看到了我在cityCrawler.Start()方法中使用了代理服務器,那個參數是可選的。經測試代理IP的速度還不錯,唯一不足的地方可能就是偶爾會出現連接超時,並發量少時並不需要開代理,這里只是為了測試的需要。來看看執行情況:

基於C#.NET的高端智能化網絡爬蟲(一)(反爬蟲哥必看)

由上圖可見,我們抓到了城市列表頁面的源代碼,但這並不是我們需要的數據,我們只想要規規矩矩的城市名稱和URL地址。

怎么辦呢?現在請出《正則表達式》—又簡潔又高效的神器,就是學起來比較費勁。我寫了個提取城市名稱及URL的正則表達式,直接提取源代碼中所有符合規則的數據:

<a[^>]+href=""*(?<href>/hotel/[^>\s]+)""\s*[^>]*>(?<text>(?!.*img).*?)</a>

在控制台程序中增加正則表達式過濾數據:

基於C#.NET的高端智能化網絡爬蟲(一)(反爬蟲哥必看)

再次運行爬蟲看看是否是我們需要的內容:

基於C#.NET的高端智能化網絡爬蟲(一)(反爬蟲哥必看)

運行狀態良好,成功拿到了城市名稱及城市URL地址,每個城市的URL中都包含了該城市的所有酒店,現在我們就根據城市URL抓取下屬的酒店列表,就拿最后一個城市來試試吧,我就不貼代碼了,同樣是先抓取源代碼,再使用正則表達式清洗數據:

"><a[^>]+href="*(?<href>/hotel/[^>\s]+)"\s*data-dopost[^>]*><span[^>]+>.*?</span>(?<text>.*?)</a>

請原諒我寫出這無比糟糕的正則表達式,看看它的運行結果:

基於C#.NET的高端智能化網絡爬蟲(一)(反爬蟲哥必看)

這里我發現一個有趣的地方,攜程網酒店列表頁中的連接,在點擊后會發生變化,會自動拼接上一個當天的日期,應該是用javascript寫的事件。我測試了下這些URL都能正確的連接到酒店介紹頁,如果這算是他們的反爬蟲手段,大家也可以在下一篇高級爬蟲知識里找到解決方案。

下面寫個多爬蟲並發抓取的例子,代碼也非常簡單,隨便寫兩個酒店URL地址,通過Parallel實現2個爬蟲的並發抓取。

基於C#.NET的高端智能化網絡爬蟲(一)(反爬蟲哥必看)

注意:單個IP並發數量不要設置太多,短時間內發送大量的爬蟲請求,很容易被反爬蟲組輕易的識別出來,因為普通用戶不可能在一秒內有那么多的請求和連接。

我們想要提高並發數量怎么辦呢?當然是使用代理IP和VPN,假設反爬蟲組限制單台IP連接數不能超過50,那我們增加一個代理IP就相當於可以多並發50個爬蟲出去,在帶寬足夠的情況下,10個有效的代理IP就可以讓爬蟲的性能提到一個新的高度,有沒有感覺到大數據已經在向你招手?

基於C#.NET的高端智能化網絡爬蟲(一)(反爬蟲哥必看)

有人說代理也可以被檢測出來,那是因為你還不太了解代理,代理服務器有很多種,而且真有不能被檢測出來的代理,比如自己搭建的 shadowsocks ,這塊內容較多,將在下一篇高級爬蟲的文章詳細講解,它的運行方式如下:

基於C#.NET的高端智能化網絡爬蟲(一)(反爬蟲哥必看)

現在大家就可以利用這個簡單的爬蟲自由發揮了,試試從酒店列表里抓取每個酒店的(評分、名稱、圖片),不要太難為自己,畢竟這只是一個最簡單的爬蟲,抓取都是同樣的原理,我就不再多說。

明天發下一篇(絕對干貨):基於C#.NET的高端智能化網絡爬蟲(二),主要講:如何開發瀏覽器內核的高級爬蟲、如何執行Javascript、如何操作Dom結構、如何搞定加密代理、如何實現分布式等功能。

然后我們通過這個高級爬蟲,實現對攜程網Ajax評論數據的抓取,這次我們就抓取他們的酒店評論。希望大家訂閱“全棧解密”,千萬不要錯過哦!

全部源代碼下載:https://github.com/coldicelion/Simple-Web-Crawler

驗證碼識別方案:用C#.NET開發通用的驗證碼識別組件


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM