HTML Agility Pack 搭配 ScrapySharp,完全解除Html解析的痛苦(轉)

自從 Web 應用程序自 1993 年 W3C 設立以來就開始發展,並且 HTML 也歷經了數個版本的演化(1.0 – 2.0 – 3.0 – 3.2 – 4.0 – 4.01),如今也已經成爲Web網頁或應用程序的最基礎,想要學習如何設計 Web 網頁或開發 Web 應用程序,這已是絕對必需要學的東西了,就算是方便的控件(例如 ASP.NET),但 HTML 仍然有學習它的必要性,所以若是不會 HTML,就等於沒學過 Web 網頁通常。css

拜 HTML 與 Web 瀏覽器蓬勃發展之賜,各式各樣的應用都在網絡上迅速發展,舉凡電子商務、企業門戶、在線下單、企業間協同應用等,乃至於社交、個性化、Web 2.0 等商務與組織運用等能力,而在信息爆炸的時代,不少信息整合的應用也隨之出爐,而這些信息整合的應用程序都會鏈接到不一樣的網站下載其信息,而且在重重的 HTML 中剖析出想要的數據(例如每股價格、漲跌幅、成交量等)。html

可是 HTML 自己並非一個結構嚴謹的語言,它容許卷標(tag)能夠在不 close 的狀況下繼續使用。這也是由於瀏覽器設計的高容錯性(Fault Tolerance)所致,如此一來,想要依照規則來剖析 HTML 文件幾乎變得不可能,並且對方的網站的 HTML 結構也可能會隨時變化,在這種狀況下,剖析 HTML 變得很是辛苦,雖然 W3C 有另外推展 XHTML(遵照 XML 嚴謹格式的 HTML),但使用它來設計網頁的案例仍爲少數,大多數的網站仍然是使用 HTML。所以咱們會須要一個工具,可以有方法快速的解析 HTML 以取出咱們須要的數據。node

你們都知道,HTML 自己其實只是一個 HTML 標記的字符串而已,所以通常說到要解析 HTML,第一個會想到的大概就是字符串比對(string comparison),本身針對 HTML 的結構寫一個 pattern,而後由函式去作逐一的比對,例如:正則表達式

[C#]c#

1. string pattern = "";api

2. html.IndexOf(pattern);瀏覽器

不過傳統的字符串比對效能太差,也沒有一個規則性,於是才發展出正則表達式(Regular Expression)技術,例以下列這樣的語法:網絡

[Regular Expression]架構

1. \s]+))?)+\s*|\s*)/?<scrapy

但 Regular Expression 的學習曲線很高,若要使用它來解析 HTML,而且再加以定製化(Customization)的話,對於通常開發人員來講,實在沒有什麼親和力。

HTML 還有一個特點,就是它是具層性(Hierarchy)的,所以瀏覽器在解譯它的時候都會以文件樹(document tree)的方式,再用遞歸(recursive)的方法來處理它,但 Regular Expression 沒有支持層級性的剖析,而最接近階層剖析又好用的工具,莫過於 XML Parser 了,它的 DOM 以及 XPath 的特性,均可以讓解析 XML 的工做變得輕鬆,然而 XML Parser 沒法讀取通常的 HTML(XHTML 能夠),由於通常的 HTML 是結構鬆散的類型,XML Parser 會在讀入時檢查語法結構是否完整(也就是 Well-known 的結構),若讀入的是結構鬆散的內容的話會擲出例外訊息,所以沒法直接使用 XML Parser 來輔助。

HTML Agility Pack 是由法國的一位軟件架構師 Simon Mourier 所開發,而且由 DarthObiwan 以及 Jessynoo 輔助開發出來的一個軟件工具,它可讓剖析鬆散格式 HTML 的工做就像剖析 XML 同樣簡單,它也有相似於 System.Xml 命名空間中的 XML DOM 的許多類別,除了可使用階層的方式存取 HTML 之外,它也支持使用 XPath 的方式來搜尋 HTML,這會較以往使用文字比對或是 Regular Expression 的比對方式來得更明確。

若要使用 HTML Agility Pack 組件,可先上 Codeplex 的 HTML Agility Pack 網站下載二進制文件(同時也提供源代碼、說明文件以及 HAP Explorer 工具程序可下載),並解壓縮後,在項目加入對 HtmlAgilityPack.dll 的引用。

Html Agility Pack 源碼中的類大概有28個左右,其實不算一個很複雜的類庫,但它的功能確不弱,爲解析DOM已經提供了足夠強大的功能支持,能夠跟jQuery操做DOM媲美:)Html Agility Pack最經常使用的基礎類其實很少,對解析DOM來講,就只有HtmlDocument和HtmlNode這兩個經常使用的類,還有一個 HtmlNodeCollection集合類。

HTML Agility Pack的操做起來仍是很麻煩,下面咱們要介紹的這個組件是ScrapySharp,他在2個方面針對Html Agility Pack進行了包裝,使得解析Html頁面再也不痛苦,幸福指數直線上升到90分哈。

ScapySharp有了一個真實的瀏覽器包裝類(處理Reference,Cookie等),另一個就是使用相似於jQuery同樣的Css選擇器和Linq語法。讓咱們使用起來很是的爽。它的代碼放在 https://bitbucket.org/rflechner/scrapysharp。也能夠經過Nuget添加

image

下面咱們來看一段解析博客園的博客文章的代碼:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using HtmlAgilityPack; 
using ScrapySharp.Extensions; 
using ScrapySharp.Network;

namespace HTMLAgilityDemo 

class Program 

static void Main(string[] args) 

var uri = new Uri("http://www.cnblogs.com/shanyou/archive/2012/05/20/2509435.html");
var browser1 = new ScrapingBrowser(); 
var html1 = browser1.DownloadString(uri); 
var htmlDocument = new HtmlDocument(); 
htmlDocument.LoadHtml(html1); 
var html = htmlDocument.DocumentNode;

var title = html.CssSelect("title"); 
foreach (var htmlNode in title) 

Console.WriteLine(htmlNode.InnerHtml); 

var divs = html.CssSelect("div.postBody");

foreach (var htmlNode in divs) 

Console.WriteLine(htmlNode.InnerHtml); 
}

divs = html.CssSelect("#cnblogs_post_body"); 
foreach (var htmlNode in divs) 

Console.WriteLine(htmlNode.InnerHtml); 



}

Basic examples of CssSelect usages:

 

var divs = html.CssSelect("div");  //all div elements

var nodes = html.CssSelect("div.content"); //all div elements with css class ‘content’

var nodes = html.CssSelect("div.widget.monthlist"); //all div elements with the both css class

var nodes = html.CssSelect("#postPaging"); //all HTML elements with the id postPaging

var nodes = html.CssSelect("div#postPaging.testClass"); // all HTML elements with the id postPaging and css class testClass

var nodes = html.CssSelect("div.content < p.para"); //p elements who are direct children of div elements with css class ‘content’

var nodes = html.CssSelect("input[type=text].login"); // textbox with css class login

We can also select ancestors of elements:

var nodes = html.CssSelect("p.para").CssSelectAncestors("div.content < div.widget");

參考文章:

HTML Agility Pack:簡單好用的快速 HTML Parser

開源項目Html Agility Pack實現快速解析Html

c#中的jQuery——HtmlAgilityPack

Html Agility Pack基礎類介紹及運用

.Net解析html文檔類庫HtmlAgilityPack完整使用說明--採集軟件開發尤爲好用

Crawler-Lib Crawler Engine

挖掘百度關鍵詞示例:BaiduTools.zip

原文地址:http://www.cnblogs.com/shanyou/archive/2012/05/27/2520603.html

相關文章
相關標籤/搜索