【初碼乾貨】關於.NET玩爬蟲這些事

来源:http://www.cnblogs.com/printhelloworld/archive/2017/01/28/6354085.html
-Advertisement-
Play Games

不要誤會,我不是針對python,也不是針對nodejs,我是說除了.NET之外,玩爬蟲的都是垃圾 ...


這幾天在微信群里又聊到.NET可以救中國但是案例太少不深的問題,我說.NET玩爬蟲簡直就是宇宙第一,於是大神朱永光說,你為何不來寫一篇總結一下?

那麼今天就全面的來總結一下,在.NET生態下,如何玩爬蟲

關於爬蟲

從搜索引擎開始,爬蟲應該就出現了,爬的對象當然也就是網頁URL,在很長一段時間內,爬蟲所做的事情就是分析URL下載WebServer返回的HTML分析HTML內容構建HTTP請求的模擬在爬蟲過程中存儲有用的信息等等,而伴隨著App的發展以及CS系統通訊方式的HTTP化,對服務介面特別是HTTP RESTFul介面的爬蟲也開始流行。爬蟲的具體形式,包括模擬瀏覽器行為和模擬HTTP行為。在爬蟲的發展過程中,也涌現出無數的工具和語言實踐,而今天要說的就是,.NET生態是爬蟲最好的伴侶

但是不要誤會,我不是針對python,也不是針對nodejs,我是說除了.NET之外,所有玩爬蟲的都是垃圾

一、先談一談對於爬蟲的理解

很多人在研究爬蟲的初期,熱衷於進行瀏覽器行為的模擬,包括使用一些語言中的WebBrowser控制項或者類似PhantomJS這樣的無頭瀏覽器,來模擬真實Web行為,進行Dom元素的填寫、按鈕點擊、滾動條操作等等。雖然這樣的做法更接近真實場景,但由於瀏覽器事件的複雜性,在批量高速的處理場景中,這樣的做法穩定程度會大打折扣,我個人非常不贊同這樣的理念。我認為只有從本質上對Web行為進行HTTP的分析,才是關鍵,任何複雜的瀏覽器行為,最終都可以準確的拆分為JS邏輯和HTTP行為,所以想要掌握好爬蟲技術,對HTTP的理解和分析至關重要。

二、那麼第一個神器就登場了,Fiddler

image_thumb2

雖然不是最早一批誕生的嗅探器,但Fiddler得益於.NET框架的強大並且融合了一個基於JScript .NET的子系統,敏捷而全面嗅探的功能快速的獲得了市場的認可,積累了大量用戶,而在被.NET控制項開發公司Telerik收購後,發展迅猛,更推出了脫離UI的跨平臺庫FiddlerCore,可以將嗅探行為融入到大型搜索網路和爬蟲系統或者是外掛應用中

Fiidler是.NET紅利的下的優良產物,而一個好的爬蟲開發工程師,首要學習目標就是對HTTP的嗅探分析,這時候Fiddler就必不可少了。在這裡列舉Fiddler幾個常見的用法

1)HTTP行為捕捉。這是基本功能,打開Fiddler後,瀏覽器或者一般進程有任何通訊發生,都會記錄下具體的HTTP請求和響應。並且根據Content-Type自動顯示為具體的內容,當然了,我推薦直接分析RAW信息,直觀明瞭也能更深刻的理解HTTP。本功能常用功能場景有,分析網頁行為、分析應用程式行為、手工獲取登陸Cookies等

2)HTTPS支持。Fiddler在添加一個本地證書後,可以完整的支持對HTTPS鏈接的抓取。

3)手機應用抓包。現在很多手機應用都使用了RESTFul的後端介面,但在手機上抓取的難度和代價都較大,替代的解決方案是,在Fiddler裡面,開啟一個HTTP代理伺服器,並設置埠,當手機的WIFI網路和Fiddler客戶端網路在同一區域網網段時,設置手機的WIFI網路的代理地址為Fiddler的HTTP代理伺服器地址,這樣手機上任何App的HTTP通訊,都會被Fiddler抓取到。本功能常用功能場景有手機App抓包、遠程代理測試等。而這一用法也常常和安卓模擬器進行配合,可以在PC上完成全部手機應用的通訊行為的分析。

4)HTTP模擬器。Fiddler內置一個請求構造器(Composer),可以手工構建任何HTTP行為,本功能常用場景有,手工抓取與爬蟲測試

5)HTTP劫持。Fiddler可以攔截HTTP請求,並響應修改後的數據,這一用法常見於外掛軟體的研發過程,在應用時,則多是FiddlerCore庫在外掛系統中的使用。這裡不得不補充一句,在這之前,最流行的是winpcap庫(或者winpcap庫的.NET封裝Pcap.Netsharppcap等),雖然winpcap的工作原理使得其應用範圍更廣,但FiddlerCore無疑已經成為了當前應用端最炙手可熱的領域庫。

三、接下來再說一下.NET對HTTP的操控能力

image_thumb1

爬蟲的主要邏輯部分,即是通過程式對HTTP進行操控,包括對目標URL的下載、對模擬HTTP請求的構造。有趣的是,即使只用System.Net下,WebClinet和HttpWebRequest這兩個類,就已經能夠滿足99%的爬蟲場景。下麵列舉一些常用的場景

1)URL快速下載(上傳)。使用WebClinet對URL進行瀏覽並下載,可以說代碼清晰、支持豐富。包括編碼格式下載格式非同步下載Form上傳參數拼接等等各種。

image_thumb4

2)HTTP請求構造。在很多場景中,需要偽造Referer、UserAgent、ContentType等等,從一個語言的HTTP庫對HTTP協議的支持細膩程度可以看出其是否親爬蟲,幸運的是,HttpWebRequest確實足夠全面,能夠滿足所有的自定義需求。

image_thumb8

3)Cookies處理。雖然Cookies已經逐漸淡出歷史的舞臺,但依然有大量的Web開發框架是以Cookie為支撐做Session體系的,所以Cookie的靈活操作也非常重要。

image_thumb10

4)代理服務。有時候目標伺服器會對IP訪問做限制,這時候使用代理伺服器以及不停的更換代理伺服器就非常重要了,如下處理也很簡潔

image_thumb40

不過,也承認一下缺陷,Socks4或者Socks5代理也是會偶爾出現在爬蟲處理中,而HttpWebRequest並不直接支持,而我之前用到過一個非常好的網路處理庫(收費的,還有EMail處理等各種),有完整的Socks5支持,但是好多年了,記不得名字了,有知道的同學可以告訴我,我補充到這篇文章里。

當然了,得益於.NET語言的強大,除了WebClinet和HttpWebRequest這兩個老古董外,還有不少好東西,比如

1)HttpClient。這是.NET4.5框架裡帶來的新東西,相比HttpWebRequest,HttpClient更像是一個無頭瀏覽器,對非同步的支持也更加完備,處理邏輯也更加合理,建議一直用HttpWebRequest做爬蟲的同學可以遷移到HttpClient來。

2)其他基於.NET的第三方HTTP庫或者知名HTTP的.NET實現。例如RestSharpEasyHttpIndy.Sockets等等,這些庫對HTTP進行更加便捷方便的封裝,有興趣的同學也可以試一試,當然了,在這裡我也提一個建議,不要沉迷於對HTTP請求便捷的封裝,.NET也不例外,這會讓你遠離HTTP的本質,對爬蟲能力的提升並無幫助

四、內容處理也是.NET的強項

在做內容型爬蟲時,會出現很多對下載後的內容進行處理的場景,主要也就是對文本的處理,這裡又一次體現了.NET的優勢,包括

1)String類及周邊類。我們來看一張圖

image_thumb12

這裡基本上涵蓋了對字元串的所有處理方法,結構清晰、使用方便。除此之外,還有很多周邊類,諸如CharStringBuilderEncoding等等,用過的都知道好!

2)正則處理。老實說,正則的學習成本往往會高於使用成本,有時候簡單的場景用一些基本的演算法和字元串處理比正則要方便的多,但作為頂級爬蟲玩家,正則處理是一門必須掌握的技能,而一旦你深入而且熟練的掌握了正則處理方法,那麼對字元串的查找、重覆數據的處理的效率將會邁上新的臺階。.NET下正則的處理在System.Text.RegularExpressions命名空間里。

3)Javascript模擬。正如前面所說,所有複雜的瀏覽器行為,最終都可以準確的拆分為JS邏輯和HTTP行為,很多複雜邏輯或者加密的頁面,直接下載到的數據還需要經過一些JS處理,才能夠變成有用的數據,這個時候Microsoft.JScript命名空間的作用就凸顯了,可以快速方便的模擬一些Javascript的內置方法,特別是時間類數學類加密類的一些古怪方法,避免走彎路。

4)序列化與反序列化(JSON、XML處理)。很多新應用的通訊格式多為XML或者JSON,對於此類內容的處理,會涉及到很多JSON、XML序列化反序列化,其中也以JSON序列化居。

首先是XML的處理,.NET中有System.Xml.Serialization命名空間或者System.Runtime.Serialization.DataContractSerializer等。而對XML處理的關鍵,在於能夠靈活的自定義符合XML標準的內容,例如如下代碼:

image_thumb18

然後是JSON的處理,雖然JSON標準並沒有XML那麼複雜,但想要靈活處理,也需要好的框架和工具支撐,在.NET裡面,有下麵幾個好東西推薦

第一個推薦的是Json.NET,這是一個非常流行的JSON處理工具,具體用法不細說,貼幾個官方的介紹代碼

image_thumb20

第二個推薦的是Jil,這是一個速度更快、更加敏捷且細粒度更高的JSON處理庫,與.NET動態語言特性配合,能夠寫出如下優雅且實用的代碼

image_thumb22
image_thumb25

總之一句話,這樣科班而正統的序列化處理體系,不僅能力強大,更讓人心情舒暢!

五、.NET下,敏捷地存儲數據會是一個好幫手

爬到的數據不可能總是在記憶體里操作,大部分時候,也需要存為臨時文件或者資料庫數據。而.NET在這裡的優勢依然非常明顯。

1)保存到文本文件。.NET提供了很多類,可以方便的操作文本文件,例如下麵這樣的超敏捷文本文件操作

image_thumb15

除此之外,還有FileStream、StreamReader等強大的文件操作類可供使用。

2)保存到資料庫。爬蟲程式對目標進行一系列處理後,有用的數據會存入資料庫,如果說在.NET下對SQL Server、MySQL、Oracle、SQLite等資料庫的全面支持是一輛性能十足的跑車,那Linq語法糖加上兩個ORM框架Linq To SQLADO.NET Entity Framework)則是給這個跑車加了個渦輪增壓。可以讓我們用最敏捷漂亮的方式,將爬蟲數據存入到資料庫中,簡潔到窒息

image_thumb28

如果有大批量數據快速插入需求,同樣也有Z.EntityFramework.Extensions這樣的第三方擴展組件可供使用。

凡此種種,只為讓數據處理不要成為爬蟲研發的累贅和束縛

六、.NET生態數不勝數的優秀特性讓爬蟲開發變得優雅

除了以上這些和爬蟲直接相關的內容,.NET還有無數的優秀的特性,可以讓爬蟲開發如虎添翼,我列舉幾個

1)WinForm開發。.NET的WinForm開發,應該是自Delphi後,效率最高的桌面UI開發方式了,雖然和爬蟲沒太大關係,但是如果能夠熟練用好WinForm,完全可以替代控制台應用,來進行爬蟲研發,提高研發效率,誰都別裝逼(特別是Linuxer、Macer等),畢竟,複雜可視化比控制台樣方便多了。

2)多線程處理。即使是在.NET 2.0時期,委托相關機制,便已革新了Win32的多線程API使用方式,而進入到Task並行庫時代後,更是優美到飛起,例如下麵這兩種常見的多線程處理方式

同步語句,非同步處理

image_thumb31

線程併發,靈活跳出

image_thumb35

我想,事已至此,其他所有的語言(.NET體系除外),都是望塵莫及吧。

4)定時處理。定時處理在很多爬蟲場景裡面都會用到,這裡也簡單提一下,在.NET里處理定時可以採用兩種方式,1、是編寫WIndows Service服務來進行定時任務的控制,2、是用定時雲服務(阿裡雲監控、騰訊雲撥測等)喚醒一個IIS托管的ASP.NET Web Application。特別是第二種方式,思路新穎,經我實踐也非常穩定可靠,有興趣的同學可以試一試。

5)其他優秀特質。.NET架構和.NET體系語言因Anders Hejlsberg的偉大而偉大,數不勝數的優秀語言特質,在任何一個聰明的開發人員面前,都是寶藏,諸如泛型擴展方法動態語言特性Lamada表達式反射等等,到底對爬蟲的開發有何幫助,只待大家去慢慢體驗和挖掘咯

七、規模化、系統化的爬蟲,.NET下的軟體工程

當出現龐大目標複雜策略的時候,客觀上下載器就要升級為下載系統、多線程處理擴充了隊列處理、定時程式就也演變為任務體系,這個時候,爬蟲程式就升級成了規模化的爬蟲系統,變成了一個軟體工程的問題,正如上面所說,.NET很強,但實踐太少,能夠深刻理解.NET人也很少。

.NET處理爬蟲很強,可問題是,.NET處理哪個領域不強?都非常強!.NET的軟體工程,還有待各位不斷的去探索,去發揚!

image_thumb37

七、最後再補充一個附加題,就是超高速IPV4的代理IP掃描

這是我之前很深入研究過的一個課題,雖然和爬蟲沒有直接的關係,但結果(高匿名HTTP代理)和爬蟲也有著密不可分的聯繫,況且處理過程也非常值得借鑒,所以分享出來

1)先說一下結果。藉助.NET體系來處理代理IP的掃描,效率極高,產量驚人,實測單節點(100M電信家庭光纖接入)每天可以產生5萬個有效的代理IP。下麵說一下幾個關鍵點

2)IP段資源和資源處理。優質的IP段(特別是機房IP段)以及IP段劃分,都是重要的資源,3個關鍵操作包括, 對純真等IP地址庫存入資料庫進行查詢將IP段以一定的模型存入資料庫進行查詢建立分散式的IP段處理隊列機制

3)SYN高速掃描(S掃描器方式)。超高速IPV4的代理IP掃描的核心技術,就是利用TCP/IP漏洞的SYN半連接掃描,有一個使用C寫的s.exe掃描器是最常見的用法,基於命令行執行模式,而在.NET中,則可以用System.Diagnostics下麵的Process類進行完整的控制和處理,這又一次體現了.NET的價值。本方式下也有個缺陷,就是僅限Windows Server 2003以下操作系統使用

4)SYN高速掃描(.NET封裝SYN方式)。正如上文所說,.NET對於winacap有很多成熟的封裝,可以做到在Windows 10操作系統下的SYN高速掃描,並控制掃描更加穩定(S掃描器高速但並不穩定),用於桌面級分散式代理IP掃描是絕佳配備。

5)代理IP驗證。掃描到開放埠的IP地址後,只有驗證成功了才能被我們所用,而往往成功率都在萬分之一以下,所以驗證的過程又是一個關鍵所在,幸好我們有.NET下的優秀的多線程處理,使得這一驗證程式非常簡潔和易重構。

如果對此話題有興趣的同學,可以聯繫我尋求進一步的幫助,今天篇幅有限,只是簡單略過

八、今天要說的差不多就結束了,下麵是總結

總結1。今天討論的東西不是爬蟲而是.NET如何玩爬蟲。也並不是在說.NET某個具體功能如何絕頂厲害,而是在說在.NET生態下的很多出色功能結合到一起後,就變成了一個非常美好親爬蟲的體系。所以無論是從生態能力出發還是基於學習實踐成本的考慮,做爬蟲程式或是大規模爬蟲系統,.NET一定是首選!

總結2。我試圖告訴一些用其他語言正在研究爬蟲的人們,你們走了一條邪路,以python比較有名的爬蟲框架scrapy為例,這又是一群想建造輪子的忙碌不休的但卻又智商不高的程式員所折騰出怪胎,試圖統一爬蟲的過程,構建模塊化流程化的插件機制,但事實上,這種東西用的越多,越遠離了爬蟲的本質,越不能適應複雜的爬蟲場景。爬蟲的本質是對目標WebServer頁面行為業務流程精準分析,是對HTTP的深刻理解,是對正則多線程等周邊技術以及軟體工程的靈活運用,爬蟲場景稍微複雜變化一下,scrapy這樣的爬蟲就成了雞肋,運用scrapy這樣的工具,對程式員在爬蟲領域的學習成長來說,不僅沒有明顯幫助,更顯反智,我有遇到過相當多做爬蟲的同學,連HTTP Header裡面有些什麼都說不出來說不清楚,卻玩爬蟲工具6的飛起,這無疑是可悲的。切記先學會走路,再去跑步,而當你深刻的理解了爬蟲的本質後,你就會發現,並沒有所謂的爬蟲語言或者爬蟲框架,只有高效的語言和工具,而這時:

.NET生態就恰到好處的映入你眼前,讓你流連忘返!


作者:張柔,發佈於  博客園  與  張柔的博客

轉載請註明出處,歡迎郵件交流:[email protected],或者加QQ群:11444444


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 引例:已知如下程式 試寫出程式的輸出值。(雖然我很討厭做這種筆頭功夫的題,我也堅信編程語言是在實踐中練出來的,但是這個題還是比較經典,所以還是拿來當一個例子來說明一下數組指針到底是個什麼玩意) 最初在學習C語言時,就一直為這兩個名詞所困擾。其實也怪漢語的博大精深,兩個詞交換一下位置,所表示的含義就不 ...
  • JSP頁面間傳遞參數是經常需要使用到的功能,有時還需要多個JSP頁面間傳遞參數。下麵介紹一下實現的方法。 (1)直接在URL請求後添加 如:< a href="thexuan.jsp?action=transparams&detail=directe">直接傳遞參數< /a> 特別的在使用respo ...
  • 1. 點擊File->New->Other,在彈出的對話框中選擇Maven->Maven Project: 2. 點擊Next,選擇maven-archetype-webapp: 3. 填入Group ID和Artifact ID,會自動生成一個包名: 4. 點擊Finish,會生成以下的目錄: 5 ...
  • 1. 首先下載apache-maven-3.3.9-bin.zip,並解壓; 2. 添加系統變數MAVEN_HOME,值為apache-maven-3.3.9-bin.zip的解壓路徑: 再在path變數中添加: 3. 輸入命令mvn -version檢測安裝是否成功: 4. 編輯%MAVEN_HO ...
  • 首先,在applicationContext.xml文件中加一行: 加上這一行以後,將自動掃描路徑下麵的包,如果一個類帶了@Service註解,將自動註冊到Spring容器,不需要再在applicationContext.xml文件定義bean了,類似的還包括@Component、@Reposito ...
  • FunDA的設計目標就是把後臺資料庫中的數據搬到記憶體里,然後進行包括並行運算的數據處理,最後可能再對後臺資料庫進行更新。如果需要把數據搬到記憶體的話,那我們就必須考慮記憶體是否能一次性容納所有的數據,有必要配合數據處理分部逐步讀入,這就是Reactive Stream規範主要目的之一。所以在設計FunD ...
  • 前段時間,聽了一堂C語言的課,那老師說:“數組名就是一個指向數組首地址的常量指針”。 我上百度查了一些,有好多教程、書籍等,都持相同的觀點。 但我一直感覺——數組名不等於指針。 實踐是檢驗真理的唯一標準,於此,有了以下內容。 首先,聲明一個數組和一個常量指針並指向那個數組。 設問:一個整型指針的長度 ...
  • 閱讀目錄 前言 解決數據一致性的方案 回到DDD 設計 實現 結語 一、前言 之前的十一篇把用戶購買商品並提交訂單整個流程上的中間環節都過了一遍。現在來到了這最後一個環節,提交訂單。單從業務上看,這個動作的背後包含了多個業務操作,根據用戶填寫的訂單信息生成訂單、扣除使用的餘額和積分、使用選擇的禮券等 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...