使用C#和HtmlAgilityPack解析HTML
近期,有一个需求,需要解析HTML页面,读取一些需要的数据后,插入本地数据库。我知道可以通过正则表达式实现,然而正则表达式之于我,就像汇编语言之于我,一样。我知道它是干什么的,我也知道它能干什么,但是我一直不知道怎么干,曾经尝试过,后来用得太少,最终放弃了。也知道有一些组件可以实现操作HMTL,比如mshtml,比如WebBrowser,然而总是感觉不太好,不太专业。犹犹疑疑,一直没有开始,直到发现HtmlAgilityPack,如获至宝,中间那个词Agility,是敏捷、灵活的意思。
以下文字,部分摘录于周公博客,有所改编。
这里是W3School的详细介绍
XPath简明介绍
XPath 使用路径表达式来选取 XML 文档中的节点或节点集。节点是通过沿着路径 (path) 或者步 (steps) 来选取的。
下面列出了最有用的路径表达式:
nodename:选取此节点的所有子节点。
/是从根节点选取。
//是从匹配选择的当前节点开始选择当前节点之下的节点,而不考虑它们的位置和深度。
.(一个点)是选取当前节点。
..(两个点)选取当前节点的父节点。
例如有下面一段XML:
<?xml version="1.0" encoding="utf-8"?>
<Articles>
<Article>
<Title>在ASP.NET中使用Highcharts js图表</title>
<Url>http://zhoufoxcn.blog.51cto.com/792419/537324</Url>
<CreateAt type="en">2011-04-07</price>
</Article>
<Article>
<Title lang="eng">Log4Net使用详解(续)</title>
<Url>http://blog.csdn.net/zhoufoxcn/archive/2010/11/23/6029021.aspx</Url>
<CreateAt type="zh-cn">2010年11月23日</price>
</Article>
<Article>
<Title>J2ME开发的一般步骤</title>
<Url>http://blog.csdn.net/zhoufoxcn/archive/2011/06/12/6540223.aspx</Url>
<CreateAt type="zh-cn">2011年06月12日</price>
</Article>
<Article>
<Title lang="eng">PowerDesign高级应用</title>
<Url>http://zhoufoxcn.blog.51cto.com/792419/166415</Url>
<CreateAt type="zh-cn">2007-09-08</price>
</Article>
</Articles>
针对上面的XML文件,我们列出了带有谓语的一些路径表达式,以及表达式的结果:
/Articles/Article[1]:选取属于Articles子元素的第一个Article元素。 即第一组<Article></Article>。注意,从1开始,不是从0开始。
/Articles/Article[last()]:选取属于Articles子元素的最后一个Article元素。 即最后一组<Article></Article>
/Articles/Article[last()-1]:选取属于Articles子元素的倒数第二个Article元素。
/Articles/Article[position()<3]:选取最前面的两个属于 bookstore 元素的子元素的Article元素。
//title[@lang]:选取所有拥有名为lang的属性的title元素。
//CreateAt[@type='zh-cn']:选取所有CreateAt元素,且这些元素拥有值为zh-cn的type属性。
/Articles/Article[Order>2]:选取Articles元素的所有Article元素,且其中的Order元素的值须大于2。
/Articles/Article[Order<3]/Title:选取Articles元素中的Article元素的所有Title元素,且其中的Order元素的值须小于3。
HtmlAgilityPack API简明介绍
在HtmlAgilityPack中常用到的类有HtmlDocument、HtmlNodeCollection、
HtmlNode和HtmlWeb等。
其流程一般是先获取HTML,这个可以通过HtmlDocument的Load()或LoadHtml()来加载静态内容,或者也可以HtmlWeb的Get()或Load()方法来加载网络上的URL对应的HTML。
得到了HtmlDocument的实例之后,就可以用HtmlDocument的DocumentNode属性,这是整个HTML文档的根节点,它本身也是一个HtmlNode,然后就可以利用HtmlNode的SelectNodes()方法返回多个HtmlNode的集合对象HtmlNodeCollection,也可以利用HtmlNode的SelectSingleNode()方法返回单个HtmlNode。
HtmlAgilityPack实战
private void ParsePage()
{
docText = GetWebClient("http://www.bjjs.gov.cn/eportal/ui?pageId=308888");
//string text = File.ReadAllText(@"C:\Users\sabre\Downloads\北京市专业人员信息查询.htm");
//Post("http://www.bjjs.gov.cn/eportal/ui?pageId=308888", text,Encoding.UTF8.WebName); //PostWebRequest("http://www.bjjs.gov.cn/eportal/ui?pageId=308888", text, Encoding.UTF8); Post("http://www.bjjs.gov.cn/eportal/ui?pageId=308888", "currentPage=10", Encoding.UTF8.WebName); var doc = new HtmlDocument();
doc.LoadHtml(docText); //人员数据
var persons = doc.DocumentNode.SelectSingleNode("/html[1]/body[1]/div[4]/div[3]/div[1]/div[2]/div[2]/table[1]/tbody[1]/tr[1]/td[1]/table[1]/tbody[1]");
HtmlNodeCollection personList = persons.SelectNodes(@"tr");
foreach (var item in personList)
{
//根据class判断,标题行跳过
if (item.Attributes["class"] != null)
{
string styleclass = item.Attributes["class"].Value;
if (styleclass == "DataGrid-Header") continue;//标题行跳过
}; var tds = item.SelectNodes(@"td"); foreach (var td in tds)
{
var a = td.InnerText;//获取目标数据,如姓名、证件号等,此处可以开始进行相应的数据处理,如持久化
}
} //按钮数据
var buttons = doc.DocumentNode.SelectSingleNode("/html[1]/body[1]/div[4]/div[3]/div[1]/div[2]/div[2]/table[1]/tbody[1]/tr[1]/td[1]/table[1]/tbody[1]/tr[19]/td[1]/div[1]"); var buttonList = buttons.SelectNodes(@"table//a"); foreach (var item in buttonList)
{
string a = string.Empty;
string b = string.Empty;
if (item.Attributes["onclick"] != null)
{
a = item.Attributes["onclick"].Value;
//var pattern = "/=(.+?);/g";
//var pattern = "/=(.*?);/";
var pattern = @"\d";
Regex reg = new Regex(pattern);
MatchCollection mc = reg.Matches(a);
foreach (Match m in mc)
{
b += m.Value;
}
}
}
}
使用C#和HtmlAgilityPack解析HTML的更多相关文章
- HtmlAgilityPack解析全国区号页面到XML
需求:完成一个城市和区号的xml配置文件 处理思路:通过HtmlAgilityPack解析一个区号页面,生产xml文件 页面:http://www.hljboli.gov.cn/html/code.h ...
- HtmlAgilityPack解析器在WP8.1下报错,不仅如此,社交化分享也报错。
以前WP7下是用的HtmlAgilityPack和 XPath来解析网页,很好用. 但是在Wp8.1下,这个里面却缺少了一个很重要的方法. HtmlDocument doc = new HtmlDoc ...
- HtmlAgilityPack --解析Html源码
最近项目需要从网络上抓取一下数据解析Html源码,奈何正则表达式难写,于是网上搜索找到了“ HtmlAgilityPack”类库,敏捷开发,果然效率非同寻常. 在此做笔记,写下心得,顺便给自己总结一下 ...
- C#:使用HtmlAgilityPack解析Html
推荐阅读: HtmlAgilityPack 入门教程1 HtmlAgilityPack入门教程2 向HtmlAgilityPack道歉:解析HTML还是你好用 获取html中meta标签中的conte ...
- 使用HtmlAgilityPack解析html
HtmlAgilityPack是.net下使用xPath来解析html的类库,可以方便的做html的页面分析处理 项目地址: http://htmlagilitypack.codeplex.com/ ...
- .Net Core下使用HtmlAgilityPack解析采集互联网数据
HtmlAgilityPack应该算是.Net下最好用的html解析库了. 因为最近帮朋友采集一些数据,在nuget里面搜索了好几个库,最后决定就用HtmlAgilityPack.并简单的记录下使用的 ...
- HtmlAgilityPack解析html文档
一.概述 HtmlAgilityPack(以下简称HAP)是一个基于.Net的.第三方免费开源的微型类库,主要用于在服务器端解析html文档. HtmlAgilityPack为网页提供了标准的DOM ...
- c#HtmlAgilityPack解析html
通过HtmlAgilityPack实现对html页面解析HtmlDocument doc = new HtmlDocument(); doc.Load(yourStream); var itemLis ...
- C#爬虫(04):HtmlAgilityPack解析html文档
原文链接 https://www.cnblogs.com/springsnow/p/13278283.html 目录 一.爬虫概述 1.使用浏览器获取页面源码 2.HTML解析组件 二.HtmlAgi ...
随机推荐
- wampserver下配置虚拟主机 实现多站点支持
wampserver下配置虚拟主机 实现多站点支持 wampserver是由德国人开发,在windows环境下实现apache+php+mysql的一款集成环境软件,wampserver自带SQLit ...
- php微信开发 -- 两种运营模式及服务器配置
微信的两种运营模式 编辑模式:使用微信公众平台提供的功能 开发者模式:通过腾讯的api接口调用相应程序进行二次开发 编辑模式 应用场景: l 不具备开发能力的运营者 l 主要是进行品牌宣传.新闻媒体. ...
- 在PADS中,大面积覆铜有3个重要概念
- iOS: Assertion failure on picker view
Q:I'm getting an assertion failure while scrolling a picker view w/ zero data(zero rows). While scro ...
- Resharper 安装以及破解
首先进行软件安装 安装后 解压下载好的 文件 会得到如下: 打开序列号 会看到 然后 复制 %LocalAppData%\\JetBrains 路径 会得到进入当前JetBrains 文件夹 然后搜 ...
- C语言对文件的操作函数用法详解1
在ANSIC中,对文件的操作分为两种方式,即: 流式文件操作 I/O文件操作 一.流式文件操作 这种方式的文件操作有一个重要的结构FILE,FILE在stdio.h中定义如下: typedef str ...
- 在Linux服务器上部署node项目(git部署,forever持续运行,配置SSL证书)
一.环境部署 1.下载安装包: wget https://nodejs.org/dist/v9.9.0/node-v9.9.0-linux-x64.tar.xz 2.解压并进入目录: xz -d no ...
- layui时间,table,大图查看,弹出框,获取音频长度,文件上传
1.引入: <link href="../../Scripts/layui-v2.3.0/css/layui.css" rel="stylesheet" ...
- SQLServer------聚集索引和非聚集索引的区别
转载: http://www.cnblogs.com/flashicp/archive/2007/05/08/739245.html 建立非聚集索引(vid不是主键) create index idx ...
- 【python】一次执行多个linux命令
方法:多个命令之间用“;”进行连接即可: