【.NET】使用HtmlAgilityPack抓取网页数据

简介: 原文:【.NET】使用HtmlAgilityPack抓取网页数据 刚刚学习了XPath路径表达式,主要是对XML文档中的节点进行搜索,通过XPath表达式可以对XML文档中的节点位置进行快速定位和访问,html也是也是一种类似于xml的标记语言,但是语法没有那么严谨,在codeplex里有一个开源...

原文:【.NET】使用HtmlAgilityPack抓取网页数据

刚刚学习了XPath路径表达式,主要是对XML文档中的节点进行搜索,通过XPath表达式可以对XML文档中的节点位置进行快速定位和访问,html也是也是一种类似于xml的标记语言,但是语法没有那么严谨,在codeplex里有一个开源项目HtmlAgilityPack提供了用XPath解析HTML文件,下面掩饰如何使用该类库的使用

首先说下XPath路径表达式

XPath路径表达式

  用来选取XML文档中的节点或节点集的

  1、术语:节点(Node):7种类型:元素,属性,文本,命名空间,处理命令,注释,文档(根)节点

  2、节点关系:父(Parent),子(Children),同胞(Sibling),先辈(Ancestor),后代(Descendant)

  3、路径表达式

   nodename  节点名,选取此节点的所有子节点  例: childnode  当前节点中的childnode子节点,不包含孙子及以下的节点

      /     从根节点选取  例:/root/childnode/grandsonnode  

       //     表示所有后代节点  例://childnode    所有名为childnode的后代节点

      .    表示当前节点  例:  ./childnode    表示当前节点的childnode节点

      ..     表示父节点  例:  ../nearnode     表示父亲节点的nearnode子节点

       @    选取属性  /root/childnode/@id     表示childnode的所有含有id属性的节点集

  4、谓语(Predicates)

    谓语可以对节点集进行一些限制,使选择更精确

      /root/book[1]    节点集中的第一个节点

      /root/book[last()]  节点集中最后一个节点

      /root/book[position() - 1]  节点集中倒数第二个节点集

      /root/book[position() < 5]  节点集中前五个节点集

      /root/book[@id]      节点集中含有属性id的节点集

      /root/book[@id='chinese']  节点集中id属性值为chinese的节点集

      /root/book[price > 35]/title  节点集中book的price元素值大于35的title节点集

  5、通配符:XPath路径中同样支持通配符(*,@*,node(), text())

    例:  /bookstore/*

        //title[@*]

  6、XPath轴

    定义相对于当前节点的节点集

      ancestor    所有祖先节点

      attribute    所有属性节点

      child      所有子元素

      descendant  所有后代节点(子,孙。。。)

      following    结束标记后的所有节点      preceding   开始标记前的所有节点

      following-sibling  结束标记后的所有同胞节点

      preceding-sibling  开始标记前的所有同胞节点

      namespace   当前命名空间的所有节点

      parent     父节点

      self       当前节点

    用法:轴名称::节点测试[谓语]

      例:  ancestor::book

            child::text()

  7、运算符

    |  两个节点集的合并  例:/root/book[1] | /root/book[3]

    +,-,*,dev,mod

    =,!=,<,>,<=,>=

    or,and  或和与

 

htmlDoc.DocumentNode.SelectNodes("//div[@ispublished='false' or @ispublished='False']");

 

//Xpath node selection - how to select 2 different elements - htmlagilitypack
//选择两种不同标签的节点

string srxPathOfCategory = "//div[@class='breadcrumbs']//li[@class='product'] | //div[@class='breadcrumbs']//a";
//So for " or " just need to use " | "

  

  

 

    //删除注释,script,style
    node.Descendants()
                .Where(n => n.Name == "script" || n.Name == "style" || n.Name=="#comment")
                .ToList().ForEach(n => n.Remove());


    //遍历node节点的所有后代节点
    foreach(var HtmlNode in node.Descendants())
    {
        
    }

 

 

HtmlAgilityPack类库用法

  1、首先需要获取到html页面数据,可以通过WebRequest类来获取

 

        public static string GetHtmlStr(string url)
        {    
            try
            {
                WebRequest rGet = WebRequest.Create(url);
                WebResponse rSet = rGet.GetResponse();
                Stream s = rSet.GetResponseStream();
                StreamReader reader = new StreamReader(s, Encoding.UTF8);
                return reader.ReadToEnd();
            }
            catch (WebException)
            {
                //连接失败
                return null;
            }
        }

 

  2、通过HtmlDocument类加载html数据

        string htmlstr = GetHtmlStr("http://www.hao123.com");
        HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();
        doc.LoadHtml(htmlstr);
        HtmlNode rootnode = doc.DocumentNode;    //XPath路径表达式,这里表示选取所有span节点中的font最后一个子节点,其中span节点的class属性值为num
        //根据网页的内容设置XPath路径表达式
        string xpathstring = "//span[@class='num']/font[last()]";    
        HtmlNodeCollection aa = rootnode.SelectNodes(xpathstring);    //所有找到的节点都是一个集合
        
        if(aa != null)
        {
            string innertext = aa[0].InnerText;
            string color = aa[0].GetAttributeValue("color", "");    //获取color属性,第二个参数为默认值
            //其他属性大家自己尝试
        }

  也可以通过HtmlWeb类来获得HtmlDocument

        HtmlWeb web = new HtmlWeb();
        HtmlAgilityPack.HtmlDocument doc = web.Load(url);
        HtmlNode rootnode = doc.DocumentNode;

 

补充:

  多个属性条件查询      //div[@align='center' and @height='24']

  不存在class属性       //div[not(@class)]

提取的时候需要判断是这个标签的class属性是否包含某个指定的属性值,google了一下(百度搜索没有相应的结果),利用Xpath的contains可以解决,代码如下:

另一种解析方式,假如我们需要根据div的class属性是否包含post值来提取div中的InnerText:

可以用以下方法来提取符合条件的所有HtmlNode节点

提取得到节点数据之后,根据实际处理即可。

目录
相关文章
|
4月前
|
SQL XML 关系型数据库
入门指南:利用NHibernate简化.NET应用程序的数据访问
【10月更文挑战第13天】NHibernate是一个面向.NET的开源对象关系映射(ORM)工具,它提供了从数据库表到应用程序中的对象之间的映射。通过使用NHibernate,开发者可以专注于业务逻辑和领域模型的设计,而无需直接编写复杂的SQL语句来处理数据持久化问题。NHibernate支持多种数据库,并且具有高度的灵活性和可扩展性。
69 2
|
6月前
|
开发框架 .NET 数据库连接
闲话 Asp.Net Core 数据校验(三)EF Core 集成 FluentValidation 校验数据例子
闲话 Asp.Net Core 数据校验(三)EF Core 集成 FluentValidation 校验数据例子
113 1
|
7月前
|
开发框架 JSON 前端开发
利用查询条件对象,在Asp.net Web API中实现对业务数据的分页查询处理
利用查询条件对象,在Asp.net Web API中实现对业务数据的分页查询处理
|
6月前
|
开发框架 前端开发 算法
分享 .NET EF6 查询并返回树形结构数据的 2 个思路和具体实现方法
分享 .NET EF6 查询并返回树形结构数据的 2 个思路和具体实现方法
109 0
|
6月前
|
机器学习/深度学习 前端开发 API
Gradio.NET:一个快速制作演示demo网页的利器
Gradio.NET:一个快速制作演示demo网页的利器
132 0
|
8月前
|
数据采集 安全 C#
.NET快速实现网页数据抓取
今天我们来讲讲如何使用.NET开源(MIT License)的轻量、灵活、高性能、跨平台的分布式网络爬虫框架DotnetSpider来快速实现网页数据抓取功能。
|
9月前
|
存储 测试技术 计算机视觉
高维数据惩罚回归方法:主成分回归PCR、岭回归、lasso、弹性网络elastic net分析基因数据
高维数据惩罚回归方法:主成分回归PCR、岭回归、lasso、弹性网络elastic net分析基因数据
|
2月前
|
监控 前端开发 API
一款基于 .NET MVC 框架开发、功能全面的MES系统
一款基于 .NET MVC 框架开发、功能全面的MES系统
|
5月前
|
开发框架 前端开发 JavaScript
ASP.NET MVC 教程
ASP.NET 是一个使用 HTML、CSS、JavaScript 和服务器脚本创建网页和网站的开发框架。
64 7

热门文章

最新文章