您的位置:首页 > 编程学习 > ASP.NET

.NET使用Html Agility Pack解析html

更多 2015/3/9 来源:ASP.NET学习浏览量:1229
学习标签: html解析
本文导读:当我们需要解析一个web页面的时候,可以用字符串查找的方式,复杂一点可以用正则表达式,但是有时候正则很麻烦的。为了方便解析html页面,.net环境下可以使用Html Agility Pack插件,HtmlAgilityPack是一个基于.Net的、第三方免费开源的微型类库,主要用于在服务器端解析html文档(在B/S结构的程序中客户端可以用Javascript、jquery解析html)。

在不少应用场合中都希望做到数据抓取,特别是基于网页部分的抓取。其实网页抓取的过程实际上是通过编程的方法,去抓取不同网站网页后,再进行分析筛选的过程。比如,有的比较购物网站,会同时去抓取不同购物网站的数据并将其保存在数据库中。一般,这些网页的抓取都需要对抓取回来的HTML进行解析。

.NET提供了很多类去访问并获得远程网页的数据,比如WebClient类和HttpWebRequest类。这些类对于利用HTTP去访问远端的网页并且下载下来是很有用的,但在对于所下载下来的HTML的解析能力方面,以往,开发者不得不用很简陋的方法,比如使用String.IndexOf,String.Substring或使用正则表达式去解析。

一种方便有效解析HTML的方法是使用开源的工具包HTML Agility Pack,这个包本身是利用了DOM文档对象模型去解析HTML的。仅需要几行代码,开发者就可以利用DOM 去访问文档中的头部一直到它的孩子结点。HTML Agility包也能通过XPATH去访问DOM中的指定结点,同时,它也包含了一个类可以用来下载远程网站上的网页,这意味者开发者可以利用它,同时下载并且解析HTML网页了,十分方便。

 

一、下载和引用

可以从 http://htmlagilitypack.codeplex.com/ 去下载Html Agility包,下载后,这个工具包实际上是以HtmlAgilityPack.dll形式存在的。使用的时候,只需要将这个dll放在你的网站或工程的bin目录下就可以了。

 

二、Html Agility Pack的使用

1、Html Agility Pack包包含了一些类,它们都在HtmlAgilityPack这个命名空间中,因此在使用前,先要引用这个命名空间,using HtmlAgilityPack

2、Html Agility Pack解析html是基于HtmlDocument对象,HtmlDocument这个类代表了一个完整的HTML文档并且包含了DocumentNode属性,这个属性返回的是一个代表文档根结点的HtmlNode对象,我们可以在这个根结点的HtmlNode对象的基础上通过SelectNodes、SelectSingleNode以XPath表达式的方式获取其它节点。

3、结点有如下几个重要属性

Name - 获得或设置结点的名称。对HTML元素来说,它返回标签中的内容,比如对于BODY标签,则返回结果为”body ”,对于[P]标签则返回结果为”p ”,如此类推

Attributes -返回该元素的所有属性的集合

InnerHtml -返回或设置该元素中的HTML内容。

InnerText -返回结点的文本文字。

NodeType -指出结点的类型,可以是Document,Element,Comment或者是文本。

 

三、Html Agility Pack的实例

 

1、解析如下Html页面,获取文章列表

2、定义如下实体

 

 
C# 代码   复制

using System;


namespace MessageHelper
{
   public class Model
    {
       public string Title { get; set; } //标题
       public string Content { get; set; } //内容
       public string Href { get; set; } //文章链接
       public string ComeFrom { get; set; } //来源
       public DateTime Time { get; set; } //发布时间

    }
}

3、定义解析Html的XPath变量

 

(1)、下面这句话是 获取全部 class为list_item article_item开始的div
 
C# 代码   复制

        /// <summary>
        /// 获取文章列表
        /// </summary>
        private const string MessageListXPath = "//div[starts-with(@class,'list_item article_item')]";

(2)、下面这句话是 获取上面获取出来的集合里面每一项的标题

 
C# 代码   复制

        /// <summary>
        /// 获取标题 解释: 第一个div,下的第一个div,下的第一个h1,下的第一个span,下的第一个a标签
        /// </summary>
        private const string MessageNameXPath = "/div[1]/div[1]/h1[1]/span[1]/a[1]";

(3)、和上面一样这个是获取内容

 
C# 代码   复制

        /// <summary>
        /// 获取内容 解释: 第一个div,下的第二个div
        /// </summary>
        private const string MessageContxtXPath = "/div[1]/div[2]";

(4)、这个是获取发布时间

 
C# 代码   复制

        /// <summary>
        /// 获取时间 这个就是 获取 第一个div,下的第3个div,下的span
        /// </summary>
        private const string MessageTimeXPath = "/div[1]/div[3]/span";

 

4、用 Html Agility Pack 找出我们想要的东西

 

 
C# 代码   复制

       /// <summary>
        /// 处理文章信息 Add shuaibi 2015-03-08
        /// </summary>
        /// <param name="myStream">网页的数据流</param>
        /// <returns></returns>
        private static List<Model> GetMessage(Stream myStream)
        {
            var document = new HtmlDocument();
            document.Load(myStream, Encoding.UTF8);
            var rootNode = document.DocumentNode;
            var messageNodeList = rootNode.SelectNodes(MessageListXPath);
            return messageNodeList.Select(messageNode => HtmlNode.CreateNode(messageNode.OuterHtml)).Select(temp => new Model
            {
                Title = temp.SelectSingleNode(MessageNameXPath).InnerText,
                Href = "http://blog.csdn.net" + temp.SelectSingleNode(MessageNameXPath).Attributes["href"].Value,
                Content = temp.SelectSingleNode(MessageContxtXPath).InnerText,
                Time = Convert.ToDateTime(temp.SelectSingleNode(MessageTimeXPath).InnerText),
                ComeFrom = "csdn"
            }).ToList();
        } 

 

5、获网页的Html并调用解析Html的方法

 

 
C# 代码   复制

        /// <summary>
        /// 获取文章列表 Add shuaibi 2015-03-08
        /// </summary>
        /// <param name="url">页面地址</param>
        /// <returns>文章列表</returns>
        public List<Model> GetHtml(string url)
        {
            var myWebClient = new WebClient();
            var myStream = myWebClient.OpenRead(url);
            var list = GetMessage(myStream); //这里调用的是上面定义的方法
            if (myStream != null) myStream.Close();
            return list;
        } 

 

 

收藏
189
很赞
491
您可能感兴趣