网页采集(通过HtmlAgilityPack+XPath)
有HtmlAgilityPack这个类库可以更方便地对HTML内容进行分析和提取。因此今天特别学习和实践了一下HtmlAgilityPack和XPath,并作下笔记。
1.下载HtmlAgilityPack.dll并将其添加引用到项目中,然后在代码中声明引用。
下载地址:http://www.codeplex.com/htmlagilitypack
引用:
using HtmlAgilityPack;
2.下载获取HTML页面的步骤和我上篇文章里介绍的差不多,都是先用WebClient或者WebRequest类来下载HTML页面然后处理成字符串。
3.与上次不同的是,这里分析和抓取HTML节点中的数据不再是之前那种STRING字符串操作的方式,而是封装成一个HtmlDocument对象,通过HtmlDocument中的方法来索引你需要抓取HTML节点,进而取出节点中的值。
4.若需要抓取的节点有ID,类似“<div id='post_list'>value</div>”这种,那很简单只需调用GetElementbyId方法根据节点ID即可获取所需节点。从而通过HtmlNode中的InnerText或Attribute属性来获取你想要的值。
CODE:

//实例化HtmlAgilityPack.HtmlDocument对象
HtmlDocument doc = new HtmlDocument();
//载入HTML
doc.LoadHtml(mainData);
//根据HTML节点NODE的ID获取节点
HtmlNode navNode = doc.GetElementbyId("post_list");

5.但很多情况下HTML节点是没有ID的,那就需要通过XPATH语言来查找匹配所需节点(XPath教程)。以抓取博客园首页文章为例,通过查看博客园HTML可以发现博客园首页里的文章列表都是放在一个ID为"post_list"的"<div>"节点中的。

这样的话就可以通过调用GetElementbyId方法来定位到这个节点了。
6.在获取到"post_list"节点后,接下来就可以调用SelectSingleNode方法通过XPATH表达式来索引出需要抓取的节点,从而抓取到文章的标题和链接地址。
(PS:在博客园首页"post_list"节点里,平均每4个DIV就是一篇新的文章可以利用这一规律遍历出首页所有文章)
CODE:

//实例化HtmlAgilityPack.HtmlDocument对象
HtmlDocument doc = new HtmlDocument();
//载入HTML
doc.LoadHtml(mainData);
//根据HTML节点NODE的ID获取节点
HtmlNode navNode = doc.GetElementbyId("post_list");
//根据XPATH来索引节点
//div[2]表示文章链接a位于post_list里面第3个div节点中
HtmlNode navNode2 = navNode.SelectSingleNode("//div[2]/h3/a");
//获取文章链接地址
string articleTitle = navNode2.Attributes["href"].Value.ToString();
//获取文章标题
string articleName = navNode2.InnerText;

对比一下之前使用string截取字符串的方法:

//以"<a class=\"titlelnk\" href=\""作为抓取点开始采集
mainData=mainData.Substring(mainData.IndexOf("<a class=\"titlelnk\" href=\"") + 26);
//获取文章页面的链接地址
string articleAddr = mainData.Substring(0,mainData.IndexOf("\""));
//获取文章标题
string articleTitle = mainData.Substring(mainData.IndexOf("target=\"_blank\">") + 16,
mainData.IndexOf("</a>") - mainData.IndexOf("target=\"_blank\">") - 16);

可见与之前相比,使用HtmlAgilityPack.HtmlDocument类来实现前台HTML的分析和采集在页面编码和数据分析上面处理更加合理、优化,代码也更加简洁。
xpath路径表达式笔记
作者: 阮一峰
日期: 2009年7月 6日
简单说,xpath就是选择XML文件中节点的方法。
所谓节点(node),就是XML文件的最小构成单位,一共分成7种。
- element(元素节点)
- attribute(属性节点)
- text (文本节点)
- namespace (名称空间节点)
- processing-instruction (处理命令节点)
- comment (注释节点)
- root (根节点)
xpath可以用来选择这7种节点。不过,下面的笔记只涉及最常用的第一种element(元素节点),因此可以将下文中的节点和元素视为同义词。
一、xpath表达式的基本格式
xpath通过“路径表达式”(Path Expression)来选择节点。在形式上,“路径表达式”与传统的文件系统非常类似。
# 斜杠(/)作为路径内部的分割符。
# 同一个节点有绝对路径和相对路径两种写法。
# 绝对路径(absolute path)必须用“/”起首,后面紧跟根节点,比如/step/step/...。
# 相对路径(relative path)则是除了绝对路径以外的其他写法,比如 step/step,也就是不使用“/”起首。
# “.”表示当前节点。
# “..”表示当前节点的父节点
二、选择节点的基本规则
- nodename(节点名称):表示选择该节点的所有子节点
- “/”:表示选择根节点
- “//”:表示选择任意位置的某个节点
- “@”: 表示选择某个属性
三、选择节点的实例
先看一个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>
[例1]
bookstore :选取 bookstore 元素的所有子节点。
[例2]
/bookstore :选取根节点bookstore,这是绝对路径写法。
[例3]
bookstore/book :选取所有属于 bookstore 的子元素的 book元素,这是相对路径写法。
[例4]
//book :选择所有 book 子元素,而不管它们在文档中的位置。
[例5]
bookstore//book :选择所有属于 bookstore 元素的后代的 book 元素,而不管它们位于 bookstore 之下的什么位置。
[例6]
//@lang :选取所有名为 lang 的属性。
四、xpath的谓语条件(Predicate)
所谓“谓语条件”,就是对路径表达式的附加条件。
所有的条件,都写在方括号“[]”中,表示对节点进行进一步的筛选。
[例7]
/bookstore/book[1] :表示选择bookstore的第一个book子元素。
[例8]
/bookstore/book[last()] :表示选择bookstore的最后一个book子元素。
[例9]
/bookstore/book[last()-1] :表示选择bookstore的倒数第二个book子元素。
[例10]
/bookstore/book[position()<3] :表示选择bookstore的前两个book子元素。
[例11]
//title[@lang] :表示选择所有具有lang属性的title节点。
[例12]
//title[@lang='eng'] :表示选择所有lang属性的值等于“eng”的title节点。
[例13]
/bookstore/book[price] :表示选择bookstore的book子元素,且被选中的book元素必须带有price子元素。
[例14]
/bookstore/book[price>35.00] :表示选择bookstore的book子元素,且被选中的book元素的price子元素值必须大于35。
[例15]
/bookstore/book[price>35.00]/title :表示在例14结果集中,选择title子元素。
[例16]
/bookstore/book/price[.>35.00] :表示选择值大于35的“/bookstore/book”的price子元素。
五、通配符
# “*”表示匹配任何元素节点。
# “@*”表示匹配任何属性值。
# node()表示匹配任何类型的节点。
[例17]
//* :选择文档中的所有元素节点。
[例18]
/*/* :表示选择所有第二层的元素节点。
[例19]
/bookstore/* :表示选择bookstore的所有元素子节点。
[例20]
//title[@*] :表示选择所有带有属性的title元素。
六、选择多个路径
用“|”选择多个并列的路径。
[例21]
//book/title | //book/price :表示同时选择book元素的title子元素和price子元素。
【相关文章】
* CSS选择器笔记
(完)
文档信息
- 版权声明:自由转载-非商用-非衍生-保持署名 | Creative Commons BY-NC-ND 3.0
- 原文网址:http://www.ruanyifeng.com/blog/2009/07/xpath_path_expressions.html
- 最后修改时间:2009年7月 6日 12:11
网页采集(通过HtmlAgilityPack+XPath)的更多相关文章
- C#+HtmlAgilityPack+XPath带你采集数据(以采集天气数据为例子)
第一次接触HtmlAgilityPack是在5年前,一些意外,让我从技术部门临时调到销售部门,负责建立一些流程和寻找潜在客户,最后在阿里巴巴找到了很多客户信息,非常全面,刚开始是手动复制到Excel, ...
- 史林枫:开源HtmlAgilityPack公共小类库封装 - 网页采集(爬虫)辅助解析利器【附源码+可视化工具推荐】
做开发的,可能都做过信息采集相关的程序,史林枫也经常做一些数据采集或某些网站的业务办理自动化操作软件. 获取目标网页的信息很简单,使用网络编程,利用HttpWebResponse.HttpWebReq ...
- Hawk 3. 网页采集器
1.基本入门 1. 原理(建议阅读) 网页采集器的功能是获取网页中的数据(废话).通常来说,目标可能是列表(如购物车列表),或是一个页面中的固定字段(如JD某商品的价格和介绍,在页面中只有一个).因此 ...
- Fiddler 网页采集抓包利器
最近这段时间,网页采集方面的工作做得比较多.用curl技术开发了一个微信文章聚合类产品,把抓取到的数据转换成json格式,并在android端调用json数据接口加以显示:基于weiphp做了一个掌上 ...
- Fiddler 网页采集抓包利器__手机app抓包
用curl技术开发了一个微信文章聚合类产品,把抓取到的数据转换成json格式,并在android端调用json数据接口加以显示: 基于weiphp做了一个掌上头条插件,也是用的网页采集技术:和一个创业 ...
- 网页采集利器 phpQuery
网页采集利器 phpQuery 2012-02-28 11:43:24| 分类: php|举报|字号 订阅 在网页采集的时候,通常都会用到正则表达式.但是有时候对于正则不太好的同学,比如我, ...
- 网页采集器-UA伪装
网页采集器-UA伪装 UA伪装 请求载体身份标识的伪装: User-Agent: 请求载体身份标识,通过浏览器发起的请求,请求载体为浏览器,则该请求的User-Agent为浏览器的身份标识,如果使用爬 ...
- 异步网页采集利器CasperJs
在采集网页中,我们会经常遇到采集一些异步加载页面的网页,我们通常用的httpwebrequest类就采集不到了,这个时候我们通常会采用webbrowser来辅助采集,但是.net下自带的webbrow ...
- 简单的网页采集程序(ASP.NET MVC4)
因为懒人太多,造成现在网页数据采集非常的流行,我也来写个简单的记录一下. 之前写了MVC的基本框架的搭建随笔,后面因为公司太忙,个人感情问题:(,导致不想写了,就写了两篇给删除了,现在就搁浅了, 本人 ...
随机推荐
- 在JAVA中生成RSA秘钥对实现SSH互信
https://blog.csdn.net/u014196729/article/details/51496262 https://blog.csdn.net/u013066244/article/d ...
- pyqt5最简单的打开和保存文件
import sys import os from PyQt5.QtWidgets import QApplication,QWidget,QFileDialog from t import Ui_F ...
- lr总结
最近一直在用Loardrunner做性能测试,记录下自己在工作中遇到的问题. LR的基本设置 首先是录制,在录制前选择TOOLS-recording options 在General中选择record ...
- spring_150907_sqlmapclientdaosupport_getSqlMapClient
1.新建java工程:spring_150907_sqlmapclientdaosupport_getSqlMapClient,如下图所示: 2.工程里添加spring.hibernate.ibati ...
- 现在就能投入使用的12个高端大气上档次的CSS3特性
原文:http://tutorialzine.com/2013/10/12-awesome-css3-features-you-can-finally-use/ 原文中有demo展示及下载. 翻译开始 ...
- 【C#】实现INotifyPropertyChanged的3种方法
class StudentItemViewModel:INotifyPropertyChanged { public event PropertyChangedEventHandler Propert ...
- codeforces-727A
题目连接:http://codeforces.com/contest/727/problem/A A. Transformation: from A to B time limit per test ...
- C++ 四种显示转换
转自:http://www.jellythink.com/archives/205 (果冻想) 前言 这篇文章总结的是C++中的类型转换,这些小的知识点,有的时候,自己不是很注意,但是在实际开发中 ...
- Web应用程序信息收集工具wig
Web应用程序信息收集工具wig 很多网站都使用成熟的Web应用程序构建,如CMS.分析网站所使用的Web应用程序,可以快速发现网站可能存在的漏洞.Kali Linux新增加了一款Web应用程序信 ...
- iOS 9应用开发基础教程下册
iOS 9应用开发基础教程下册 介绍: 本教程是国内第一本iOS 9开发应用教程.本教程基于Xcode 7.0,使用Swift 2.0语言讲解如何开发iOS 9的应用App. 学习建议:本教程针对 ...