1. 程式人生 > >爬蟲還在用Python?我與Node.js不得不說的故事

爬蟲還在用Python?我與Node.js不得不說的故事

深夜閒來無事,默默的開啟github,在搜尋框中填入了”Stars:>1”,本想著依舊可以在第一頁看到Spark的身影,結果第一個映入眼簾的是這個:

快速瀏覽完第一頁(Top10),10個專案裡面7個JS或者具體來說是Node.js的專案!Github歷來代表技術圈發展的風向,那麼這個在Github比Spark更受追捧的Node.js,到底厲害在哪裡?

愛的初體驗Node.js:一體化資料視覺化。

領取福利加python程式語言學習QQ群 515267276

第一次聽說“一體化資料視覺化”我的內心是抗拒的,怎麼可能,我的經驗告訴我,做資料視覺化,需要獲取資料、處理資料、載入資料、呈現資料等多個過程,各種更是涉及到爬蟲、ETL、SQL、HTML、服務端開發等多項技能,一個工具根本無法搞定。

不過抱著一種謹慎的心態,我還是決定先去研究一下Node.js究竟能夠做什麼:

隨後我看到了顛覆我世界觀人生觀價值觀的一片文章:爬蟲效能:Node.js VS Python (“http://python.jobbole.com/86257/”)

以下內容為針對此文章內容的一些要點的提煉,有興趣的可以瀏覽以下,大神請自行跳過此段:

文章主要想要通過爬蟲證明Node.js的非同步策略與I/O能力,看是否真的有官方介紹和相關檔案描述的這麼強勢。(注意:文中作者為了更好的測試Python的效能,並未使用Scrapy等Python爬蟲框架。)

1.headers設計


爬蟲的設計中,為了降低被網站拉黑的風險,同時防止因為標頭檔案導致爬蟲獲取資料內容的不一致,一致的web請求頭是必不可少的,針對一些特殊的網站,甚至還需要人為的加入cookies、網路代理等形式去更好的保護我們的爬蟲不被網站拉黑。文中作者由於測試目的及測試網站自身的反扒機制問題,並未使用較為繁瑣的設定,具體內容如下:

2.爬蟲功能設計


常規爬蟲的設計中需要設定一個url佇列,通過分工協作的方式,某些執行緒專門用於解析佇列中的某類或某幾類的url,某些執行緒專門用於將解析後的結果進行處理(資料落地,新url重入佇列等)。文中作者分別製作了Python單執行緒版,Python多執行緒版和Node.js版3種爬蟲,接下來我們一一分析作者這樣設計的實現:

2.1 Python單執行緒版


整個程式碼邏輯較為簡單,被爬網頁url字尾為頁面,單執行緒版中通過for迴圈,在單個執行緒中完成對30個頁面內共計720個課程的初步內容提取,整個過程為執行緒獲取url資訊,通過網路獲取對應url頁面的具體html程式碼,針對html程式碼解析相關課程的內容,並通過遍歷的方式完成計數。

執行結果越為46s左右,平均每個頁面耗時1.5秒,基本略高於我們正常瀏覽器點選網頁後加載完畢頁面的時間,效能相對較低。

{ it takes 48.1727159614 Seconds to get 720 items

 it takes45.3397999415 Seconds to get 720 items 

 it takes44.4811429862 Seconds to get 720 items

 it takes44.4619293082 Seconds to get 720 items

 it takes46.669706593 Seconds to get 720 items }

2.2 Python多執行緒版

由於篇幅原因,此處主要說明為何Python多執行緒速度(執行結果顯示,處理完畢30個頁面資料總耗時約為11.5秒)會遠遠高於Python單執行緒的原因。


{it takes 11.6800132309 Seconds to get 720 items

it takes 11.3621804427 Seconds to get 720 items

it takes 11.6811991567 Seconds to get 720items  }


單執行緒中,一個執行緒每次只能執行一個命令,多個命令根據設定好的內容依次執行,在此過程中,由於網路傳輸等原因,CPU在網路傳輸的過程中由於無其他可處理的執行緒,導致存在計算資源的閒置浪費,與此同時由於單次只響應一個頁面,計算機的網路頻寬使用也遠遠無法達到上限,故整體耗時較長。

多執行緒模型中,程式通過新建數十個執行緒,每個執行緒處理一個頁面的請求處理和解析,整體過程中若CPU的通道數(可以理解為CPU可以同時處理的執行緒數,目前常規筆記本為2核4通道)低於需要處理的執行緒數,則根據CPU排程執行緒原理,當CPU排程的執行緒開始進行資料IO的時候,CPU會暫時閒置執行緒,處理其他需要處理的執行緒,等到執行緒IO完畢後,繼續進行後續內容的排程,從而起到充分利用CPU計算能力的目的。同時多執行緒對網站進行請求,相比單執行緒版也起到了大大降低請求平均相應時間的作用,從而其到了提高爬蟲效能的作用。

2.3 Node.js版

為了便於大家可以直接在電腦上面測試,Node.js程式碼我先搬運過來:

領取福利加python程式語言學習QQ群 515267276

整體的思路和Python單執行緒版類似,以列表遍歷的形式產生URL串,提交程式碼執行,最後輸出結果,平均下來處理30個頁面的平均時間在3.8秒左右。


{it takes 3.695 Seconds to get 720 items

it takes 3.781 Seconds to get 720 items

it takes 3.94 Seconds to get 720 items

it takes 3.705 Seconds to get 720 items

it takes 3.601 Seconds to get 720 items}


如果單從這個結果考慮,貌似Python的多執行緒版還存在優勢?其實不然,由於Node.js的特性,本文使用的Node.js是單執行緒進行的,而與之對應的Python多執行緒版本應該僅分配一個物理通道進行計算才算公平,而按照作者文章中的處理時間看,多執行緒部署機器的通道數估計會較高,不然不會有如此的效能(請參考單執行緒版的單頁面處理時間的1.5s)。所以綜合來看,在爬蟲這類對於高併發和高I/O的具體應用上,Node.js還是展示了他應有的風采。

注意:

程式設計工具不管怎麼高效,依舊無法擺脫物理效能的約束,針對具體業務的每一次程式碼優化都是存在著某種成本,若場景為一個極高請求數,但是單請求對於網路頻寬需求較少的應用,例如通過呼叫API的方式去窮舉資料,提高執行緒數往往是一個比較好的選擇。

但是在一些圖片採集內容中,較高執行緒數導致的網路頻寬瓶頸卻往往會導致程式的效能降低(CPU在排程執行緒中也是存在一定的效能損耗的),使用一定的執行緒數往往可以起到更加好的效果。

雖說作者在效能對比中並沒有將各類條件控制得比較嚴苛,但就結果而言,Node.js在做爬蟲相關的功能時,較Python還是有一定優勢的。

Node.js優缺點及應用場景

總的來說,PHP、Python、Node.js,哪個比較適合寫爬蟲呢?

PHP:由於其對於多執行緒和非同步的支援較差,在爬蟲領域較不推薦;

Python:目前主流的爬蟲框架語言,對於分散式爬取的支援較好,針對企業級的大規模爬蟲等專案強力推薦;

Node.js:由於其非同步處理機制的特性,對於垂直網站的爬取具有較好的效能和較低的學習成本,但是其對於分散式爬取和訊息通訊的支援較弱,大規模的爬蟲專案的使用難度較高。

而為何選擇使用Node.js作為爬蟲語言?

◆ Node.js作為一種JS語言,入門門檻較低;

◆ 其對於資料視覺化的後端資料支援能力較好(高併發和I/O密集支援),降低學習門檻和壓力;

◆ 業界流行通過Node.js去製作web架構中的中介軟體,完成設定路由,請求介面,渲染頁面等功能,在高效的同時也保證網頁的seo和安全性(對比Ajax,可瀏覽下文:AJAX技術對於SEO的影響 http://blog.csdn.net/dengxingbo/article/details/5756567)

相比而言,Node.js的優點:

◆ 高併發:如此專業的詞彙,身為一個單純的吃貨還真很難理解,便附上一句文中的總結“Java、PHP也有辦法實現並行請求(子執行緒),但Node.js通過回撥函式(Callback)和非同步機制會做得很自然”;

◆ 適合I/O密集型應用:不行了再看下去要被安利了,趕緊調到缺點去。

……

Node.js的缺點(好樣的,終於來了):

1. 不適合CPU密集型應用:好好好,吐槽點一號準備就緒;

4. 開源元件庫質量參差不齊,更新快,向下不相容;

5. Debug不方便,錯誤沒有stack trace。

別問我為啥2,3不見了,明明就可以通過Nnigx可以解決的事情,還放在這麼前面,由儉入奢易,由奢入儉難啊,提出一個缺點馬上帶上一個解決方法,夭壽啦。

……(此處省略許多關於Node.js的適用場景,作者用了一句話總結:Node.js能實現幾乎一切的應用,我們考慮的點只是適不適合用它來做)

領取福利加python程式語言學習QQ群 515267276

好歹找到一個糟點,搞大資料的,每每看到不適合CPU密集型,總是會有莫名的優越感,平時操作計算任務少說都是幾百個core(自行腦補富土康VS小作坊)。

熟練地按下alt+tab,切出聊天視窗,飛快在聊天欄中打入:Node.js雖然說在爬蟲方面還是略有效能優勢(JS的老本行應該的),在後臺開發中能夠支援較高的併發能力(也算JS的一些特性),據說其對於IO密集型操作有著獨到的解決方法(這個還是得服一波),可是其對於CPU密集性的功能要求支援度還是有點問題的(這玩意還是有點問題的,看我後一句怎麼打你臉),說什麼一體化資料視覺化有點太過了吧!

等等,一體化的資料視覺化,貌似和CPU密集性操作有那麼一丟丟的差距,貌似這玩意還和D3.js的整合度還挺高。

這麼說來,資料視覺化的4個步驟(獲取資料,處理資料,載入資料,呈現資料)裡面,Node.js還真的解決了三個比較核心的問題:

獲取資料靠爬蟲

載入資料靠非同步IO:平時還真的是擔心頁面的資料渲染,一個頁面的資料得一個一個得去取資料,基本10個數據下來,等的花兒都謝了

呈現資料靠d3的支援

至於處理資料…:“DBA大神,這個資料你這邊能夠幫我寫個SQL直接出來麼?”“後臺大哥,你這邊的接口裡面能夠幫我再加個計算欄位麼?這邊我怕到時候使用者一瞬間點了幾千下,給人家弄宕機了”……)

那麼問題來了,我上面究竟寫的是什麼?


你以為是一個精分修煉手冊麼?不!其實這是一個廣告O(∩_∩)O。

幾天前,一次巧合看到了稀牛學院的《資料視覺化工程師》課程。作為一個喜歡使用Scrapy的腦殘粉,看到課程內容竟然是Node.js做爬蟲,我這小暴脾氣分分鐘炸得稀里嘩啦的。較真的我想著好好和老師交流溝通一波人生,便做了一波準備...然後就出現了上述精分現象。

課程基於Node.js講解了從爬蟲到後端開發到前段呈現的單一語言的一體化流程操作;適合入門型學員學習使用,學一種語言完成3種功能,活脫脫的事半功倍。

與此同時,課程還設定了至少11個案例展示與講解,並以綜合實戰型結業專案收尾,真能分分鐘教面試官做人的道理。

視覺化課程當然少不了視覺化的開源件。課程內使用了目前業界使用較多的Echart、D3等框架,基本和公司級別使用無縫銜接(資訊源自各類友商)。

至於各類機構都十分推崇的所謂就業問題,我只能說,在我寫這個文章的時候,我已經在幻想被群內的CDO、CEO看上,升職加薪,當上總經理,出任CEO,迎娶白富美,走上人生巔峰。

想想還有點小激動呢,嘿嘿~~ 


關注微信公眾號:程式設計師交流互動平臺!獲取資料學習!