基于C#.NET的高端智能化網(wǎng)絡(luò)爬蟲
本篇故事的起因是攜程旅游網(wǎng)的一位技術(shù)經(jīng)理,豪言壯舉的揚(yáng)言要通過他的超高智商,完美碾壓爬蟲開發(fā)人員,作為一個(gè)業(yè)余的爬蟲開發(fā)愛好者,這樣的言論我當(dāng)然不能置之不理。

有人評(píng)論我上一篇的簡(jiǎn)單爬蟲:代碼太過簡(jiǎn)單以至于弱爆了,真是被這群有文化的孩子給雷到了!不得不猜測(cè)你是不是攜程網(wǎng)的托兒,我還沒寫完你咋就知道弱爆了?看來不下點(diǎn)猛料你是得不到滿足?。?/p>

今天我們就來學(xué)習(xí)高級(jí)爬蟲的開發(fā),同時(shí)我們還要利用之前的簡(jiǎn)單爬蟲程序,來實(shí)現(xiàn)分布式爬蟲的Links Master部分,以提高分布式抓取的效率。
下邊的我們要講的內(nèi)容,涉及了眾多開源軟件。先別太緊張,越是高級(jí)的東西通常都封裝的越好,只要放開心態(tài)綜合運(yùn)用就行了,我先假設(shè)你對(duì)下邊這些工具都有過了解:
RabbitMQ:用于分布式消息傳遞。
Shadowsocks:用于代理加密。
PhantomJS:用于Web頁面渲染。
Selenium:用于Web自動(dòng)化控制。
一、什么是高級(jí)爬蟲?
我們長(zhǎng)談到的高級(jí)爬蟲,通常是說它具有瀏覽器的運(yùn)行特征,需要第三方的類庫(kù)或工具的支持,比如說以下這些常見的東東:
Webkit
WebBrowser
PhantomJS + Selenium
很多人都覺得,分布式爬蟲才能算是高級(jí)的爬蟲。這絕對(duì)是一種錯(cuò)誤的理解,分布式只是我們實(shí)現(xiàn)爬蟲架構(gòu)的一種手段,而并非是用來定義它高級(jí)的因素。

我們之所以稱它們?yōu)楦呒?jí)爬蟲組件,主要是因?yàn)樗麄儾坏梢灾苯幼ト【W(wǎng)頁源代碼,同時(shí)還能能渲染網(wǎng)站頁面的HTML、CSS、Javascript等內(nèi)容。
這樣的功能,對(duì)于開發(fā)爬蟲到底有什么好處呢?說起這好處那是有點(diǎn)謙虛了,絲毫不夸張的說:這玩意簡(jiǎn)直可以稱為“爬無敵”?。?!

我猜你還是這個(gè)表情,因?yàn)樗膹?qiáng)大機(jī)制,讓我們可以直接在網(wǎng)站頁面:執(zhí)行Javascript代碼、觸發(fā)各類鼠標(biāo)鍵盤事件、操縱頁面Dom結(jié)構(gòu)、利用XPath語法抓取數(shù)據(jù),幾乎可以做一切在瀏覽器上能做的事情。

很多網(wǎng)站都用Ajax動(dòng)態(tài)加載、翻頁,比如攜程網(wǎng)的評(píng)論數(shù)據(jù)。如果是用之前那個(gè)簡(jiǎn)單的爬蟲,是很難直接抓取到所有評(píng)論數(shù)據(jù)的,我們需要去分析那漫天的Javascript代碼尋找API數(shù)據(jù)接口,還要時(shí)刻提防對(duì)方增加數(shù)據(jù)陷阱或修改API接口地。
如果通過高級(jí)爬蟲,就可以完全無視這些問題,無論他們?nèi)绾渭用躂avascript代碼來隱藏API接口,最終的數(shù)據(jù)都必要呈現(xiàn)在網(wǎng)站頁面上的Dom結(jié)構(gòu)中,不然普通用戶也就沒法看到了。所以我們可以完全不分析API數(shù)據(jù)接口,直接從Dom中提取數(shù)據(jù),甚至都不需要寫那復(fù)雜的正則表達(dá)式。

二、如何開發(fā)一款高級(jí)爬蟲?
現(xiàn)在我們就來一步一步實(shí)現(xiàn)這個(gè)高級(jí)爬蟲,接下來就用目前潮到爆的兩個(gè)組件,來完成一個(gè)有基本功能的高級(jí)爬蟲,首先我們?nèi)ハ螺d開源組件:

PhantomJS:算是一個(gè)沒有UI界面的瀏覽器,主要用來實(shí)現(xiàn)頁面自動(dòng)化測(cè)試,我們則利用它的頁面解析功能,執(zhí)行網(wǎng)站內(nèi)容的抓取。下載解壓后將Bin文件夾中的phantomjs.exe文件復(fù)制到你爬蟲項(xiàng)目下的任意文件夾,我們只需要這個(gè)。
下載地址:http://phantomjs.org/download.html

Selenium:是一個(gè)自動(dòng)化測(cè)試工具,封裝了很多WebDriver用于跟瀏覽器內(nèi)核通訊,我用開發(fā)語言來調(diào)用它實(shí)現(xiàn)PhantomJS的自動(dòng)化操作。它的下載頁面里有很多東西,我們只需要Selenium Client,它支持了很多語言(C#、JAVA、Ruby、Python、NodeJS),按自己所學(xué)語言下載即可。
下載地址:http://docs.seleniumhq.org/download/
這里我我下載C#語言客戶端,將這4個(gè)DLL文件都添加到項(xiàng)目引用中,其他語言開發(fā)者請(qǐng)自行尋找方法,然后開始我們的編碼之旅。

老規(guī)矩,打開Visual Studio 2015 新建一個(gè)控制臺(tái)應(yīng)用程序,增加一個(gè)簡(jiǎn)單的StrongCrawler類,由于這兩個(gè)爬蟲類具有公共部分,本著DRY的原則,需要對(duì)部分代碼重構(gòu),我們先提取一個(gè)ICrawler接口:

然后我們用StrongCrawler類來實(shí)現(xiàn)這個(gè)接口:

接著我們來編寫它的異步爬蟲方法:

好了,這個(gè)高級(jí)爬蟲的基本功能就定義完成了,還是用攜程的酒店數(shù)據(jù)作為抓取的例子,我們測(cè)試一下抓?。ň频昝Q、地址、評(píng)分、價(jià)格、評(píng)論數(shù)量、評(píng)論當(dāng)前頁碼、評(píng)論下一頁碼、評(píng)論總頁數(shù)、每頁評(píng)論數(shù)量)等詳細(xì)數(shù)據(jù)試試。我們現(xiàn)在用控制臺(tái)程序來調(diào)用一下:

由上圖可知,等待酒店頁面加載完成后,我們通過XPath語法查找頁面元素,首先點(diǎn)擊了頁面上的“酒店評(píng)論”按鈕,再等待頁面的Dom結(jié)構(gòu)發(fā)生變化,也就是說等待Ajax加載成功,然后對(duì)需要的數(shù)據(jù)進(jìn)行抓取。看看代碼的執(zhí)行結(jié)果:

我們很輕松的抓取到了酒店的信息,以及酒店的第一頁全部評(píng)論數(shù)據(jù)。因?yàn)閿y程網(wǎng)的評(píng)論數(shù)據(jù)是通過Ajax翻頁的,因此要想抓取所有評(píng)論,還抓取了評(píng)論的頁碼等數(shù)據(jù)。再看看執(zhí)行性能:

還算不錯(cuò),484毫秒,可以說在所有高級(jí)爬蟲組件中,PhantomJS的效率應(yīng)該是最高的了,幾乎沒有其他組件可以直接與之抗衡。有了頁碼數(shù)據(jù),我們就可以對(duì)評(píng)論進(jìn)行執(zhí)行翻頁抓取操作,以這個(gè)速度,抓取幾百頁的評(píng)論數(shù)據(jù)根本不需要搞分布式。
三、如何實(shí)現(xiàn)分布式?
分布式爬蟲通常使用消息隊(duì)列來實(shí)現(xiàn),目前互聯(lián)網(wǎng)上的開源消息隊(duì)列非常多,今天我們就來介紹一款非常拉風(fēng)的分布式消息隊(duì)列開源組件:

RabbitMQ是一個(gè)開源的AMQP實(shí)現(xiàn),服務(wù)器端用Erlang語言編寫,支持多種客戶端,如:.NET、Python、Ruby、Java、JMS、C、PHP、ActionScript、XMPP、STOMP等,支持AJAX。用于在分布式系統(tǒng)中存儲(chǔ)轉(zhuǎn)發(fā)消息,在易用性、擴(kuò)展性、高可用性等方面表現(xiàn)都非常好。
下載地址:
http://www.rabbitmq.com/download.html
分布式爬蟲通常需要兩個(gè)端:
控制端
爬蟲端
控制端主要負(fù)責(zé)控制爬蟲運(yùn)行、監(jiān)控爬蟲狀態(tài)、配置爬蟲抓取方式等。爬蟲端主的功能就是抓取數(shù)據(jù)并將數(shù)據(jù)提交給數(shù)據(jù)清洗服務(wù)。
爬蟲端還需要分出Master爬蟲及Worker爬蟲,Master爬蟲主要利用簡(jiǎn)單爬蟲的運(yùn)行方式實(shí)現(xiàn)高性能的超連接(Links)的抓取。Worker爬蟲則利用高級(jí)爬蟲特性來采集精細(xì)化的數(shù)據(jù),例如Ajax加載的內(nèi)容。把最擅長(zhǎng)的事情交給最合適的爬蟲來做。
聰明的你應(yīng)該想到了,他們之間的溝通方式就是消息隊(duì)列。Master爬蟲只需要將抓取的Links扔進(jìn)數(shù)據(jù)抓取隊(duì)列。Worker爬蟲通過定時(shí)拉去隊(duì)列中的Links來實(shí)現(xiàn)數(shù)據(jù)抓取,抓取完成后將數(shù)據(jù)再提交至數(shù)據(jù)清洗隊(duì)列。
原理應(yīng)該都講清楚了吧?那就自己實(shí)現(xiàn)代碼吧,RabbitMQ官網(wǎng)上都有示例代碼,我就不再這里啰嗦了。
四、如何實(shí)現(xiàn)穩(wěn)定的加密代理?
在這個(gè)互聯(lián)網(wǎng)時(shí)代,免費(fèi)的東西基本上快消失殆盡了,就算有也肯定很垃圾。所以今天我要講的Shadowsocks,也是一個(gè)需要付少量費(fèi)用的東西,這個(gè)東西的強(qiáng)大之處,就在于其流量特征不明顯,可以非常穩(wěn)定的提供上網(wǎng)代理。

下載地址:https://github.com/shadowsocks
Shadowsocks客戶端會(huì)在本地開啟一個(gè)socks5代理,通過此代理的網(wǎng)絡(luò)訪問請(qǐng)求由客戶端發(fā)送至服務(wù)端,服務(wù)端發(fā)出請(qǐng)求,收到響應(yīng)數(shù)據(jù)后再發(fā)回客戶端。中間通過了AES-256來加密傳輸數(shù)據(jù),因此要必普通的代理服務(wù)器安全得多,我們來看看它的運(yùn)行方式:

由圖得知,它需要先在本地運(yùn)行客戶端程序,連接遠(yuǎn)程代理服務(wù)器的服務(wù)端程序?qū)崿F(xiàn)加密通訊。再在本地模擬代理端口,讓本機(jī)流量先經(jīng)過本地客戶端加密,然后再傳輸至遠(yuǎn)程服務(wù)端,完成代理的轉(zhuǎn)發(fā)服務(wù)。
因此我們只需要買一臺(tái)基于Linux的VPS服務(wù)器,成本大約在15元人民幣每月,安裝好服務(wù)端后,就可以實(shí)現(xiàn)一個(gè)非常穩(wěn)定的加密代理服務(wù)。相關(guān)教材網(wǎng)上一大堆,我也就不再這里啰嗦。
五、結(jié)束語
迫于一些壓力,我就不在這里公布詳細(xì)的爬蟲源代碼了,看上面的例子肯定能自己完成一個(gè)更強(qiáng)大的高級(jí)爬蟲。全部源代碼下載:https://github.com/coldicelion/Simple-Web-Crawler
原文地址:http://www.toutiao.com/i6304492725462893058/
回復(fù) 【關(guān)閉】學(xué)關(guān)閉微信朋友圈廣告 回復(fù) 【實(shí)戰(zhàn)】獲取20套實(shí)戰(zhàn)源碼 回復(fù) 【被刪】學(xué)查看你哪個(gè)好友刪除了你巧 回復(fù) 【訪客】學(xué)微信查看朋友圈訪客記錄 回復(fù) 【小程序】學(xué)獲取15套【入門+實(shí)戰(zhàn)+賺錢】小程序源碼 回復(fù) 【python】學(xué)微獲取全套0基礎(chǔ)Python知識(shí)手冊(cè) 回復(fù) 【2019】獲取2019 .NET 開發(fā)者峰會(huì)資料PPT 回復(fù) 【加群】加入dotnet微信交流群 微信終于可以免費(fèi)提現(xiàn)了!


