HtmlAgilityPack 总结(一)
一个解析html的C#类库HtmlAgilityPack,
HtmlAgilityPack是一个基于.Net的、第三方免费开源的微型类库,主要用于在服务器端解析html文档(在B/S结构的程序中客户端可以用Javascript、jquery解析html)。截止到本文发表时,HtmlAgilityPack的最新版本为 1.4.6。下载地址:http://htmlagilitypack.codeplex.com/。最新版本支持Linq to Objects ( LINQ to Xml ).
准备:
如果你有安装Nuget的话,可以直接查找安装即可。
下载后解压缩后有3个文件,这里只需要将其中的HtmlAgilityPack.dll(程序集)、HtmlAgilityPack.xml(文档,用于Visual Studio 2008中代码智能提示和帮助说明之用)引入解决方案中即可使用,无需安装任何东西,非常好用。
在C#类文件开头引入using HtmlAgilityPack;就可以使用该命名空间下的类型了。实际使用中,几乎都是以HtmlDocument类为主线的,这一点非常类似于微软.net framework中的XmlDocument类。XmlDocument类是操作的是xml文档,而HtmlDocument类操作的是html文档(其实也可以操作xml文档),它们的操作方式都是基于Dom,所不同的是后者取消了诸如GetElementsByTagName这样的方法,强化了GetElementById方法(在HtmlDocument中可以直接使用,而XmlDocument则不可以)。
HtmlAgilityPack中定位节点基本上都用Xpath表达式,Xpath表达式的参考文档可见:http://www.w3school.com.cn/xpath/xpath_syntax.asp。自行学习。
不过可以先用几个简单就可以。比如,我们用到最多可能就是针对某个元素(div)、或者某个class属性的div、或者某个id的div,或者以什么开头的div,
类似这样的Xpath还是比较简单的。
Xpath举几个例子,下面的代码中我们就会用到:
"//comment()"在XPath中表示“所有注释节点”
1、获取网页title:doc.DocumentNode.SelectSingleNode("//title").InnerText;
解释:XPath中“//title”表示所有title节点。SelectSingleNode用于获取满足条件的唯一的节点。
2、获取所有的超链接:doc.DocumentNode.Descendants("a")
3、获取name为kw的input,也就是相当于getElementsByName():
var kwBox = doc.DocumentNode.SelectSingleNode("//input[@name='kw']");
解释:"//input[@name='kw']"也是XPath的语法,表示:name属性等于kw的input标签。
//li/h3/a[@href]:所有li下面的h3包含a超级链接有href属性才符合。有的a可能是支持的js事件
//div[starts-with(@class,'content_single')]:所有符合条件的div,并且它的class是由字符串content_single 开头的。
//标示获取documet下的所有符合条件。/div标示从根目录开始的符合条件的。
以上是准备工作。下面说一下HtmlAgilityPack读取web页面,并解析的方法步骤。
1.读取url:
HtmlAgilityPack.HtmlWeb hw = new HtmlAgilityPack.HtmlWeb();
HtmlAgilityPack.HtmlDocument doccc = hw.Load(url);//是你需要解析的url
ArrayList ImagePtahs = GetHrefs(doccc);
这里可能会遇到2个问题。
一个是编码问题,一个是gzip不支持的问题。
首先编码问题解决办法:就是不用HtmlAgilityPack去获取Url的data数据,自己获取了。大家可能就问了:我自己获取了他不给我解析那?
没事,他不会那么笨的。谁的肉不是吃啊?
方法如下:
WebProxy proxyObject = new WebProxy(IP, port);//这里我是用的代理。
//向指定地址发送请求
HttpWebRequest HttpWReq = (HttpWebRequest)WebRequest.Create(url);
HttpWReq.Proxy = proxyObject;
HttpWReq.Timeout = 10000;
HttpWebResponse HttpWResp = (HttpWebResponse)HttpWReq.GetResponse();
StreamReader sr = new StreamReader(HttpWResp.GetResponseStream(), System.Text.Encoding.GetEncoding("UTF-8"));
//注意上面的编码了吗??
HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();
doc.Load(sr);
int res = CheckIsGoodProxy(doc); //这是我解析的函数,还没到那一步。不解释了。
sr.Close();
HttpWResp.Close();
HttpWReq.Abort();
另一个问题就是很奇怪了。gzip的问题开启了gzip压缩的网页请求时会报错。报错信息为“gzip”不是受支持的编码名。
在谷歌上搜索了半天,终于找到解决方案,而且不必更换HttpRequest或WebClient进行请求。同时还可以用此方法设置cookie,render伪装等等。。。
解决后代码如下:在你发起请求的是修改一下。
HtmlWeb webClient = new HtmlWeb();
HtmlAgilityPack.HtmlWeb.PreRequestHandler handler = delegate(HttpWebRequest request)
{
request.Headers[HttpRequestHeader.AcceptEncoding] = "gzip, deflate";
request.AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip;
request.CookieContainer = new System.Net.CookieContainer();
return true;
};
webClient.PreRequest += handler;
HtmlDocument doc = webClient.Load(this.getUrl());
可能最新版本的HtmlAgilityPack会修复这个问题吧。期待中。
2.用Xpath解析。
这一步就比较简单了。就用Xpath选出你想要的数据,遍历他们,取出他们的value即可。
实例代码:
private ArrayList GetHrefs(HtmlAgilityPack.HtmlDocument _doc)
{
try
{
Images = new ArrayList();
HtmlNodeCollection hrefs = _doc.DocumentNode.SelectNodes("//li/h3/a[@href]");
HtmlNodeCollection hrefs2 = _doc.DocumentNode.SelectNodes("//div[starts-with(@class,'content_single')]");
if (hrefs == null)
return new ArrayList();
foreach (HtmlNode href in hrefs)
{
// Images.Add(href.Attributes["src"].Value);
string hreff = href.Attributes["href"].Value;// 排除 博海拾贝第二百零二期】吃完薯条寂寞了
string title = href.Attributes["title"].Value;
if (title.IndexOf("邪恶") >= 0)
{
continue;
}
if (title.IndexOf("恶搞") >= 0)
{
continue;
}
if (title.IndexOf("雷人") >= 0)
{
continue;
}
///执行数据保存的逻辑
}
}
catch (Exception ex)
{
ShowLogMsg("出错了:"+ex.Message+ex.StackTrace);
return new ArrayList();
}
}
每一个Htmlnode,你要获取他的数据用这个方法: img.Attributes["src"].Value
整个过程就是这样的简单。大家有不明白或者有问题可以留言交流。
HtmlAgilityPack 总结(一)的更多相关文章
- C#+HtmlAgilityPack+XPath带你采集数据(以采集天气数据为例子)
第一次接触HtmlAgilityPack是在5年前,一些意外,让我从技术部门临时调到销售部门,负责建立一些流程和寻找潜在客户,最后在阿里巴巴找到了很多客户信息,非常全面,刚开始是手动复制到Excel, ...
- 用WebRequest +HtmlAgilityPack 从外网抓取数据到本地
相信大家对于WebRequest 并不陌生,我们在C#中发请求的方式,就是创建一个WebRequest .那么如果我们想发一个请求到外网,比如国内上不了的一些网站,那么该怎么做呢? 其实WebRequ ...
- 【C#】获取网页内容及HTML解析器HtmlAgilityPack的使用
最近经常需要下载一些东西,而这个下载地址又会经过层层跳转,每个页面上都有很多广告,烦不胜烦,所以做了一个一键获得最终下载地址的小工具.使用C#,来获取网页内容,然后通过HtmlAgilityPack获 ...
- 爬虫技术 -- 进阶学习(十)网易新闻页面信息抓取(htmlagilitypack搭配scrapysharp)
最近在弄网页爬虫这方面的,上网看到关于htmlagilitypack搭配scrapysharp的文章,于是决定试一试~ 于是到https://www.nuget.org/packages/Scrapy ...
- 黄聪:C#类似Jquery的html解析类HtmlAgilityPack基础类介绍及运用
Html Agility Pack下载地址:http://htmlagilitypack.codeplex.com/ Html Agility Pack 源码中的类大概有28个左右,其实不算一个很复杂 ...
- HTML解析器HtmlAgilityPack的一些使用总结(C#)
哎~本来这些总结是作为使用时的快速备注,但是用不上了.实际应用当中HtmlAgilityPack的可靠性不太稳定,一主要问题是:-> 一些字符会出现乱码或者变成'?',如韩语字符.由于我是已经有 ...
- 2012-09-10 23:30 如何解决HtmlAgilityPack得到的InnerText中有残留的script、样式的问题
那么如何解决HtmlAgilityPack得到的InnerText中有残留的script.样式的问题呢,在google上搜索“HtmlAgilityPack script innerText”找到了s ...
- HtmlAgilityPack组件
HtmlAgilityPack组件用于解析Html字符串,一个典型的应用场景是用于网页爬虫. 示例程序 using Common.Tools; using Datebase.Entity; using ...
- 使用HtmlAgilityPack解析Html(非常好用)
/// <summary> /// 设计成一个exe,解决WebBrowser控件内存泄漏的问题. /// </summary> public partial class Ma ...
- HtmlAgilityPack中通过sibling才能得到对应的InnerText和form,option等tag的子节点
[背景] 之前使用HtmlAgilityPack期间,遇到了2个bug: 1. InnerText没有包含对应字符串(但是用NextSibling.InnerText却可以得到) 对于html: ? ...
随机推荐
- adb连接不上手机
昨天电脑重装了系统,今天打开之前的eclips工作环境,点击run as -> android application,一直报各种诡异的错误,总之就是连接不上手机. 其中包括 Adb conne ...
- Winform合并多个Excel文件到一个文件中(源文件.xls,实际是.xml)
1.下面两个文件.xls是给的文件,实际上是.xml文件 2.具体的代码 private void btOK_Click(object sender, EventArgs e) { //0.获取路径文 ...
- CSS居中的实现用法实例
转载的一篇文章,讲解css内容居中的. 网上有关css 居中的文章不胜枚举,不过大多没有做系统的总结.这里分享的这篇有关css居中的文章,个人感觉不错,值得收藏. 一.水平居中1,将元素水平居中(us ...
- delphi图形图像开发相关
①delphi的图形处理(doc) http://wenku.baidu.com/view/519df09951e79b89680226ee.html ②delphi的图形图像处理(ppt) http ...
- Python开发【第一篇】Python基础之自定义模块和内置模块
为什么要有模块,将代码归类.模块,用一砣代码实现了某个功能的代码集合. Python中叫模块,其他语言叫类库. 类似于函数式编程和面向过程编程,函数式编程则完成一个功能,其他代码用来调用即可,提供了代 ...
- 用户登录密码RSA加密后传输的实现,非明文密码传输
在用户登录页面,用户输入密码后,在传送到服务器端时,为防止在密码传送过程中,被如360这种东东给拦截到, 需要在传送前对密码进行加密,然后再传送! 利用RSA加密,在客户端使用公钥对密码进行加密,在服 ...
- nginx搭建流媒体服务器的方法详解
一.FLV视频发布方式简介 FLV视频有两总发布方式 1. HTTP方式 这种方式要下载FLV视频文件到本地播放,一旦FLV视频文件下载完成,就不会消耗服务器的资源和带宽,但是拖动功能没有RTM ...
- scanf gets fgets区别与联系 puts fputs printf区别与联系
组一:scanf( )函数 gets( )函数 fgets()函数都可用于输入字符串, 组二:printf( )函数 puts( )函数 fputs()函数则用于字符串的输出. 两组内部函数各有 ...
- ASP.NET MVC +EasyUI 权限设计(四)角色动作
请注明转载地址:http://www.cnblogs.com/arhat 由于最近的事情比较多,一直忙于工作和照顾老婆,所以老魏更新的速度慢了,本来写文章就要占据工作和生活很多的时间,这也就是院子中很 ...
- Spiral Matrix
Spiral Matrix Given a matrix of m x n elements (m rows, n columns), return all elements of the matri ...