用C++、Python、Ruby寫爬蟲的比較?

我打算寫一個爬蟲爬點數據,調查了一下,發現很多教程以及現有的成熟框架似乎都是基於Python的,比如Scrapy……。於是我產生了如下疑問:為什麼鮮有人用C++或Ruby寫爬蟲呢?

關於C++,是我想它的速度顯然是遠快於Python的,我也發現了一個叫chilkat的公司提供C++的爬蟲庫。但為什麼沒有成熟的基於C++的爬蟲框架呢?(或許是我沒找到?)我見過爬蟲用Python、Ruby、甚至javascript寫的,鮮有用C++的,難道爬蟲不應該優先考慮速度么?

關於Ruby,我是覺得他和Python是差不多的。而且我還覺得Ruby更簡潔更好用些,為什麼感覺網上關於用Ruby寫爬蟲的信息較Python來少得多呢。。


Ruby 爬蟲框架少是因為幾點:

  • 一般程序員不了解 Ruby
  • Ruby 缺少 NLTK/Stanford NLP 這種全面的自然語言處理工具 (基本分散成了好多個 gem), 而爬過來分析關鍵詞啊情感啊的需求還是挺多的
  • 缺少一個 Scrapy 這樣的品牌把社區力量匯聚起來 (雖然我覺得 Scrapy 和裸寫沒多大區別...)

但, Ruby 是文本處理最方便的語言, 比 Python 不止方便一點點.

Python 沒有正則表達式字面量, 經常要先 re.compile() 或者 regex.Regex() 緩存起來提高性能, 而 Ruby 里的正則字面量都是預編譯的, 不需要做這種手動優化. Python 標準庫的 re 不能搞定的地方例如 Unicode character class, 還得上 regex. 而 regex 還有 當你既需要匹配 Grapheme, 又需要 Unicode character class 時, 就沒辦法了. 而 Ruby 自帶的正則表達式相當於 Python 3 的 re 和 regex 包的總和, 文檔也非常完整.

Python 的模塊設計缺乏一致性, 同樣是處理字元串, 有的是字元串自帶的, 有的卻在 string 包里. 經常寫著代碼發現誒這個函數得 import string 才有, 然後回頭補括弧, 碼代碼的流暢性大打折扣. Ruby 的字元串方法全都是實例方法, 編寫的腦包袱很小, 代碼簡單容易維護. 同樣是調用其他進程, 現存的代碼里 os.system, os.spawn*, os.popen*, popen2.*, subprocess.* 混著用的很多... Python 里哪些功能是在 os 包, 哪些是在 sys 包, 很難全部記住, 需要 import 很多很細的東西. 而 Ruby 的對應模塊劃分粒度要稍微好一些.

再說回來, 爬蟲框架的調度邏輯, 其實用不了幾行代碼. 現在用 Headless Chrome 加點腳本處理也差不多了...


爬蟲的性能瓶頸通常是網路IO吧,內容解析速度再快也沒用。


我改過一個scrapy,改成用thrift框架分散式。

當時的想法是,其中某些部分例如網頁處理,如果有瓶頸,可以弄成C++重寫一下。

不過只是寫著玩,後來忙就沒動力繼續改成C++了。用python寫還是快很多。


其實前幾天因為調用一些REST API的時候看過C++的一些網路庫,網路上有很多封裝十分方便的網路庫,其實在網路方面只要配置好項目,用C++爬取數據還是能和Python、Java一樣簡單的。

但是問題是在於C++對於內存的管控要求很高,這點兒很難把握,如果沒有良好的編程風格和編程習慣,爬蟲跑不了太久程序就崩潰了,而且C++對於字元串的處理也是個問題,如果不依賴於其他庫的話,僅用std::string,Python一句話C++至少就要寫3句。Python10句話C++估計得50句了。

所以綜上所述,大家不用C++網路爬蟲主要原因還是:

因為框架問題,其實C++的開發效率低,容易內存泄露這些問題很大程度上可以通過優秀的第三方庫來解決,但是C++優秀的第三方庫相對於Python和Java來說也是比較少的了

而且C++不原生支持網路庫以及C++11之前語法上的繁雜也導致了大家懶得去給C++開發相關的框架。

還有就是C++和腳本語言的工作原理導致了C++存在劣勢了,有時候僅僅是需要更改一個簡單的功能就要重新編譯整個項目,而腳本語言直接改掉然後放上去繼續運行就好了,就算是Java在編譯速度上也是可以甩C++幾條街的。希望C++17引入module之後情況會有改善。

最後就是對於一般的爬蟲而言,爬蟲的瓶頸在於網路IO,Python足夠,稍微需要點兒速度也可以通過定位於互聯網的Java實現,C++的優勢本來就體現不出來,還在開發效率上存在劣勢,大家當然不會用的。當然,對於大型企業,他們的網路爬蟲對於性能的強調以及有能力造一個不錯的輪子導致了他們也願意使用C++來開發爬蟲。不過我覺得更合適的方法是用Python去爬,C++來處理,畢竟長劍和匕首都得帶在身上才能所向披靡嘛。


不要用C++

不要用C++

不要用C++

如果你是以爬取數據為目的,而不是以學習C++以及多線程編程為目的,強烈不建議C++

如果是為大公司開發大型數據爬取系統,另當別論

小公司或者個人開發爬蟲,或者要求開發周期短,強烈建議Python

沒寫過爬蟲,熟悉一下,很快也就能寫出一個不錯的爬蟲以完成任務

若使用python可考慮在Scrapy基礎上修改訂製開發

或者直接自己用python寫爬蟲,藉助request+beautifulsoap很快完成,藉助Pool可並行,縮短時間

PS: 最近參與了C++爬蟲開發,感覺十分的蛋疼。。。如果用python我一晚上就搞定了....


我分別用C++,C#,Python寫過爬蟲。

使用的是相同(相近)的演算法,三個版本,同樣的環境分別測試。發現三個版本的測試結果一模一樣:解析單元幾乎一直處於掛起狀態,因為抓取速度根本趕不上處理速度。

每個網頁剛被下載下來瞬間就完成解析了,使用任何語言都一樣。所以開發爬蟲的時候哪個語言方便用哪個就行了。


我覺得純說爬蟲的話, js 比 ruby, py 都好用。

講真,很多不是性能問題,而是反反爬的問題…


爬蟲的最大的瓶頸是網路IO, 使用async io或類似golang的goroutinue,而不是多線程。知乎上爬蟲這麼多,怎麼討論起來........


Python最適合,沒用過其他兩個寫過,也不推薦。

再怎麼說Python也是排第一的呀(手動滑稽)。


如果量大了 最好使用c++

c++多線程要比py之類的腳本語言快50倍+

雖然爬蟲的性能瓶頸是網路IO,但是在高並發環境下c++的效率會比py高很多很多很多

其實c++最大的優點並不是 所謂的高性能 而是其靈活性 變化莫測

其實c++開發 效率並不比py慢多少 反而很多時候甚至還要比py開發效率要高

應為我們可以把一些常用的代碼封裝的比py還要簡潔高效 另外c++處理數據的效率要比py高很多

具體使用py也好c++也好 還是更具自己的熟練程度 因人而異吧


因為 Ruby 程序員的所有精力主要集中在 Rails 這一塊了, 木有時間去搞爬蟲....


爬蟲就是網路爬蟲(Web crawler),是一種按照一定的規則,自動地抓取萬維網信息的程序或者腳本,它們被廣泛用於各類網站,可以自動採集所有其能夠訪問到的頁面內容,以獲取或更新這些網站的內容和檢索方式。

換句話說,爬蟲主要目的是將網頁下載到本地,然後通過一系列的數據分析演算法等提取有效信息(這也就類似與數據分析)。先來說說C++寫爬蟲的流程:

1. 選出種子URL(必須可訪問,如果不可訪問,爬蟲生存周期直接結束)。

2. 開啟爬蟲線程,首先讀取種子URL。

3. 讀取到種子URL內容,一邊提取頁面的URL,另一方面分析當前頁數據。

4. 保存提取的URL到「URL庫」(已經掃描的置為1,未掃描置為0),另外保存重要的數據到「數據分析庫」。

5. 線程讀取「URL庫」中的未掃描鏈接。

6. ……重複3、4、5操作……

7. 爬蟲生存周期(可指定:當前域名掃描結束,死亡;或指定:記錄掃描深度,超過深度死亡)。

再來看看Python寫爬蟲的基本操作: 

1.導入爬蟲所需要的庫(如:urllib、urllib2、BeautifulSoup、Scrapy等)

2.定義目標鏈接:url="http://www.cnblogs.com/Maple2cat/"

3.添加data信息:data為字典類型,可以添加name,password等一些登錄所需信息

4.定義headers:有些網站會識別鏈接是否由瀏覽器發出的請求,需要定義headers用偽裝是瀏覽器所訪問的

5.如果在第三步中添加了data信息,則需要對data進行轉編碼:urlencode(data)

6.請求鏈接:res=urllib2.Request(url,data,headers)

7.讀取HTML源碼:html=res.read()

8.解析html,一般常用的方法有兩種:1 正則表達式(根據提取規則截取目標內容);2 BeautifulSoup(根據html標籤進行提取,如:&……&)

9.存入本地或者資料庫

為什麼用Ruby寫爬蟲的信息較Python來少得多?這是因為Python更受歡迎啊,又好學。而且,Python已經成為世界上最受歡迎的語言了。


如果你真想要在爬蟲上考慮速度和性能的問題的話,我覺得用集群來做 mapReduce 更為靠譜,在語言的性能上糾結最後效果其實也不顯著,但是還是盡量避免C++寫爬蟲,何必呢


還是用戶基數大導致社區活躍,為什麼用的人多?因為一般需求的爬蟲都只是特定業務邏輯,需要定製很多規則而不是寫代碼,所以真正這類的用戶可能沒有太強的程序背景,要求的是規則描述好寫、清晰、易改,而不是功能靈活強大,所以當然是要不會編程的人都能看懂的python上了。

而要真上分散式了,那又要考慮穩定性和對複雜架構友好了,這方面還是Java強,而且基本開源的分散式infra都是Java based,這麼想的話,現在市面上都是python和java的爬蟲框架也就不難理解了。


用 C++ 寫程序開發慢 bug 多優勢不明顯。資源管理、內存訪問,各種細節的坑數不盡數;能不必須用的時候當然應該選擇迴避。

Ruby 的話,可能因為是火起來的時間比較晚,所以資源比較少吧。


推薦閱讀:

怎樣通過互聯網了解一家公司的現狀?
給你一台交換機,一個路由器,你能夠做什麼?
最近發現很多人在裝了360衛士後電腦漸漸地多了很多360系列軟體的現象,這是為什麼?
firefox有什麼奇技淫巧?
當區域網內客戶端數量大於254時,如何解決DHCP地址池不夠用的問題?

TAG:Ruby | Python | 計算機網路 | 爬蟲計算機網路 | C |