1. 程式人生 > >黃聰:C#類似Jquery的html解析類HtmlAgilityPack基礎類介紹及運用

黃聰:C#類似Jquery的html解析類HtmlAgilityPack基礎類介紹及運用

Html Agility Pack 原始碼中的類大概有28個左右,其實不算一個很複雜的類庫,但它的功能確不弱,為解析DOM已經提供了足夠強大的功能支援,可以跟jQuery操作DOM媲美:)

基礎類和基礎方法介紹

Html Agility Pack最常用的基礎類其實不多,對解析DOM來說,就只有HtmlDocument和HtmlNode這兩個常用的類,還有一個 HtmlNodeCollection集合類。

HtmlDocument類

當然在解析DOM前需要載入html原始檔案或者html的字串,HtmlDocument類封裝了支援此功能的方法,下面是載入html的方法介紹。


HtmlDocument類定義了多個過載的Load方法來實現以不同方式載入html,其實主要分為兩種,一種是從Stream中載入html,另外一種是從物理路徑載入html,分別見下面:


方法:public void Load(TextReader reader)
說明:從指定的 TextReader物件中載入Html
示例

HtmlDcument doc =new HtmlDocument();

StreamReader sr
= File.OpenText("file path");

doc.Load(sr);


基於上面方法,衍生出了幾個不同過載方法。

以指定的Stream物件為主的有:

(1)public void Load(Stream stream)    ///從指定的Stream物件中載入html;

(2)public void Load(Stream stream, bool detectEncodingFromByteOrderMarks)    ///指定是否從順序位元組流中解析編碼格式

(3)public void Load(Stream stream, Encoding encoding)    ///指定編碼格式

(4)public void Load(Stream stream, Encoding encoding, bool detectEncodingFromByteOrderMarks)

(5)public void Load(Stream stream, Encoding encoding, bool detectEncodingFromByteOrderMarks, int buffersize)


以指定的物理路徑為主的有:

 (1)public void Load(string path)

(2)public void Load(string path, bool detectEncodingFromByteOrderMarks)    ///指定是否從順序位元組流中解析編碼格式

(3)public void Load(string path, Encoding encoding)    ///指定編碼格式

(4)public void Load(string path, Encoding encoding, bool detectEncodingFromByteOrderMarks)

(5)public void Load(string path, Encoding encoding, bool detectEncodingFromByteOrderMarks, int buffersize)

HtmlDocument類中還定義了直接從html字串中載入Html,如下:


方法:public void LoadHtml(string html)
說明:從指定的html字串中載入html
示例

HtmlDocument doc =new HtmlDocument();

string html ="<div id="demo"><span style="color:red;"><h1>Hello World!</h1></span></div>";

doc.LoadHtml(html);


HtmlDocument類還有其他寫DOM方法的定義,這裡不作詳細介紹,留作以後專門介紹Html Agility Pack寫DOM章節介紹吧,這裡著重介紹Html Agility pack解析DOM的細節。

HtmlNode類和HtmlNodeCollection類


通過HtmlDocument把html載入進來後,接著是要做什麼呢?當然是對html解析了,解析DOM就需要提到HtmlNode類 了。 HtmlDocument類由屬性DocumentNode屬性返回當前Html解析後的一個全域性的HtmlNode物件;如果想獲取某一個元素的 HtmlNode,可以通過HtmlDocument類的GetElementbyId(string Id)方法來獲取,返回指定某一個html元素的HtmlNode物件。如何通過HtmlNode物件來訪問DOM呢?介紹之前先對它的功能瞭解下。


HtmlNode類實現了IXPathNavigable介面,這說明了它可以通過xpath來查詢DOM了,如果對System.Xml 名稱空間下的 XmlDocument類瞭解的,特別是使用過了SelectNodes()和SelectSingleNode()方法的朋友對使用HtmlNode類 將會很熟悉。其實Html Agility Pack內部是把html解析成xml文件格式了的,所以支援xml中的一些常用查詢方式。下面對HtmlNode的一些主要的常用成員作簡要的說明。

HtmlNode類的主要屬性

1)Attributes屬性

獲取當前Html元素的屬性的集合,返回的是一個HtmlAttributeCollection物件。如一個div元素,它可能會定義一些屬性, 如:<div id="title" name="title" class="class-name" title="title div">***</div>,那Attributes返回的HtmlAttributeCollection就包含了 “id,name,class,title”的資訊。HtmlAttributeCollection類是實現了介面 IList<HtmlAttribute>的一個集合類,故此可以通過下面程式碼方式訪問每一個成員。

HtmlNode node = doc.GetElementbyId("title");

string titleValue = node.Attributes["title"].Value;


或者

複製程式碼 foreach(HtmlAttribute attr in node.Attributes)

{

Console.WriteLine(
"{0}={1}",attr.Name,attr.Value);

}
複製程式碼
在獲取屬性值時,如果某一個屬性名稱不存在的話,Attributes["name"]返回的是null值。


2)FirstChild,LastChild,ChildNodes,ParentNode屬性


FirstChild屬性:返回所有子節點的第一個節點,如下面程式碼:

string html ="<div id="demo"><span style="color:red;"><h1>Hello World!</h1></span><div id="innerDiv">inner div</div></div>";

FirstChild則返回的是“<span style="color:red;"><h1>Hello World!</h1></span>” 的節點。


LastChild屬性:返回所有子節點的最後一個節點,以上面的html為例,則返回“<div id="innerDiv">inner div</div>”節點。


ChildNodes屬性:返回當前節點所有直接一代的子節點的集合,不包括跨代子節點,以上面的html為例,則返回“<span style="color:red;"><h1>Hello World!</h1></span>” 和“<div id="innerDiv">inner div</div>”兩個節點。


ParentNode屬性:返回當前節點的直接父節點。

3)獲取Html原始碼和文字


HtmlNode類設計了OuterHtml屬性和InnerHtml屬性用於獲取當前節點的Html原始碼。兩者不同之處 是,OuterHtml屬性返回的是包含當前節點的Html程式碼在內的所有Html程式碼,而InnerHtml屬性返回的是當前節點裡面子節點的所有 Html程式碼。如下面:

複製程式碼 HtmlDocument doc =new HtmlDocument();

string html ="<div id="demo"><span style="color:red;"><h1>Hello World!</h1></span></div>";

doc.LoadHtml(html);


HtmlNode node
= doc.HtmlDocument;

Console.WriteLine(node.OuterHtml);
/// return "<div id="demo"><span style="color:red;"><h1>Hello World!</h1></span></div>";Console.WriteLine(node.InnerHtml); /// return "<span style="color:red;"><h1>Hello World!</h1></span>"; 複製程式碼


如要獲取節點的文字值,通過InnerText屬性來獲取,InnerText屬性過濾掉了所有的Html標記程式碼,只返回文字值,如下面:

Console.WriteLine(node.InnerText);/// return "Hello World!";

HtmlNode類的主要方法

HtmlNode類提供了足夠豐富的方法供查詢當前節點下的子節點(元素),當然也包括查詢當前節點的父節點(元素)的方法,下面列出主要的方法和使用說明。


獲取父節點的系列方法:

1)public IEnumerable<HtmlNode> Ancestors()

獲取當前節點的父節點列表(不包含自身)。

2)public IEnumerable<HtmlNode> Ancestors(string name)

以指定一個名稱來獲取父節點的列表(不包含自身)。

3)public IEnumerable<HtmlNode> AncestorsAndSelf()

獲取當前節點的父節點列表(包含自身)。

4)public IEnumerable<HtmlNode> AncestorsAndSelf(string name)

以指定一個名稱來獲取父節點的列表(包含自身)。

獲取子節點的系列方法:

1)public IEnumerable<HtmlNode> DescendantNodes()

獲取當前節點下的所有子節點的列表,包括子節點的子節點(不包含自身)。

2)public IEnumerable<HtmlNode> DescendantNodesAndSelf()

獲取當前節點下的所有子節點的列表,包括子節點的子節點(包含自身)。

3)public IEnumerable<HtmlNode> Descendants()

獲取當前節點下的直接子節點的列表(不包含自身)。

4)public IEnumerable<HtmlNode> DescendantsAndSelf()

獲取當前節點下的直接子節點的列表(包含自身)。

5)public IEnumerable<HtmlNode> Descendants(string name)

獲取當前節點下的以指定名稱的子節點列表。

6)public IEnumerable<HtmlNode> DescendantsAndSelf(string name)

獲取當前節點下的以指定名稱的子節點的列表(包含自身)。

7)public HtmlNode Element(string name)

獲取第一個符合指定名稱的直接子節點的節點元素。

8)public IEnumerable<HtmlNode> Elements(string name)

獲取符合指定名稱的所有直接子節點的節點列表。

9)public HtmlNodeCollection SelectNodes(string xpath)

獲取符合指定的xpath的子節點列表。

10)public HtmlNode SelectSingleNode(string xpath)

獲取符合指定的xpath的單個位元組點元素。


查詢節點的方法主要是上面10個方法,該類還有其他寫節點的系列方法,這裡不詳細介紹寫操作的方法,留作以後詳細介紹。

結合Xpath進行查詢節點是功能比較強大,這像操作xml那樣方便。


簡單例子的程式碼

下面例子是把部落格園的精華區部落格列表查詢出來。執行結果如下面:

 


程式碼

複製程式碼 程式碼 using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using HtmlAgilityPack;


namespace DemoCnBlogs
{
class Program
{
staticvoid Main(string[] args)
{
HtmlWeb web
=new HtmlWeb();
HtmlDocument doc
= web.Load("http://www.cnblogs.com/pick/");

HtmlNode node
= doc.GetElementbyId("post_list");

StreamWriter sw
= File.CreateText("log.txt");

foreach(HtmlNode child in node.ChildNodes)
{
if (child.Attributes["class"] ==null|| child.Attributes["class"].Value !="post_item")
continue;
HtmlNode hn
= HtmlNode.CreateNode(child.OuterHtml);

///如果用child.SelectSingleNode("//*[@class=\"titlelnk\"]").InnerText這樣的方式查詢,是永遠以整個document為基準來查詢,
///這點就不好,理應以當前child節點的html為基準才對。
Write(sw, String.Format(
"推薦:{0}", hn.SelectSingleNode("//*[@class=\"diggnum\"]").InnerText));
Write(sw, String.Format(
"標題:{0}", hn.SelectSingleNode("//*[@class=\"titlelnk\"]").InnerText));
Write(sw, String.Format(
"介紹:{0}", hn.SelectSingleNode("//*[@class=\"post_item_summary\"]").InnerText));
Write(sw, String.Format(
"資訊:{0}", hn.SelectSingleNode("//*[@class=\"post_item_foot\"]").InnerText));

Write(sw,
"----------------------------------------");

}

sw.Close();

Console.ReadLine();
}

staticvoid Write(StreamWriter writer, string str)
{
Console.WriteLine(str);
writer.WriteLine(str);
}


}
}
複製程式碼

相關推薦

C#類似Jquery的html解析HtmlAgilityPack基礎介紹運用

Html Agility Pack 原始碼中的類大概有28個左右,其實不算一個很複雜的類庫,但它的功能確不弱,為解析DOM已經提供了足夠強大的功能支援,可以跟jQuery操作DOM媲美:) 基礎類和基礎方法介紹 Html Agility Pack最常用的基礎類其實不多,對解析DOM來說,就只有

C#獲取網頁HTML內容的三種方式

HttpWebRequest httpReq; HttpWebResponse httpResp; string strBuff = ""; char[] cbuffer = new char[256]; int byteRead = 0; string filename

C#使用GeckoFx攔截監控Http資料

找了整整兩天,在大海撈針之後,終於在上古程式碼中找到了一個可用的。。。。 可以用喜極而泣來形容測試有效之後的心情!!! 跟cefsharp相比geckofx最大的優點就是模式更接近於IE,包括node、xml、xpath以及單獨設定cookie等。但是資料、問答等實在是太古老太古老了。 如果已入坑gec

ffmpeg基本用法(轉)

sca wid cal ner aspect mp4 動態文本 tegra 控制輸出 FFmpeg FFmpeg 基本用法 本課要解決的問題 1.FFmpeg的轉碼流程是什麽? 2.常見的視頻格式包含哪些內容嗎? 3.如何把這些內容從視頻文件中抽取出來? 4.如

FFmpeg 使用指南

留下 時間 下一個 pseudo rdquo tle 全局 什麽 實時 1. ffmpeg 是什麽? ffmpeg(命令行工具) 是一個快速的音視頻轉換工具。 2. ffmpeg 的使用方式 命令行: ffmpeg [全局選項] {[輸入文件選項] -i &lsquo

FFmpeg視頻轉碼技巧之-crf參數(H.264篇)

文件中 one log 它的 忽略 enter center tail vcd 昨天,有個朋友給我出了個難題:他手上有一個視頻,1080P的,49秒,200多兆;要求在確保質量的情況下把文件壓縮到10M以內。 這是什麽概念呢?按照文件大小10M來計算,碼率是:10 x 8

濃縮的才是精華淺析GIF格式圖片的存儲和壓縮(轉)

meid 單獨 圖片分辨率 change 之前 dex 本質 0.11 blog http://www.cnblogs.com/qcloud1001/p/6647080.html 成文迪, 在Web前端摸爬滾打的碼農一枚,對技術充滿熱情的菜鳥,致力為手Q的建設添磚加瓦

PHP數據庫連接失敗--could not find driver 解決辦法

才會 pdo_mysq php 驅動 mysq sql ould 數據庫 對象 數據庫連接失敗could not find driver在調試一個PHP程序時,報了這個錯誤, could not find driver 經過一番查找,結合自己的思考和實踐,終於找到了問題所在

JQUERY判斷操作CHECKBOX選中、取消選中、反選、第二次無法選中的問題

clas 再次 box als 修改 api disable jquer checkbox 用JQuery做CheckBox全選和反選的時候,遇到一個問題。當用JQ控制全選,全取消一次以後,再次點擊全選,發現代碼變了,但是CheckBox沒有處於選中狀態。 $(

Jquery+DataTables插件,如何在ajax調用服務器數據後,自動給tr添加id屬性

jquer ida ted fnr pos sid idt 事件 all http://legacy.datatables.net/usage/callbacks#fnRowCallback 主要通過 fnCreatedRow 事件來實現 var table = $

jquery.bootgrid表格插件有的屬性(visibleInSelection、cssClass、headerCssClass、headerAlign)不能識別的解決辦法

oot div 添加 bsp load scl 不能 大小 jquer 主要是屬性大小寫問題,修改jquery.bootgrid.js文件,在function loadColumns()方法裏面添加下面的語句就好了 data.headerAlign = data.he

iOS $299刀企業證書申請的過程以及細節補充

別人 華夏鄧白氏 details 等等 .com 註意 內容 QQ blog 最近申請了iOS的 299刀企業證書,相關過程有些問題,分享出來,以便後來人參考。申請的過程我主要參考了別人以前的文章,鏈接如下:1、https://developer.apple.com/cn/

AngularJS最理想開發工具WebStorm

java tool row scl ng-repeat data- oom repos href Aug 29, 2013 Tags: angularangular.jsangularjswebstorm Comments: 23 Comments

通過 itms:services://? 在線安裝ipa ,跨過appstore

ins with 安裝 .get 解決方法 str war item 點擊 1.需要一個html文件,引導下載用戶在線安裝ipa <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">&

JS數學計算精度修正

function 浮點數 turn 計算 filesize add follow fun his 問題描述 如果我問你,4330.61乘以100等於多少,我猜你肯定跟我說:“肯定是 433061”啊! 是啊,要我我也是這麽回答,來來來我們

OTP動態密碼_Java代碼實現

-c name 好的 動態口令 comm final 並不是 bsp down OTP認知 動態口令(OTP,One-Time Password)又稱一次性密碼,是使用密碼技術實現的在客戶端和服務器之間通過共享秘密的一種認證技術,是一種強認證技術,是增強目前靜態口令

史上最詳細的kali安裝教程沒有之一

ner 沒有 操作系統 你是 著作權 如圖所示 鏈接 class 區域 首先在vm裏面新建虛擬機,直接選擇典型,然後下一步。 1 2 然後到了這一步,選擇中間的安裝程序光盤鏡像文件,然後去文件裏面

mysql主從配置(清晰的思路)

   mysql主從配置。鄙人是在如下環境測試的:   主資料庫所在的作業系統:win7   主資料庫的版本:5.0   主資料庫的ip地址:192.168.1.111   從資料庫所在的作業系統:linux   從資料的版本:5.0   從資料庫的ip地址:192.168.1.112 介紹完

Mysql主從配置,實現讀寫分離

大型網站為了軟解大量的併發訪問,除了在網站實現分散式負載均衡,遠遠不夠。到了資料業務層、資料訪問層,如果還是傳統的資料結構,或者只是單單靠一臺伺服器扛,如此多的資料庫連線操作,資料庫必然會崩潰,資料丟失的話,後果更是 不堪設想。這時候,我們會考慮如何減少資料庫的聯接,一方面採用優秀的程式碼框架,進行程式碼的優

浮動視窗程式碼(帶關閉按鈕+全屏漂浮)

<html><head><meta http-equiv="Content-Type" content="text/html; charset=gb2312"><title>帶關閉按鈕的浮動視窗程式碼(全屏漂浮)</title></head