HtmlAgilityPack --解析Html源码

最近项目需要从网络上抓取一下数据解析Html源码,奈何正则表达式难写,于是网上搜索找到了“ HtmlAgilityPack”类库,敏捷开发,果然效率非同寻常。

在此做笔记,写下心得,顺便给自己总结一下。

1、 HtmlAgilityPack使用的是XPath进行路径搜索,如果对XML路径搜索很熟悉,用起来会得心应手

<?xml version="1.0" encoding="ISO-8859-1"?>

<bookstore>

<book>
  <title lang="eng">Harry Potter</title>
  <price>29.99</price>
</book>

<book>
  <title lang="eng">Learning XML</title>
  <price>39.95</price>
</book>

</bookstore>

/bookstore/book[1] 选取属于 bookstore 子元素的第一个 book 元素。
/bookstore/book[last()] 选取属于 bookstore 子元素的最后一个 book 元素。
/bookstore/book[last()-1] 选取属于 bookstore 子元素的倒数第二个 book 元素。
/bookstore/book[position()<3] 选取最前面的两个属于 bookstore 元素的子元素的 book 元素。
//title[@lang] 选取所有拥有名为 lang 的属性的 title 元素。
//title[@lang=‘eng‘] 选取所有 title 元素,且这些元素拥有值为 eng 的 lang 属性。
/bookstore/book[price>35.00] 选取 bookstore 元素的所有 book 元素,且其中的 price 元素的值须大于 35.00。
/bookstore/book[price>35.00]/title 选取 bookstore 元素中的 book 元素的所有 title 元素,且其中的 price 元素的值须大于 35.00。

2、HtmlAgilityPack基本用法:

最常使用的方法:SelectNodes (XPath)、 SelectSingleNode(XPath) 、

CreateNode(HtmlNode.OuterHtml)(该方法通常用在查询完的结果再次进行分析,无法从查询出来的节点进行操作,查询是对大节点树的操作),一般用法

其流程一般是先获取HTML,这个可以通过HtmlDocument的Load()或LoadHtml()来加载静态内容,或者也可以HtmlWeb的Get()或Load()方法来加载网络上的URL对应的HTML。(此方法我还没尝试,不知道是否能够加载网络上的方法)
 得到了HtmlDocument的实例之后,就可以用HtmlDocument的DocumentNode属性,这是整个HTML文档的根节点,它本身也是一个HtmlNode,然后就可以利用HtmlNode的SelectNodes()方法返回多个HtmlNode的集合对象HtmlNodeCollection,也可以利用HtmlNode的SelectSingleNode()方法返回单个HtmlNode。

我从网站获取数据用WebClient、WebRequest、WebResponse 简单协议(Http、ftp)请求,基本满足项目要求:

常用的属性:InnerHtml  InnerText   OuterHtml

            /// <summary>
        /// 通过Stream流下载Html源码
        /// </summary>
        /// <param name="Url"></param>
        /// <returns></returns>
        public static string DownLoadHtmlCode(string Url)
        {
            string HtmlCode = "";
            if (string.IsNullOrEmpty(Url)) return "";
            WebClient client = new WebClient();
            Stream stream=  client.OpenRead(Url);
            StreamReader sr = new StreamReader(stream);
            HtmlCode = sr.ReadToEnd();
            sr.Close();
            stream.Close();
            client.Dispose();
            return HtmlCode;

        }

HtmlAgilityPack.HtmlDocument hd = new HtmlAgilityPack.HtmlDocument();
                    //加载Html文档
                     hd.LoadHtml(DownLoadHtmlCode("http://www.baidu.com"));

//以下是从代码里面截取部分信息

HtmlNode strHtml = null;
foreach (var item in hd.DocumentNode.SelectNodes("//*[@id=‘header‘]"))
{
//解析品牌
strHtml = HtmlNode.CreateNode(item.OuterHtml);
Project.Brand = strHtml.SelectSingleNode("//a[last()-1]").InnerText.Replace("移动手机", "").Replace("手机", "") + "<br/>";
}

3、删除样式、脚本、脚本注释

从密密麻麻的源码中查找有效的源码信息,删除样式、脚本、脚本注释,解析获取innerHtml,装载到泛型变量,进行二次操作(输出页面、数据库存储)

  //去掉脚本标签和内容
                if (hd.DocumentNode.SelectNodes("//script")!=null)
                {
                    foreach (var script in hd.DocumentNode.SelectNodes("//script"))
                        script.Remove();
                }

                //去掉样式标签和内容
                if (hd.DocumentNode.SelectNodes("//style")!=null)
                {
                    foreach (var style in hd.DocumentNode.SelectNodes("//style"))
                        style.Remove();
                } 

                //去掉注释标签和内容
                if (hd.DocumentNode.SelectNodes("//comment()")!=null)
                {
                    foreach (var comment in hd.DocumentNode.SelectNodes("//comment()"))
                        comment.Remove();//新增的代码
                }

总结:

HtmlAgilityPack 工具能够快速上手,而且是开源的,能够满足解析Html源码需求。

HtmlAgilityPack --解析Html源码

时间: 2024-10-06 12:49:44

HtmlAgilityPack --解析Html源码的相关文章

GlusterFS源码解析 —— GlusterFS 源码安装

安装环境: CentOS6.2 glusterfs-3.4.3 GlusterFS 挂载需要 fuse 支持,如果你的内核版本低于 2.6.16 则需要下载fuse的源码包自行编译安装,也可下载 fuse 的rpm包.安装fuse的方法我就不说了,不会源码安装的直接去rpmfind.net上下载rpm即可.高于此版本的内核中已经有了fuse.ko的模块,需要的时候可以执行以下命令进行加载: modprobe -b fuse 1.下载GlusterFS的源码包,目前已经有更新版本 : wget h

Android中图片加载框架Glide解析2----从源码的角度理解Glide的执行流程

转载地址:http://blog.csdn.net/guolin_blog/article/details/53939176 在本系列的上一篇文章中,我们学习了Glide的基本用法,体验了这个图片加载框架的强大功能,以及它非常简便的API.还没有看过上一篇文章的朋友,建议先去阅读 Android图片加载框架最全解析(一),Glide的基本用法 . 在多数情况下,我们想要在界面上加载并展示一张图片只需要一行代码就能实现,如下所示: Glide.with(this).load(url).into(i

Python解析器源码加密系列之(二):一次使用标准c的FILE*访问内存块的尝试

摘要:由于近期打算修改Python解释器以实现pyc文件的加密/解密,出于保密的要求,解密之后的数据只能放在内存中,不能写入到文件中.但是后续的解析pyc文件的代码又只能接受FILE*作为入参,所以就提出了一种把通过FILE*来访问内存的需求,下文是针对这个需求的几个方面的尝试及其结论. 以下尝试的前提是:Win7 + VS2010. 在vc中,FILE其实就是_iobuf,定义如下: struct _iobuf { char *_ptr; //文件输入的下一个位置 int _cnt; //当前

用Beautiful Soup解析html源码

#xiaodeng #python3 #用Beautiful Soup解析html源码 html_doc = """ <html> <head> <title>The Dormouse's story</title> </head> <body> <b>测试</b> <p class="title"> <b>The Dormouse's

EventBus框架原理解析(结合源码)(下)

上一篇文章EventBus框架原理解析(结合源码)(上),给大家讲述了EventBus中实体类的封装和register()的具体代码. 接下来我们看另外一个重要方法post(),这个方法显然是要根据传入的参数类型,从subscriptionsByEventType取出对应的subscription /** Posts the given event to the event bus. */ public void post(Object event) {//event就是参数 PostingTh

C语言解析JSON源码

2020-01-09 关键字:cJSON.linux JSON解析 JSON 是一种在互联网领域内很常用的轻量级数据交换协议. 它与 XML 的地位差不多,但就笔者而言,笔者更喜欢 JSON 的风格,因为它更符合我们的思维习惯,同样一份数据,JSON 格式的就是比 XML 要清晰明了一些. 最近笔者需要在 C语言 上解析 JSON 格式,在网上一顿找,找到一份很不错的开源代码.经过一阵研究与修改以后,终于变成了让笔者用的很顺手的 C语言 版 JSON 解析器. 现将这份经笔者小小修改过的代码记录

Android应用setContentView与LayoutInflater加载解析机制源码分析

[工匠若水 http://blog.csdn.net/yanbober 转载烦请注明出处,尊重分享成果] 1 背景 其实之所以要说这个话题有几个原因: 理解xml等控件是咋被显示的原理,通常大家写代码都是直接在onCreate里setContentView就完事,没怎么关注其实现原理. 前面分析<Android触摸屏事件派发机制详解与源码分析三(Activity篇)>时提到了一些关于布局嵌套的问题,当时没有深入解释. 所以接下来主要分析的就是View或者ViewGroup对象是如何添加至应用程

浩哥解析MyBatis源码(十一)——Parsing解析模块之通用标记解析器(GenericTokenParser)与标记处理器(TokenHandler)

原创作品,可以转载,但是请标注出处地址:http://www.cnblogs.com/V1haoge/p/6724223.html 1.回顾 上面的几篇解析了类型模块,在MyBatis中类型模块包含的就是Java类型与Jdbc类型,和其间的转换处理.类型模块在整个MyBatis功能架构中属于基础组件之一,是提前注册到注册器中,并配置到Configuration中备用. 从这一篇开始解析Parsing解析模块,这个模块不同于Type模块,这个模块更像是一套工具模块.本篇先解析通用标记解析器Gene

修改Flume-NG的hdfs sink解析时间戳源码大幅提高写入性能

转自:http://www.cnblogs.com/lxf20061900/p/4014281.html Flume-NG中的hdfs sink的路径名(对应参数"hdfs.path",不允许为空)以及文件前缀(对应参数"hdfs.filePrefix")支持正则解析时间戳自动按时间创建目录及文件前缀. 在实际使用中发现Flume内置的基于正则的解析方式非常耗时,有非常大的提升空间.如果你不需要配置按时间戳解析时间,那这篇文章对你用处不大,hdfs sink对应的解