程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> 關於.NET >> 如何使用.Net來設計一個爬蟲系統

如何使用.Net來設計一個爬蟲系統

編輯:關於.NET

創業以來嘗試過好幾個創業項目,在每次 bootstrap的時候,往往都需要借助於一些Internet上的內容,這裡不可避免的就需要寫一些簡單的爬蟲來抓取一些數據來完成項目的初期引導。這些小的爬蟲對於我學習.Net,Http Protocol, Framework Design, Design Patterns提供了很多的幫助。爬蟲版本的一次一次refactoring和upgrade都往往能夠加深我對於某些領域的知識的掌握。

Open source方面比較有名的爬蟲項目有Nutch和Heritrix。Nutch可謂出身名門,Lucene,  Hadoop,  Hbase等都給Nutch增色不少。Heritrix配置有點麻煩,我下載過source code,不過只是大概過了一下,沒有具體debug它的具體源代碼。前幾天也看到園子裡arrowcat和Phinecos(洞庭散人)兩位同志做過一點介紹。由於個人是沒有這方面深入的需求,所以一直都是靠自己個人來思考如何完成一個簡單爬蟲的設計和編碼。這兩個項目都是Java寫的,所以對我們很多.Net fans來說還是不大方便。為此,我把我在寫爬蟲過程中遇到問題,solutions特別是一些需求總結給大家做些基本的介紹,希望對一些人有所幫助,對我個人也算是一個不錯的總結。

第一,請求發送。一般我寫的爬蟲都是走http協議的,當然你可以用TCP協議來模擬http request。

· http request 發送和response接受

在.Net Framework中HttpWebRequest和HttpWebResponse兩個類的封裝使得http發送變得很容易,不過這兩個類設計到很多http protocol方面的知識,所以不熟悉的同志還需深入挖一挖。一般都要提供GET和POST兩個方法。這裡可能會出現gzip壓縮的解壓,有些網站對於useragent要求不能為空等問題。

· 網站編碼方式

我們常見的編碼方式一般是UTF-8,GBK或者GB2312編碼,這裡如果網站變化多就需要自動檢測出每個網站的編碼方式,不然編碼搞錯了,後果很嚴重。這個我沒有做過,應該拿一個request的響應然後分析一下那個結果的http header就可以確定出來了。如果網站可以簡單枚舉,自己手工設置一下就可以了。

· Request發送頻率

如果你的request太多,容易給對方機器加大負載,可能會被server上某些軟件屏蔽掉,最誇張會讓對方管理員發現,所以要小心設置一個合適的請求延遲。不知道google的spider的參數怎麼得來的,應該也是經驗的慢慢積累來著。

· Http分析 :很多時候你寫spider之前是需要分析一下爬蟲源頭,這裡你需要借助一下工具來完成任務,我常用的是HttpWatch,Fiddler2, IE Developer Toolbar, FireBug,類似還有一些,例如Microsoft Network Monitor, Web Development Helper等。有了這些工具的幫助使得你能夠快速了解要抓網頁的結構和request的一些細節。

第二,內容解析。通過request我們拿到response後就需要根據其內容的格式進行解析。我以前寫過關於hotmail, gmail, yahoo! Mail, 163的聯系人導入程序,這些可能需要你去解析xml, json等格式。還有一個關於blog的rss解析問題,這裡都有一些規則,如果能找到open source的library最好,沒有只好讀點文檔或者研究其規則自己嘗試解析了。對於xml解析,使用SAX要比DOM快很多。RSS+ATOM可能有.net方面的開源類庫,我以前是自己解析的,這個就很難把所有情形cover了,risk還是蠻高的。對於最常見的Html解析您可以選用htmlparser這樣的類庫,當然也可以自己從頭來,我主要是利用正則表達式和.Net Framework來搞定這些問題的,例如從文檔中抽取出所有的html anchors,去除所有的html tags,變相對路徑url成絕對路徑url,截取一部分內容到一句話結尾等。還有可能遇到的情形就是垂直搜索,例如抓電影信息,可能對導演,演員,播放長度,圖片要求很准確,這裡你的spider extractor就需要依賴對方的html格式,如果對方有rss等API那就爽了。沒有你只能想辦法降低對html格式的依賴程度了,也可能需要提供一些解析器失效的報警或日志機制。

列一下可能需要的代碼:

抽取所有鏈接:

Regex htmlLinkReg = new Regex(@"(href)[ ]*=[ ]*[""'][^""'> ]+[""'> ]", RegexOptions.IgnoreCase);

去除html標簽和 這樣的編碼:

result = Regex.Replace(html, @"<(.[^>]*)>?", replacedWord, RegexOptions.IgnoreCase);
  
result = Regex.Replace(result, @"&\w{2,7};", "");

第三,分布式的架構。這裡可能涉及到多客戶端的部署,因為很多時候IP算是稀有資源,同一個IP來抓速度還是很慢的,又不敢太快。呵呵。我寫過一個分布式爬蟲,抓了數千萬數據下來。Client我一般是用winform寫的,後台開點線程來完成各種爬行任務,它每次從服務器獲取一點任務,然後去發送request,解析結果,最後再通過http request來上傳爬行結果。這種簡單的架構還是很容易scale的。

· 爬行歷史:你可能需要將spider的url爬行歷史記錄保存下來,一方面可以避免重復爬行;另外也可以判斷這些url是否在上次爬行後更新過。

· 網站更新:如果您需要持續抓取某個網站的內容,你可能需要把首頁或者更新相關的頁面作為源頭,然後抽取出頁面所有鏈接,然後filter出你要解析的頁面和已經爬過的頁面,然後使用一個隊列來存儲這些源頭,通過進一步加深爬蟲深度來找到所有可能新的內容頁面,這裡你可以使用廣度優先搜索或者DFS來遞歸深入。這裡你可能會遇到輸入輸出速率不匹配的情形,你可能需要依賴一些隊列模擬,當然也可以自己通過數據庫來實現。

· 具體頁面爬行:如果您通過數據庫等來存儲具體內容頁面的源頭,對於分布式的應用,你可能需要考慮好同步問題,你可以依賴於.Net提供的一些concurrency方法來解決可能的並發重復問題,例如Monitor, Semaphore, Event, Mutex等.

以上幾點是我關於一個簡單爬蟲設計可能遇到的問題的總結。希望對於需要的有所幫助。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved