一 本系列隨筆概覽及產生的背景css
本身開發的豆約翰博客備份專家軟件工具問世3年多以來,深受廣大博客寫做和閱讀愛好者的喜好。同時也不乏一些技術愛好者諮詢我,這個軟件裏面各類實用的功能是如何實現的。html
該軟件使用.NET技術開發,爲回饋社區,現將該軟件中用到的核心技術,開闢一個專欄,寫一個系列文章,以饗廣大技術愛好者。git
本系列文章除了講解網絡採編發用到的各類重要技術以外,也提供了很多問題的解決思路和界面開發的編程經驗,很是適合.NET開發的初級,中級讀者,但願你們多多支持。github
不少初學者常有此類困惑,「爲何我書也看了,C#相關的各個方面的知識都有所瞭解,但就是無法寫出一個像樣的應用呢?」,數據庫
這其實仍是沒有學會綜合運用所學知識,鍛煉出編程思惟,創建起學習興趣,我想該系列文章也許會幫到您,希望如此。編程
開發環境:VS2008網頁爬蟲
本節源碼位置:https://github.com/songboriceboy/GatherAll網絡
源碼下載辦法:安裝SVN客戶端(本文最後提供下載地址),而後checkout如下的地址:https://github.com/songboriceboy/GatherAll數據結構
系列文章提綱以下:多線程
二 第五節主要內容簡介(將任意博主的所有博文下載到內存中並經過Webbrower顯示)
將任意博主的所有博文下載到內存中並經過Webbrower顯示的解決方案,演示demo以下圖所示:可執行文件下載
三 基本原理
本節咱們提供了一個示例將本系列中的第一節和第二節的內容綜合到一塊兒,實現下載博客園任意博主的所有博文功能。用戶只要在編輯框中輸入博客園任意博主的ID,該博主的所有文章就會被下載到內存中,咱們本節就來剖析一下實現原理。
採集博文的結構圖以下所示:
整體步驟以下:
1.用分頁地址初始化Url隊列(實際上是一個堆棧數據結構),具體請參考本系列第一節內容;
2.調度器不斷從Url隊列中取得url,從網上獲取該url對應的網頁正文;
3.多線程的網頁爬蟲分析下載到的網頁正文是連接提取頁仍是文章正文頁;
(1)若爲連接提取頁面,則提取所有符合規則的文章連接,而後壓入到前面的Url隊列中(實際上是堆棧操做,這裏能夠理解爲,一個分頁頁面地址換取了幾十個文章連接地址,接下來調度器將取得的連接是這幾十個文章連接地址,所有下載完,存儲到數據存儲後,接下來纔會輪到取第二個分頁頁面,這點你們能夠對照提供的代碼自行理解,此處是網絡爬蟲的精髓)。
(2)若爲文章正文頁,則按照正文css路徑,提取出正文,存儲到數據存儲中(本節爲datatable中),具體可參考本系列第二節內容。
4.遞歸的執行第2步和第3步,直至Url隊列爲空或已經判斷出所有文章下載完畢(參見第一節)時,程序結束。
核心代碼以下:
private void ParseWebPage(string strVisitUrl, string strPageContent, DoWorkEventArgs e) { string strUrlFilterRule = GetUrlFilterRule(); if (!IsFinalPage(strVisitUrl, strUrlFilterRule)) { bool bNoArticle = SaveUrlToDB(strVisitUrl, strPageContent, e); if (!bNoArticle) { BlogGatherNext(e); } } else { if (strPageContent != "") { string strTitle = SaveFinalPageContent("" , GetMainContentCss(), strVisitUrl, strPageContent); } BlogGatherNext(e); } }
IsFinalPage(strVisitUrl, strUrlFilterRule),該行代碼根據本次請求的url和文章連接的url規則來判斷當前獲取的頁面是最終文章頁仍是文章連接提取頁,其實現代碼以下:
protected bool IsFinalPage(string strVisitUrl, string strUrlFilterRule) { bool bRet = false; MatchCollection matchsTemp = Regex.Matches(strVisitUrl.ToString(), strUrlFilterRule, RegexOptions.Singleline); if (matchsTemp.Count > 0) { bRet = true; } return bRet; }
補充說明,何謂連接提取頁?以下圖所示便是:
更詳細的代碼請自行下載研究。