当前位置:编程学习 > ASP.NET> 正文

.NET使用Html Agility Pack解析html

时间:2015-3-9类别:编程学习

.NET使用Html Agility Pack解析html

.NET使用Html Agility Pack解析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开始的li
  •  
  • C# 代码   复制
  • 
            /// <summary>
            /// 获取文章列表
            /// </summary>
            private const string MessageListXPath = "//li[starts-with(@class,'list_item article_item')]";
    
    			
  • (2)、下面这句话是 获取上面获取出来的集合里面每一项的标题

  •  
  • C# 代码   复制
  • 
            /// <summary>
            /// 获取标题 解释: 第一个li,下的第一个li,下的第一个h1,下的第一个span,下的第一个a标签
            /// </summary>
            private const string MessageNameXPath = "/li[1]/li[1]/h1[1]/span[1]/a[1]";
    
    			
  • (3)、和上面一样这个是获取内容

  •  
  • C# 代码   复制
  • 
            /// <summary>
            /// 获取内容 解释: 第一个li,下的第二个li
            /// </summary>
            private const string MessageContxtXPath = "/li[1]/li[2]";
    
    			
  • (4)、这个是获取发布时间

  •  
  • C# 代码   复制
  • 
            /// <summary>
            /// 获取时间 这个就是 获取 第一个li,下的第3个li,下的span
            /// </summary>
            private const string MessageTimeXPath = "/li[1]/li[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;
            } 
    
    		
  •  

     

    标签:
    上一篇下一篇

    猜您喜欢

    热门推荐