一 本系列隨筆概覽及產生的背景css
本系列開篇受到你們的熱烈歡迎,這對博主是莫大的鼓勵,此爲本系列第二篇,但願你們繼續支持,爲我繼續寫做提供動力。html
本身開發的豆約翰博客備份專家軟件工具問世3年多以來,深受廣大博客寫做和閱讀愛好者的喜好。同時也不乏一些技術愛好者諮詢我,這個軟件裏面各類實用的功能是如何實現的。node
該軟件使用.NET技術開發,爲回饋社區,現將該軟件中用到的核心技術,開闢一個專欄,寫一個系列文章,以饗廣大技術愛好者。git
本系列文章除了講解網絡採編發用到的各類重要技術以外,也提供了很多問題的解決思路和界面開發的編程經驗,很是適合.NET開發的初級,中級讀者,但願你們多多支持。github
不少初學者常有此類困惑,「爲何我書也看了,C#相關的各個方面的知識都有所瞭解,但就是無法寫出一個像樣的應用呢?」,web
這其實仍是沒有學會綜合運用所學知識,鍛煉出編程思惟,創建起學習興趣,我想該系列文章也許會幫到您,希望如此。chrome
開發環境:VS2008數據庫
本節源碼位置:https://github.com/songboriceboy/GetWebContent編程
源碼下載辦法:安裝SVN客戶端(本文最後提供下載地址),而後checkout如下的地址:https://github.com/songboriceboy/GetWebContent瀏覽器
系列文章提綱以下:
二 第二節主要內容簡介(如何使用C#語言得到任意站點博文的正文及標題)
使用C#語言得到任意站點博文的正文及標題的解決方案演示demo以下圖所示:可執行文件下載
三 基本原理
要想獲取任意網頁文章的正文及標題,咱們除了要利用上一節提到的HtmlAgilityPack.dll程序集以外,還要藉助於另一個實用的程序集Fizzler.dll(http://fizzlerex.codeplex.com/)
HtmlAgilityPack是經過xpath來解析html元素,相對來講仍是稍微麻煩些;Fizzler提供了相似css選擇器的方式來解析html元素,很是符合咱們的習慣。
一般對於某篇文章,咱們只想保留文章的正文(去掉廣告,側邊欄等四周的網頁佈局元素),接下來,咱們就來看一下操做步驟,這裏咱們須要藉助一下強大的瀏覽器工具。
1.使用firefox瀏覽器或chrome瀏覽器打開咱們想要提取正文的網頁,firefox要安裝firebug插件,chrome直接按F12,這裏咱們以firefox舉例:
好比,打開咱們上一節的博文(http://www.cnblogs.com/ice-river/p/4110799.html),以下圖所示:
首先右上角的小蟲子圖標在咱們安裝完firebug插件後出現,點擊它,瀏覽器下端彈出調試界面,在調試界面中,點擊我紅線框起來的圖標(一藍色方框,上面有個箭頭),此時你會發現網頁中的各個元素都變爲可框選的,咱們框選正文以後,會發如今下面的調試界面對應的div元素被高亮選中,咱們對該div元素(博客園這裏是div#cnblogs_post_body)右鍵,彈出右鍵菜單,以下圖所示:
咱們點擊[複製css路徑菜單項],此時咱們粘貼板中就獲得了正文的css路徑[html body div#home div#main div#mainContent div.forFlow div#topics div.post div.postBody div#cnblogs_post_body]
對於Fizzler來講,咱們只須要提供最後部分的div#cnblogs_post_body便可(你們記住,咱們只須要從得到的css路徑長字符串中從後往前看,拿到最後一個空格以後的字符串,這裏是div#cnblogs_post_body
把這個字符串填入到咱們demo的[正文css路徑]部分,以下圖所示:
其實對應於Fizzler來說,只需一行代碼:
IEnumerable<HtmlNode> NodesMainContent = htmlDoc.DocumentNode.QuerySelectorAll(this.textBoxCssPath.Text);
是否是很簡單?
對於其餘技術博客,你們能夠自行練習,檢驗是否理解了我上面所說的方法,這裏給出幾個常見技術博客的正文Css路徑答案:
站點 ---> CSS路徑 "Cnblogs" ---> "div#cnblogs_post_body" "Csdn" ---> "div#article_content.article_content" "51CTO" ---> "div.showContent" "Iteye" ---> "div#blog_content.blog_content" "ItPub" ---> "div.Blog_wz1" "ChinaUnix" ---> "div.Blog_wz1"
好了,回過頭來咱們講講本節demo中的重點代碼:
獲取博客正文標題:
private void GetTitle() { string strContent = m_wd.GetPageByHttpWebRequest(this.textBoxUrl.Text, Encoding.UTF8); HtmlAgilityPack.HtmlDocument htmlDoc = new HtmlAgilityPack.HtmlDocument { OptionAddDebuggingAttributes = false, OptionAutoCloseOnEnd = true, OptionFixNestedTags = true, OptionReadEncoding = true }; htmlDoc.LoadHtml(strContent); string strTitle = ""; HtmlNodeCollection nodes = htmlDoc.DocumentNode.SelectNodes("//title"); // Extract Title if (!Equals(nodes, null)) { strTitle = string.Join(";", nodes. Select(n => n.InnerText). ToArray()).Trim(); } strTitle = strTitle.Replace("博客園", ""); strTitle = Regex.Replace(strTitle, @"[|/\;:*?<>&#-]", "").ToString(); strTitle = Regex.Replace(strTitle, "[\"]", "").ToString(); this.textBoxTitle.Text = strTitle.TrimEnd(); }
主要流程是首先用咱們上一節給出的 WebDownloader類獲取到網頁的源代碼,而後經過下面一行代碼獲取網頁標題:
HtmlNodeCollection nodes = htmlDoc.DocumentNode.SelectNodes("//title");
這裏的藉助了HtmlAgilityPack的SelectNodes函數提取網頁中的title元素,注意通常的格式良好網頁都具備title元素,由於這樣方便搜索引擎索引收錄咱們的文章,下圖解釋下什麼是title元素
你們注意上圖,我用紅筆圈出的2個地方,應該不言自明瞭吧,不解釋。
獲取博客正文內容:
private void GetMainContent() { string strContent = m_wd.GetPageByHttpWebRequest(this.textBoxUrl.Text, Encoding.UTF8); HtmlAgilityPack.HtmlDocument htmlDoc = new HtmlAgilityPack.HtmlDocument { OptionAddDebuggingAttributes = false, OptionAutoCloseOnEnd = true, OptionFixNestedTags = true, OptionReadEncoding = true }; htmlDoc.LoadHtml(strContent); IEnumerable<HtmlNode> NodesMainContent = htmlDoc.DocumentNode.QuerySelectorAll(this.textBoxCssPath.Text); if (NodesMainContent.Count() > 0) { this.richTextBox1.Text = NodesMainContent.ToArray()[0].OuterHtml; this.webBrowser1.DocumentText = this.richTextBox1.Text; } }
很簡單就是調用htmlDoc.DocumentNode.QuerySelectorAll函數,參數傳入咱們上面講到的正文div的css路徑,最後NodesMainContent.ToArray()[0].OuterHtml中保存的就是網頁正文內容的源代碼,放到richTextBox1.Text裏顯示html源代碼,放到webBrowser1.DocumentText裏顯示網頁內容。
四 下節預告
網頁的抓取主要分爲3步:
1.經過分頁連接抓取到所有文章連接集合(第一節內容)
2.經過每個文章連接獲取到文章的標題及正文(本節內容)
3.從文章正文中解析出所有圖片連接,並將文章的所有圖片下載到本地(下節內容)
這3步有了,以後你就想怎麼折騰就怎麼折騰了,各類加工處理,生成pdf,chm,靜態站點,遠程發佈到其餘站點等等(請繼續關注本系列文章,並不吝點一下推薦,您的支持是我寫做的最大動力)。