C# 网络爬虫利器之Html Agility Pack如何快速实现解析Html

简介

  现在越来越多的场景需要我们使用网络爬虫,抓取相关数据便于我们使用,今天我们要讲的主角Html Agility Pack是在爬取的过程当中,能够高效的解析我们抓取到的html数据。

优势

  在.NET技术下,解析html工具也很多,比如很多人可能会使用htmlparser,或者微软的MSHTML,htmlparser虽然比较易上手,但是相对应的解析速度较慢,而Html Agility Pack解析速度相当快,并且开源,易用,它可以帮助我们解析html文档就像用XmlDocument类来解析xml一样轻松、方便。

  传送门:官网地址Github开源代码地址

方法介绍

  其实Html Agility Pack的类不是很多,我们解析Html的时候,用到的也就HtmlDocument和HtmlNode(还有HtmlNodeCollection集合类)这几个类。官网也有相对应的API文档说明,其实真的是简单易懂,传送门:API文档

Question 1、如何加载Html?

  HtmlDocument类定义; 多个重载Load方法来实现不同方式的Html加载,主要常见的有三种方式;从文件加载、从字符串加载、从网页链接加载。

  示例:

 1 // 从物理路径的文件加载
 2 var doc = new HtmlDocument();
 3 doc.Load(filePath);//文件路径
 4
 5 // 从Stream当中加载
 6 var doc = new HtmlDocument();
 7 doc.LoadHtml(html);
 8
 9 // 从网页的Url链接加载
10 var url = "http://www.cnblogs.com/xuliangxing/";
11 var web = new HtmlWeb();
12 var doc = web.Load(url);

  以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)

 Question 2、如何精准定位到我们需要的数据

  这个时候我们需要用到HtmlNodeCollection和HtmlNode这两个类,我们把Html每个标签看作一个Node,所有我们想到定位到某个标签的内容,就需要知道这个标签的相关属性。顺便说一下,HtmlNode类实现了IXPathNavigable接口,这说明了它可以通过xpath来定位数据了,如果你对解析XML格式数据的XmlDocument类了解的话,特别是使用过了SelectNodes()和SelectSingleNode()方法的人来说,对使用HtmlNode类将会很熟悉。其实Html Agility Pack内部是把html解析成xml文档格式了的,所以支持xml中的一些常用查询方式。下面通过简单示例对HtmlNode的一些主要的常用成员作简要的说明。

  就以我博客园主页为例,希望大家在此基础上能够举一反三,这里只做抛砖引玉,界面图如下:

  后台Html代码,我抓取了部分代码拿来做示例

 1 <!DOCTYPE html>
 2 <html lang="zh-cn">
 3 <head>
 4 <meta charset="utf-8"/>
 5 <meta name="viewport" content="width=device-width, initial-scale=1" />
 6 <title>法号阿兴 - 博客园</title>
 7 </head>
 8 <body>
 9 <div id="home">
10 <div id="header">
11     <div id="blogTitle">
12     <a id="lnkBlogLogo" href="http://www.cnblogs.com/xuliangxing/"><img id="blogLogo" src="/Skins/custom/images/logo.gif" alt="返回主页" /></a>
13     <h1><a id="Header1_HeaderTitle" class="headermaintitle" href="http://www.cnblogs.com/xuliangxing/">法号阿兴</a></h1>
14     <h2>你的能力还驾驭不了你的目标时,就应该沉下心来历练</h2>
15     </div>   <!--end: blogTitle 博客的标题和副标题 -->
16     <div id="navigator">
17 <ul id="navList">
18     <li><a id="blog_nav_sitehome" class="menu" href="http://www.cnblogs.com/">博客园</a></li>
19     <li><a id="blog_nav_myhome" class="menu" href="http://www.cnblogs.com/xuliangxing/">首页</a></li>
20     <li><a href="http://news.cnblogs.com/">新闻</a></li>
21     <li><a id="blog_nav_newpost" class="menu" rel="nofollow" href="https://i.cnblogs.com/EditPosts.aspx?opt=1">新随笔</a></li>
22     <li><a id="blog_nav_contact" accesskey="9" class="menu" rel="nofollow" href="https://msg.cnblogs.com/send/%E6%B3%95%E5%8F%B7%E9%98%BF%E5%85%B4">联系</a></li>
23     <li><a id="blog_nav_admin" class="menu" rel="nofollow" href="https://i.cnblogs.com/">管理</a></li>
24     <li><a id="blog_nav_rss" class="menu" href="http://www.cnblogs.com/xuliangxing/rss">订阅</a>
25     <a id="blog_nav_rss_image" class="aHeaderXML" href="http://www.cnblogs.com/xuliangxing/rss"><img src="//www.cnblogs.com/images/xml.gif" alt="订阅" /></a></li>
26 </ul>
27 </div><!--end: header 头部 -->
28 <div id="main"></div><!--end: 正文 -->
29 <div id="footer"></div><!--end: 底部 -->
30 </div>
31 </body>
32 </html>

  一般Html最常见的是div标签元素,它可能会定义一些属性,比例本文当中的<div id="blogTitle">,有些不是id属性,是class属性,这个根据实际情况而定,要灵活变通

(1)通过ID属性(或者其他属性)来选择对应的节点

  通用格式:@id=‘xxxx’(id可以是其他属性等等),比如我们要定位到本文博客主页的标题和副标题内容。

1 HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();
2 doc.LoadHtml(url)//博客主页URL
3 //下面的意思是:通过属性id的值,来定位header下的blogTitle节点信息
4 HtmlNode titleNode = doc.DocumentNode.SelectSingleNode("//div[@id=‘header‘]/div[@id=‘blogTitle‘]");

  我们还可以不通过属性id去定位,还有通过索引去定位,如下所示,这个效果和上面是等同的:

1 //下面的意思是:通过索引定位,div[2]是表示根节点的第二个
2 HtmlNode titleNode = doc.DocumentNode.SelectSingleNode("//div[2]/div[1]");

  备注:注意路径里"//"表示从根节点开始查找,两个斜杠‘//’表示查找所有childnodes;一个斜杠‘/‘表示只查找第一层的childnodes(即不查找grandchild);点斜杠"./"表示从当前结点而不是根结点开始查找。我们接着上面titleNode节点,查找我博客园的ID。

1 //下面的意思是:通过当前titleNode节点,获取便签h1的节点
2 HtmlNode IDNode = titleNode.SelectSingleNode("./h1");

  讲解了上面这些,大家应该已经能够明白了Html Agility Pack的基本使用方法,那么如何一次性获取博主的ID呢?

1 HtmlNode IDNode = doc.DocumentNode.SelectSingleNode("//div[@id=‘header‘]/div[@id=‘blogTitle‘]/h1");

(2)如何获取节点文本内容

  接着上面(1)所说的,通过代码“HtmlNode IDNode = doc.DocumentNode.SelectSingleNode("//div[@id=‘header‘]/div[@id=‘blogTitle‘]/h1") ”获取到了IDNode的节点,那么接下来,我们需要这么获取具体的文本值呢(即博主ID)?有三种方式获取OuterHtml,InnerHtml和InnerText。

  HtmlNode类设计了OuterHtml属性和InnerHtml属性用于获取当前节点的Html源码。两者不同之处是,OuterHtml属性返回的是包含当前节点的Html代码在内的所有Html代码,而InnerHtml属性返回的是当前节点里面子节点的所有Html代码,InnerText属性过滤掉了所有的Html标记代码,只返回文本值。具体用哪种方式,要根据我们实际情况而定,一般InnerHtml和InnerText使用的频率比较多。如下所示:

1 //我们获取博客ID
2 IDNode.OuterHtml ///返回结果是:<h1><a id="Header1_HeaderTitle" class="headermaintitle" href="http://www.cnblogs.com/xuliangxing/">法号阿兴</a></h1>
3 IDNode.InnerHtml ///返回结果是:<a id="Header1_HeaderTitle" class="headermaintitle" href="http://www.cnblogs.com/xuliangxing/">法号阿兴</a>
4 IDNode.InnerText ///返回结果是:法号阿兴

(3)如何获取节点属性值

  假如我们上面Html数据当中,博主博客地址,在标签<div id="header">里的<a>标签里,这个时候就需要使用HtmlNode下的Attribute属性了。

1 string url = doc.DocumentNode.SelectSingleNode("//div[@id=‘header‘]/div[@id=‘blogTitle‘]/a").Attributes["href"].Value;

(4)如何获取某个标签的所有节点

  我们如果获取前面Html数据的li所有分类,这个时候需要使用方法SelectNodes了

HtmlNodeCollection uiListNodes = doc.DocumentNode.SelectNodes("//ui[@id=‘navList‘]/li");

 Question 3、Html Agility Pack进行删除操作

  Html Agility Pack是可以对Html做删除操作的,具体的可以参考官网的API,这里我们讲下最常见

(1)如何去掉外层的html tag只留下文本内容

  回到我们刚刚上面讲到的地方,用remove方法。假设要删除上文结点<a id="Header1_HeaderTitle" class="headermaintitle" href="http://www.cnblogs.com/xuliangxing/">法号阿兴</a>,你想留下博客名称而不要<a></a>的话,那你需要先得到这个Html结点,通过remove方法删除掉多余的HTML Tag假设该节点叫Node:

Node.ParentNode.RemoveChild(Node,true); 

  参数true表示留下grandchild,在这里即博主博客ID内容; false表示将此结点连同其grandchilds一起删除。

  更多的方法大家可以到官网的API文档进行了解,这里就不做更多的说明。

 PS:如有疑问,请留言,未经允许,不得私自转载,转载请注明出处:http://www.cnblogs.com/xuliangxing/p/8004403.html

时间: 2024-10-07 14:30:42

C# 网络爬虫利器之Html Agility Pack如何快速实现解析Html的相关文章

开源项目Html Agility Pack实现快速解析Html

[转]开源项目Html Agility Pack实现快速解析Html 这是个很好的的东西,以前做Html解析都是在用htmlparser,用的虽然顺手,但解析速度较慢,碰巧今天找到了这个,就拿过来试,一切出乎意料,非常爽,推荐给各位使用. 下面是一些简单的使用技巧,希望对大家有用,我个人也是个学习过程. Why Html Agility Pack? (以下简称HAP) .Net下解析HTML文件有很多种选择,包括微软自己也提供MSHTML用于manipulate HTML文件.但是,经过我一段时

HTML Agility Pack 搭配 ScrapySharp,彻底解除Html解析的痛苦(转)

自从 Web 应用程序自 1993 年 W3C 设立以来就开始发展,而且 HTML 也历经了数个版本的演化(1.0 – 2.0 – 3.0 – 3.2 – 4.0 – 4.01),现在也已经成为Web网页或应用程序的最基础,想要学习如何设计 Web 网页或开发 Web 应用程序,这已经是绝对必须要学的东西了,就算是方便的控件(例如 ASP.NET),但 HTML 仍然有学习它的必要性,因此如果不会 HTML,就等于没学过 Web 网页一般. 拜 HTML 与 Web 浏览器蓬勃发展之赐,各式各样

网络爬虫:使用多线程爬取网页链接

前言: 经过前面两篇文章,你想大家应该已经知道网络爬虫是怎么一回事了.这篇文章会在之前做过的事情上做一些改进,以及说明之前的做法的不足之处. 思路分析: 1.逻辑结构图 上图中展示的就是我们网络爬虫中的整个逻辑思路(调用Python解析URL,这里仅仅作了简略的展示). 2.思路说明: 首先.我们来把之前思路梳理一下.之前我们採用的两个队列Queue来保存已经訪问过和待訪问的链接列表,并採用广度优先搜索进行递归訪问这些待訪问的链接地址.并且这里使用的是单线程操作. 在对数据库的操作中.我们加入了

打造一个健壮高效的网络爬虫

以下内容转自爬虫界大佬崔庆才的文章,传送门 整个分享的主题叫做<健壮高效的网络爬虫>,本次分享从抓取.解析.存储.反爬.加速五个方面介绍了利用 Python 进行网络爬虫开发的相关知识点和技巧,介绍了不同场景下如何采取不同措施高效地进行数据抓取的方法,包括 Web 抓取.App 抓取.数据存储.代理选购.验证码破解.分布式抓取及管理.智能解析等多方面的内容,另外还结合了不同场景介绍了常用的一些工具包,全部内容是我在从事网络爬虫研究过程以来的经验精华总结. 爬取 对于爬取来说,我们需要学会使用不

网络爬虫----男!生!福!利!

一.配置mvn依赖 <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> <version>4.1.2</version> </dependency> 二.代码 1.获取网页内容 package com.chenanyi.fuli.Helper; import java.io.I

一款很不错的html转xml工具-Html Agility Pack 实现html转Xml

[转]一款很不错的html转xml工具-Html Agility Pack 之前发个一篇关于实现html转成xml的劣作<实现html转Xml>,受到不少网友的关心.该实现方法是借助htmlparser去分解html内容,然后按照dom的结构逐个生成xml字符串.在没有充分实践后,还以为该方案能解决问题.然而经过实际使用,效率确实很低,而且对一些特殊html属性的转换也不支持,得到的结果差强人意. 偶然一次机会在浏览codeplex网站时,发现一款很不错的html解析以及转换工具,就是本篇标题

一款很不错的html转xml工具-Html Agility Pack

之前发个一篇关于实现html转成xml的劣作<实现html转Xml>,受到不少网友的关心.该实现方法是借助htmlparser去分解html内容,然后按照dom的结构逐个生成xml字符串.在没有充分实践后,还以为该方案能解决问题.然而经过实际使用,效率确实很低,而且对一些特殊html属性的转换也不支持,得到的结果差强人意. 偶然一次机会在浏览codeplex网站时,发现一款很不错的html解析以及转换工具,就是本篇标题所提到的Html Agility Pack.Html Agility Pac

[c#] Html Agility Pack 解析HTML

摘要 在开发过程中,很有可能会遇到这样的情况,服务端返回的是html的内容,但需要在客户端显示纯文本内容,这时候就需要解析这些html,拿到里面的纯文本.达到这样的目的可以有很多途径,比如自己写正则表达式,但对于没有什么规则的内容,就有点力不从心了.Html Agility Pack开源组件,可以通过xPath的方式快速的解析html内容. 一个例子 组件网址:http://htmlagilitypack.codeplex.com/ ,你可以通过Nuget进行安装. 比如我们这里解析博客园首页文

Python3网络爬虫(七):使用Beautiful Soup爬取小说

转载请注明作者和出处:http://blog.csdn.net/c406495762 运行平台: Windows Python版本: Python3.x IDE: Sublime text3 一.Beautiful Soup简介 简单来说,Beautiful Soup是python的一个库,最主要的功能是从网页抓取数据.官方解释如下: Beautiful Soup提供一些简单的.python式的函数用来处理导航.搜索.修改分析树等功能.它是一个工具箱,通过解析文档为用户提供需要抓取的数据,因为简