澳门新浦京娱乐场网站-www.146.net-新浦京娱乐场官网
做最好的网站

澳门新浦京娱乐场网站:项目记录,网络爬虫利

明天刚开首做毕设....好啊,的确有些晚。小编的毕设设计必要爬取豆瓣的电影推荐,于是就需求解析爬取下来的html,早先用Python玩过剖析,但眼前本身使用的是C#,我觉得C#比不上python差,有微软大大在,这些不要求操心,首要照旧生态难题。查了下资料,开采Html Agility Pack是相比较好的,当然还应该有任何的,小编就隐蔽了,首要使用它做的。

简介

  将来更是多的风貌供给我们应用网络爬虫,抓取相关数据便宜大家利用,几天前大家要讲的庸中佼佼Html Agility Pack是在爬取的历程此中,能够急忙的深入分析大家抓取到的html数据。

 

Html Agility Pack ── 一个拆解解析HTML的工具

从今 Web 应用程序自 1994 年 W3C 设立以来就初步升高,何况 HTML 也历经了数个版本的嬗变(1.0 – 2.0 – 3.0 – 3.2 – 4.0 – 4.01),今后也早已成为Web网页或应用程序的最基本功,想要学习怎么设计 Web 网页或支付 Web 应用程序,那已是纯属必定要学的东西了,就终于低价的控件(譬如ASP.NET),但 HTML 依然有上学它的必要性,因而只要不会 HTML,就拾叁分没学过 Web 网页通常。

    官方网站地址(能够自身去下载dll卡塔尔(英语:State of Qatar):

优势

  在.NET技巧下,深入分析html工具也比较多,比如很六个人只怕会利用htmlparser,或然微软的MSHTML,htmlparser即便相比比较简单上手,不过相对应的分析速度异常慢,而Html Agility Pack拆解剖析速度相当的慢,而且开源,易用,它能够支持大家深入分析html文书档案就如用XmlDocument类来解析xml同样轻便、方便。

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

本文为大大维原创,最先于新浪公布,转发请注脚出处!!!

 

拜 HTML 与 Web 浏览器如日中天之赐,精彩纷呈的选用都在互联网上便捷升高,举凡电商、集团门户、在线下单、公司间一块应用等,甚至于社交、性格化、Web 2.0 等商务与集体利用等力量,而在新闻爆炸的时日,超多音讯整合的施用也随着出炉,而这么些音讯整合的应用程序都会连选用分裂的网址下载其新闻,而且在重重的 HTML 中解析出想要的多少(比如每只股票价格格、上涨或下跌幅、成交量等)。

    

格局介绍

  其实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的片段关键的常用成员作简要的辨证。

  就以小编今日头条主页为例,希望大家在这里功底上能够触类旁通,这里只做一得之见,分界面图如下:

澳门新浦京娱乐场网站 1

  后台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/customlogo.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/法号阿兴">联系</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.comxml.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=" Tag尽管该节点叫Node:

Node.ParentNode.RemoveChild(Node,true); 

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

  更加多的方法我们能够到官方网址的API文书档案实行打探,这里就不做更加的多的表达。

 PS:如有疑问,请留言,未经允许,不得违规转发,转发请注脚出处:

澳门新浦京娱乐场网站 2

澳门新浦京娱乐场网站 3

 

 

——通过知识共享树立个人品牌。

唯独 HTML 自己并非二个构造严苛的言语,它同意卷标(tag)能够在不 close 的情状下继续应用。那也是因为浏览器设计的高容错性(Fault Tolerance)所致,如此一来,想要依据准则来分析 HTML 文件差十分的少变得不或然,何况对方的网址的 HTML 构造也也许会任何时候变动,在此种状态下,剖析 HTML 变得卓殊麻烦,即使 W3C 有其余推销和展览 XHTML(信守 XML 严峻格式的 HTML),但利用它来两全网页的案例仍是少数,大超级多的网站依旧是利用 HTML。因而大家会要求三个工具,能够有一点点子火速的剖释 HTML 以收取我们供给的多少。

    参考:Html Agility Pack底工类介绍及应用

第一章 简介

本文主要介绍了在.NET下使用天时地利的HTML深入剖判组件HtmlAgilityPack开荒的叁个吉上将内文告oa.jlu.edu.cn的爬取器。尽管.Net下解析HTML文件有很三种选项,包蕴微软温馨也提供MSHTML用于manipulate HTML文件。不过,经过本人多边查阅资料和调谐的品味,Html Agility Pack稳步盛气凌人:它是Stackoverflow网址上引入最多的C# HTML深入分析器。HAP开源,易用,深入分析速度快。因此,自己最后采撷使用HAP作为爬虫的费用的HTML深入分析组件。

小编达成的爬虫OAWebScraping能够兑现由使用者内定时期的(从近期时间往前n天卡塔尔的,对oa.jlu.edu.cn上的全部全部公告和新闻,包蕴时间、题目、公布部门、正文全文和附属类小零器件的爬取,何况依照时间->发布部门->题目->正文及附属类小零件的树形结构将爬取的文书保留在硬盘中。以下是选用截图:

初阶爬虫,输入爬取的时光节制:

 澳门新浦京娱乐场网站 4

爬取成功,对于从未发放布告的日子付与提示:

 澳门新浦京娱乐场网站 5

文件的集体构造:

 澳门新浦京娱乐场网站 6

爬取的文本依据树形布局

日子->宣布部门->标题->正文及附件

保留在硬盘:

按时间:

 澳门新浦京娱乐场网站 7

按公布部门:

澳门新浦京娱乐场网站 8

按标题:

澳门新浦京娱乐场网站 9

 

正文及附属类小零部件:

澳门新浦京娱乐场网站 10

正文:

 澳门新浦京娱乐场网站 11

附件:

 澳门新浦京娱乐场网站 12


大家都掌握,HTML 本人其实只是一个 HTML 标识的字符串而已,因此日常聊起要剖判HTML,第4个会想到的大约正是字符串比对(string comparison),本身针对 HTML 的构造写多少个 pattern,然后由函式去做逐生龙活虎的比对,例如:

    代码设计:

第二章    商量方法

(1) How to use HAP?1

  1. 下载

  2. 解压

  3. 在Visual Studio Solution里,右击project -> add reference -> 选取解压文件夹里的HTMLAgilityPack.dll -> 显著

  4. 代码尾部插手 using HtmlAgilityPack;

Done!

(2)HAP 概述:【2】

      在HtmlAgilityPack中常用到的类有HtmlDocument、HtmlNodeCollection、            HtmlNode和HtmlWeb等.其流程平时是先拿走HTML,这几个能够通过HtmlDocument的Load(卡塔尔(英语:State of Qatar)或LoadHtml(卡塔尔(英语:State of Qatar)来加载静态内容,大概也能够HtmlWeb的Get(卡塔尔(英语:State of Qatar)或Load(卡塔尔国方法来加载网络上的U陆风X8L对应的HTML。

      得到了HtmlDocument的实例之后,就足以用HtmlDocument的DocumentNode属性,那是总体HTML文档的根节点,它自己也是三个HtmlNode,然后就足以采纳HtmlNode的SelectNodes(卡塔尔(英语:State of Qatar)方法重临七个HtmlNode的聚众对象HtmlNodeCollection,也能够行使HtmlNode的SelectSingleNode(卡塔尔国方法再次来到单个HtmlNode。

(3)XPath 概述:[2]

      HtmlAgilityPack是叁个支撑用X帕特h来分析HTML的类库,防止了应用正则表明式一步步将无关的HTML注释及JS代码部分删除掉,然后再用正则表达式找寻须要领取的部分,能够说利用正则表明式来做是二个相比较繁杂的经过,以下是贰个大致的XPath介绍:XPath 使用路线表明式来抉择 XML 文书档案中的节点或节点集。节点是由此沿路线 (path卡塔尔国或然步 (steps卡塔尔(قطر‎ 来筛选的。
 上面列出了最可行的路线表明式:
 nodename:选取此节点的全数子节点。 
 /:从根节点选择。 
 //:从相称选取的日前节点选拔文书档案中的节点,而不思虑它们的岗位。 
 .:选拔当前节点。 
 ..:选择当前节点的父节点。

(4)关键代码剖析:

 澳门新浦京娱乐场网站 13

 

Main函数逻辑:通过GetItemWebs(range卡塔尔(英语:State of Qatar)找寻须要爬取的url簇,然后用etItemWeb(itemWebUrl卡塔尔(قطر‎爬取文件并下载。

 澳门新浦京娱乐场网站 14

 

拼接yyyyMMdd天的oa通知分界面url。

 澳门新浦京娱乐场网站 15

 

加载Html并物色当前页,由于oa中通报跳转连接均在<div> class“li rel”下 的<a>

Class “font14” 中,爬抽出其href并拼接成相关具体通告的url,压入叁个List(itemWebs)中,由于有些时段未有发通报,那样会促成nodes为空,会使得nodes.Select(卡塔尔国发生空指针格外,由此引进分外机制,有限支持程序符合规律运作,并对还没发通报的日子实行提示。

如上是GetItemWebs(int range)的要害逻辑。该函数再次来到贰个兼有须要探求的照管的url的string s数组。

 

 澳门新浦京娱乐场网站 16

 

在GetItemWeb(string itemWebUrl)函数中,通过url初始化uri,解析uri获得title和orgname。

 澳门新浦京娱乐场网站 17

 解析HtmlDocument并通过<div> class ‘content_time’ 获得通报揭橥时间。

 澳门新浦京娱乐场网站 18

解析HtmlDocument中<div> class ‘content_font fontsize immmge’中的p标签,来拼接通告正文。

澳门新浦京娱乐场网站 19

 

根据“时间->公布部门->标题->正文”树形构造将正文存款和储蓄在硬盘

 澳门新浦京娱乐场网站 20

 

下载附属类小零部件,并将附属类小零部件和呼应的正文存在一个文件中。

以上是GetItemWeb(string itemWebUrl卡塔尔国的重大逻辑。

 

[C#]

static void complete(object o, AsyncCompletedEventArgs e) 
 { 
 // 开始解析html 
 var doc = new HtmlDocument(); 
 doc.Load( "E:程序文件C#程序代码ValidateConsoleApplication1movie.txt", Encoding.UTF8); 
 List<string> movie = new List<string>(); 

 //  
 HtmlNodeCollection nodeCollection = doc.DocumentNode.SelectNodes("//ul/li[ class="title"]"); 
 foreach (HtmlNode n in nodeCollection) 
 { 
 Console.WriteLine(n.InnerHtml.Trim()); 
 movie.Add(n.InnerText.Trim()); 
 } 


 //获取豆瓣最受欢迎影评 
 HtmlNodeCollection nodeCollection1 = doc.DocumentNode.SelectNodes("//div[ class="review-bd"]/h3"); 
 foreach (HtmlNode n in nodeCollection1) 
 { 
 Console.WriteLine(n.InnerHtml.Trim()); 
 movie.Add(n.InnerText.Trim()); 
 } 

 foreach(var m in movie) 
 { 
 Console.WriteLine(m); 
 } 

 File.Delete( "E:程序文件C#程序代码ValidateConsoleApplication1movie.txt"); 
 } 

 static void Main(string[] args) 
 { 
 Console.BufferHeight = 10000; 
 Console.BufferWidth = 10000; 
 string moviePath =  "E:程序文件C#程序代码ValidateConsoleApplication1movie.txt"; 
 WebClient wc = new WebClient(); 
 wc.UseDefaultCredentials = true; 
 wc.DownloadFileAsync(new Uri("https://movie.douban.com/"), moviePath); 
 wc.DownloadFileCompleted  = new AsyncCompletedEventHandler(complete); 

 Console.Read(); 
 }

 第三章 数据拆解解析和结果

      由于时限,小编爬取了2017/6/15-2017/6/20里边6天的持有数据,在那之中2017/6/18一贯不公告,没有数据。其余17号只有研讨院发放的一条通告,别的时段基本上每天都有贰十一个左右的部门发给15条左右的通报。查日历可以看到,17,18号为周天。

      可以知道在职业日中,作者校的教务专门的工作都在积极举办,别的省级委员会社团部和宣传总局是打招呼发送的大洋。具体可以知道ScrapingFiles文件夹(爬取数据的存放文件夹)。

.NET 框架类库本人未有提供工具剖判HTML,早前常用的做法是用正则表达式,或许浏览器控件,或许MSHTML组件,以至SgmlReader。SgmlReader能够将HTML转变成XML,然后您就足以应用System.Xml命名空间下的类对文件实行查询。

  1. string pattern = "<td id='stockPrice'>";

  2. html.IndexOf(pattern);

对于WebClient文档,请看

第四章 结论

      小编在.NET下采用地利人和的HTML拆解深入分析组件HtmlAgilityPack开垦的一个吉上将内布告oa.jlu.edu.cn的爬取器,测量检验好用并且挺实用。

CodePlex上有三个Html Agility Pack项目,是原生的.NET项目,不依据于MSHTML或然ActiveX/COM 对象。个中的HtmlDocument能够加载任何HTML文件(尽管该公文是不well-formed的HTML卡塔尔,然后允许你利用相通于System.Xml的目的模型对文本实行询问。

不过守旧的字符串比对效能太差,也平素不七个准则性,由此才发展出正则表明式(Regular Expression)技艺,比如下列那样的语法:

    一定要说,微软官方网址的多级文书档案真是良心!早先也是听人说过,微软的解决方案以致文档很全,不过平素查资料都以直接百度,今后换了风流倜傥种,间接上微软官方网站查....真是心肝!何况例子是相比较经典的!

第五章 参谋文献

【1】Brian互连网畅游的笔录的博客《开源项目Html Agility Pack完成急忙深入剖析Html》

【2】51Ct0博主周公的博客《HTML解析利器HtmlAgilityPack》:

【3】CSDN无极世界博主的博客《HtmlAgilityPack——深入分析html和征集网页的神兵利器》

【4】HAP官方网址的费用文档

 

官方网址地址:www.codeplex.com/htmlagilitypack
例如: 

[Regular Expression]

第六章 代码

澳门新浦京娱乐场网站 21澳门新浦京娱乐场网站 22

  1 using System;
  2 using System.Collections.Generic;
  3 using System.IO;
  4 using System.Linq;
  5 using System.Net;
  6 using System.Web;
  7 using HtmlAgilityPack;
  8 
  9 //作者:大大维
 10 namespace OA
 11 {
 12     class Program
 13     {
 14         static void Main()
 15         {
 16             Console.WriteLine("用于查询距今X天的oa通知!!!欢迎使用!!!");
 17             Console.WriteLine("请输入查询的范围(距现在多少天,0表示当天,1表示昨天 今天,以此类推):");
 18             var range = int.Parse(Console.ReadLine());
 19             Console.WriteLine("开始爬取!!!");
 20             var itemWebUrls = GetItemWebs(range);
 21             foreach (var itemWebUrl in itemWebUrls)
 22             {
 23                 GetItemWeb(itemWebUrl);
 24             }
 25             Console.WriteLine("爬取完毕!!!");
 26             Console.ReadLine();         
 27         }
 28 
 29         private static string[] GetItemWebs(int range)
 30         {
 31             /*在HtmlAgilityPack中常用到的类有HtmlDocument、HtmlNodeCollection、 
 32             HtmlNode和HtmlWeb等.其流程一般是先获取HTML,这个可以通过HtmlDocument的Load()或LoadHtml()来加载静态内容,
 33             或者也可以HtmlWeb的Get()或Load()方法来加载网络上的URL对应的HTML。 
 34             得到了HtmlDocument的实例之后,就可以用HtmlDocument的DocumentNode属性,
 35             这是整个HTML文档的根节点,它本身也是一个HtmlNode,
 36             然后就可以利用HtmlNode的SelectNodes()方法返回多个HtmlNode的集合对象HtmlNodeCollection,
 37             也可以利用HtmlNode的SelectSingleNode()方法返回单个HtmlNode。 */
 38             var itemWebs = new List<string>();//由于每页网站的通知内容数目不定,采用List较好
 39             //@忽略转义字符
 40             var baseUrl = @"https://oa.jlu.edu.cn/defaultroot/PortalInformation!jldxList.action?channelId=179577&searchnr=";
 41             var web = new HtmlWeb();
 42             for (var i = range; i >= 0; --i)
 43             {
 44                 //拼接yyyyMMdd天的oa通知界面
 45                 DateTime dt = DateTime.Now.AddDays(-i);
 46                 var dtStr = string.Format("{0:yyyyMMdd}", dt);
 47                 var url = baseUrl   dtStr   "&searchlx=3";
 48                 //加载HTML静态内容
 49                 var htmlDoc = web.Load(url);
 50                 //获取每个子页面的url并存入items中
 51                 var nodes = htmlDoc.DocumentNode.SelectNodes("//div[@class='li rel']/a[@class='font14']");
 52                 try
 53                 {
 54                     var pageItemUrl = nodes.Select(node => "https://oa.jlu.edu.cn/defaultroot/"
 55                       node.GetAttributeValue("href", "")).ToList();
 56                     itemWebs.AddRange(pageItemUrl);
 57                 }
 58                 catch(Exception)//当当天没有通知下发时,nodes为空,在nodes.Select()中抛出空指针异常
 59                 {
 60                     Console.WriteLine(dtStr "没有通知下发!!!");                    
 61                 }               
 62             }
 63             return itemWebs.ToArray();
 64         }
 65 
 66         private static void GetItemWeb(string itemWebUrl)
 67         {
 68             //uri解析
 69             var uri = new Uri(itemWebUrl);
 70             var title = HttpUtility.ParseQueryString(uri.Query).Get("title");//title即url的title部分
 71             var orgname = HttpUtility.ParseQueryString(uri.Query).Get("orgname");//orgname即url的orgname部分
 72 
 73             var web = new HtmlWeb();
 74             var htmlDoc = web.Load(itemWebUrl);
 75 
 76             var contentTime = htmlDoc.DocumentNode.SelectSingleNode("//div[@class='content_time']").InnerText;
 77             var indexOfBlank = contentTime.IndexOf(' ');
 78             var time = contentTime.Substring(0, indexOfBlank);
 79 
 80             var contentNode = htmlDoc.DocumentNode.SelectSingleNode("//div[@class='content_font fontsize immmge']");
 81             var content = string.Empty;
 82             var ps = contentNode.SelectNodes("p");
 83             if (ps != null)
 84             {
 85                 foreach (var p in ps)
 86                 {
 87                     content  = p.InnerText.Replace("&nbsp;", " ").Replace(' ', ' ')   "n";
 88                 }
 89             }
 90             else
 91             {
 92                 content = contentNode.InnerHtml.TrimStart().Replace("&nbsp;", " ").Replace(' ', ' ').Replace("<br>", "n");
 93             }
 94 
 95             //创建ScrapingFiles文件夹保存文件
 96             Directory.CreateDirectory($"../../../ScrapingFiles/{time}/{orgname}/{title}");
 97             File.WriteAllText($"../../../ScrapingFiles/{time}/{orgname}/{title}/" title   ".txt", content);
 98 
 99             //下载相关附件
100             var fileNodes = htmlDoc.DocumentNode.SelectNodes("//td[@width='93%']/span");
101             if (fileNodes != null)
102             {
103                 var webClient = new WebClient();
104                 foreach (var node in fileNodes)
105                 {
106                     var fileId = node.GetAttributeValue("id", "");//寻找文件ID
107                     var fileTitle = node.GetAttributeValue("title", "");//寻找文件title
108                     var articleId = HttpUtility.ParseQueryString(uri.Query).Get("id");
109 
110                     var res = webClient.DownloadString(
111                         "https://oa.jlu.edu.cn/defaultroot/rd/jldx/BASEEncoderAjax.jsp?"  
112                         $"res={fileId}@{fileTitle}@{articleId}");
113                     res = res.Trim().Replace("n", "");
114                     webClient.DownloadFile("https://oa.jlu.edu.cn/defaultroot/rd/attachdownload.jsp?res="   res,
115                         $"../../../ScrapingFiles/{time}/{orgname}/{title}/"   fileTitle);
116                 }
117             }
118         }
119     }
120 }

View Code

 HtmlDocument doc = new HtmlDocument();
 doc.Load("file.htm");
 foreach(HtmlNode link in doc.DocumentElement.SelectNodes("//a[@href"])
 {
    HtmlAttribute att = link["href"];
    att.Value = FixLink(att);
 }
 doc.Save("file.htm");  

1. </?w ((s w (s*=s*(?:".*?"|'.*?'|[^'">s] ))?) s*|s*)/?>

 

 

浅析 HTML:Web 开垦职员心中的痛

自从Web 应用软件自1994 年W3C 设立以来就起来发展,而且HTML 也历经了数个本子的嬗变(1.0 – 2.0 – 3.0 – 3.2 – 4.0 – 4.01),未来也后生可畏度变成Web网页或应用软件的最底蕴,想要学习如何安排Web 网页或开辟Web APP,那曾经是纯属一定要学的事物了,就到底实惠的主宰八臂李哪吒项充满(举例ASP.NET),但HTML 仍有上学它的必要性,因而假使不会HTML,就等于没学过Web 网页般。

拜HTML 与Web 浏览器蒸蒸日上之赐,丰富多彩的运用都在网路上飞速发展,举凡电商、集团输入、线上下单、企业间协同应用等,甚至于社会群众体育、个人化、Web 2.0 等商务与团伙使用等本事,而在情报爆炸的有的时候,相当多谍报整合的应用也任何时候出炉,而那些音信整合的应用程式都会连选用差别的网址下载其音信,何况在重重的HTML 中分析出想要的资料(举个例子每一股票价格格、上涨或下落低的幅度、成交量等)。

只是HTML 自己并非三个结构严俊的言语,它同意标签(tag)可以在不close 的动静下持续接收。那也是因为浏览器设计的高容错性(Fault Tolerance)所致,如此一来,想要根据法规来深入分析HTML 文件大概变得不或许,何况对方的网址的HTML 构造也可能会任何时候变动,在这里种景色下,剖判HTML 变得拾叁分麻烦,固然W3C 有此外推销和展览XHTML(坚守XML 严峻格式的HTML),但利用它来规划网页的案例仍是少数,大比相当多的网址依然是行使HTML。因而我们会需求一个工具,能够有艺术赶快的拆解深入分析HTML 以抽取大家须要的材质。

但 Regular Expression 的求学曲线相当的高,若要使用它来深入分析HTML,並且再加以定制化(Customization)的话,对于平日开荒人士来讲,实在未有何样吸重力。

历史观深入分析 HTML 的办法

咱们都清楚,HTML 本身其实只是二个HTML 标志的字串而已,由此常常说起要深入解析HTML,第三个会想到的概况正是字串比对(string comparison),本身针对HTML 的结构写多个pattern,然后由函式去做逐后生可畏的比对,比如:   

string pattern = "<td id='stockPrice'>";  
html.IndexOf(pattern);    

可是守旧的字串比对成效太差,也未曾贰个法规性,由此才提超过准则运算式(Regular Expression)能力,比如下列这样的语法: 

</?w ((s w (s*=s*(?:".*?"|'.*?'|[^'">s] ))?) s*|s*)/?>    

但Regular Expression 的上学曲线极高,若要使用它来拆解分析HTML,何况再加以客制化(Customization)的话,对于日常开采职员来说,实在未有何样亲合力。
HTML 还应该有一个特征,正是它是具阶层性(Hierarchy)的,因而浏览器在解译它的时候都会以文件树(document tree)的主意,再用递回(recursive)的主意来管理它,但Regular Expression 未有利于阶层性的深入分析,而最接近阶层深入分析又好用的工具,莫过于XML Parser 了,它的DOM 以至XPath 的特色,都可以让深入深入分析XML 的专业变得轻便,不过XML Parser 不能够读取经常的HTML(XHTML 可以),因为相通的HTML 是布局松散的类型,XML Parser 会在读入时检查语法结构是或不是完全(也正是Well-known 的协会),若读入的是布局松散的从头到尾的经过的话会掷出例外信息,因而不能直接使用XML Parser 来支持。 

澳门新浦京娱乐场网站 23

HTML 文件树(IE8 开垦者工具)

然则,今后早就有人发展出能够在HTML 下边使用相近于X帕特h 的主意来存取松散构造的HTML 的工具,而且在Codeplex 上以开放原始码的章程公开给外部使用,这一个工具正是本文所要介绍的HTML Agility Pack。

HTML 还会有叁个天性,正是它是具层性(Hierarchy)的,由此浏览器在解译它的时候都会以文件树(document tree)的不二秘诀,再用递归(recursive)的不二法门来管理它,但 Regular Expression 未有扶持层级性的剖判,而最周围阶层分析又好用的工具,莫过于 XML Parser 了,它的 DOM 甚至 XPath 的特征,都足以让分析 XML 的行事变得自在,然而XML Parser 无法读取平时的 HTML(XHTML 能够),因为相通的 HTML 是组织松散的项目,XML Parser 会在读入时检查语法构造是不是完整(相当于Well-known 的布局),若读入的是构造松散的剧情的话会掷出例外信息,因而不能够直接运用 XML Parser 来帮衬。

HTML Agility Pack 简介

HTML Agility Pack 是由法国的一人软体结构师Simon Mourier 所发展,况且由DarthObiwan 以至Jessynoo 辅助开荒出来的叁个软体育工作具,它能够让深入分析松散格式HTML 的劳作就好像解析XML 一样轻易,它也是有像样于System.Xml 命名空间中的XML DOM 的过多品种,除了能够动用阶层的点子存取HTML 以外,它也支持使用XPath 的主意来搜寻HTML,这会较过去选用文字比对或是Regular Expression 的比对形式来得更醒目,比如: 

澳门新浦京娱乐场网站 24

上海教室中以紫色方框框住的是W3C 的最新新闻公告区,而它的HTML 阶层树是以此样子:

澳门新浦京娱乐场网站 25

往年要动用Regular Expression 深入分析时恐怕要走超级多手续(Match 会回传比超多资料,除非写的够精准),才会抵达方框所在之处,但利用HTML Agility Pack 元器件时,大家能用那样的语法:

xpath: 

 

/html[1]/body[1]/div[1]/div[2]/div[3]/div[2]/div[1]/div[1]/div[1]   

 

就抵达大家想要之处,这几个语法和XPath 特别接近,对于熟习X帕特h 或是DOM 的开拓职员会相比方便。 HTML Agility Pack 元器件的花色阶层和XML DOM Parser 其实蛮像的,若以前有用过XML DOM 的开采职员会感到很熟知: 

澳门新浦京娱乐场网站 26

HTML Agility Pack 元器件的类型阶层

如上边的验证,我们得以编写那样的程式码来读取W3C 首页揭橥的最新信息的清单: 

using HtmlAgilityPack;   
   
public static void Main(string[] args)   
{   
    HtmlWeb webClient = new HtmlWeb();   
    HtmlDocument doc = webClient.Load("");   
   
    HtmlNodeCollection nodes = doc.DocumentNode.SelectNodes("/html[1]/body[1]/div[1]/div[2]/div[3]/div[2]/div[1]/div[澳门新浦京娱乐场网站:项目记录,网络爬虫利器之Html。1]/div[1]/div");   
   
    foreach (HtmlNode node in nodes)   
    {   
        Console.WriteLine(node.InnerText.Trim());   
    }   
   
    doc = null;   
    nodes = null;   
    webClient = null;   
   
    Console.WriteLine("Completed.");   
    Console.ReadLine();   
}   

 

 

 

读取W3C 首页中流行公告的程式码(专案类型:主要调节台应用软件)

HTML Agility Pack 只相依于.NET Framework,因而无需任何各个HTML 剖判器的任何元器件,只要有.NET Framework 就能够举办。

HTML Agility Pack 是由法兰西的壹个人软件构造师 西蒙 Mourier 所开拓,何况由 DarthObiwan 以致Jessynoo 帮助开辟出来的七个软件工具,它能够让分析松散格式 HTML 的劳作就好像深入分析 XML 同样简单,它也是有像样于 System.Xml 命名空间中的 XML DOM 的多多品类,除了可以利用阶层的措施存取 HTML 以外,它也支撑选择 XPath 的不二等秘书技来搜寻 HTML,那会较往年利用文字比对或是 Regular Expression 的比对方式来得更享誉中外。

利用形式

若要使用HTML Agility Pack 元器件,可先上Codeplex 的HTML Agility Pack 网址下载二进位档(同有时间也提供原始程式码、表达档以至HAP Explorer 工具程式可下载),并解压缩后,在专案参预对HtmlAgilityPack .dll 的参阅: 

澳门新浦京娱乐场网站 27

接下来在程式发表参预: 

 

using HtmlAgilityPack;   

 

就可以在程式中使用HTML Agility Pack 的服从。

若要使用 HTML Agility Pack 组件,可先上 Codeplex 的 HTML Agility Pack 网址下载二进制文件(同一时候也提供源代码、表达文件以至 HAP Explorer 工具程序可下载),并解压缩后,在项目步入对 HtmlAgilityPack.dll 的援引。

运用轨范:深入剖判Yahoo 奇摩股票商场的各档股票(stock卡塔尔资源音信。

小编以为那应该是大多写作股票市场资料搜罗的APP的非常重要标的,如果要由证券交易所得到资料授权恐怕要一笔开支,不过由Yahoo 奇摩股票市聚焦剖判并读取资料是无需付费的,只是Yahoo 奇摩股票集镇的HTML 布厅长久以来都以松散型的,不像W3C 是XHTML(此前运用HTML Agility Pack 读取是要体现它的功能),所以要分析它须求花超级多心血,未来大家能够运用HTML Agility Pack 来将以此工作简化。

在Yahoo 奇摩股票市聚焦,贰个个人股的音讯是那般: 

澳门新浦京娱乐场网站 28

而它的 HTML 布局则是:

澳门新浦京娱乐场网站 29

故此只要大家要运用X帕特h 来解读它,则供给先采取下列XPath 先到达上层table 的岗位,再往下获得HTML 中的内容: 

 

/html[澳门新浦京娱乐场网站:项目记录,网络爬虫利器之Html。1]/body[1]/center[1]/table[2]/tr[1]/td[1]/table[1]   

 

为此我们能够创作下列的程式码:  

using System.Net;   
using System.IO;   
using HtmlAgilityPack;   
   
public static void Main(string[] args)   
{   
    // 下载Yahoo 奇摩股票市集资料(典范为2317 鸿海卡塔尔(英语:State of Qatar)   
    WebClient client = new WebClient();   
    MemoryStream ms = new MemoryStream(client.DownloadData(   
""));   
   
    // 使用预设编码读入 HTML   
    HtmlDocument doc = new HtmlDocument();   
    doc.Load(ms, Encoding.Default);   
   
    // 装载第风度翩翩层查询结果   
    HtmlDocument docStockContext = new HtmlDocument();   
   
    docStockContext.LoadHtml(doc.DocumentNode.SelectSingleNode(   
"/html[1]/body[1]/center[1]/table[2]/tr[1]/td[1]/table[1]").InnerHtml);   
   
    // 拿到个人股标头   
    HtmlNodeCollection nodeHeaders =   
 docStockContext.DocumentNode.SelectNodes("./tr[1]/th");   
    // 得到个人股数值   
    string[] values = docStockContext.DocumentNode.SelectSingleNode(   
"./tr[2]").InnerText.Trim().Split('n');   
    int i = 0;   
   
    // 输出资料   
    foreach (HtmlNode nodeHeader in nodeHeaders)   
    {   
        Console.WriteLine("Header: {0}, Value: {1}",   
nodeHeader.InnerText, values[i].Trim());   
        i ;   
    }   
   
    doc = null;   
    docStockContext = null;   
    client = null;   
    ms.Close();   
   
    Console.WriteLine("Completed.");   
    Console.ReadLine();   
}   

 

 

 

读取Yahoo 奇摩个人股资料的程式码(专案类型:主要调整台APP) 

眼前HTML Agility Pack 预设编码应是俄文编码,所以假如是读取汉语HTML 内容的话,不能直接采取HtmlDocument.LoadHtml(卡塔尔 方法,而要透过MemoryStream 使用HtmlDocument.Load(卡塔尔(英语:State of Qatar) 方法,才方可钦定中文的编码。

此模范的结果输出为:

澳门新浦京娱乐场网站 30

有了这几个读取程式后,小编以为能够做的事就广大了,疑似将它以XSLT 调换到分歧的HTML 来突显,或是存到资料库中做任何的行事(解析恐怕图表输出等都能够做到)。

由上列程式能够看来,HTML Agility Pack 的应用其实就和XML DOM 的利用差不了多少,何况也不用再去写不具吸重力的Regular Expression 的一声令下,就足以轻便的施用XPath 来解析HTML,就终于松散的HTML 也得以分析。

就算HTML Agility Pack 能够深入分析成功松散的HTML 文件内容,不过请留意,松散的HTML 内容大概会招致HtmlNode 不是预料的结果,或是在言之有序表格时,档头和内容分化台的气象,那几个部份开拓职员或然必要多加注意。
HTML Agility Pack 也能够用来动态发生HTML 的内容,就不啻XmlDocument 爆发XML 文件内容风流罗曼蒂克致,它也许有疑似CreateElement(卡塔尔(قطر‎、CreateAttribute(卡塔尔、CreateComments(卡塔尔(英语:State of Qatar)与CreateTextNode(卡塔尔(قطر‎ 等方法,其选拔方法与XmlDocument 十分少,由此作者在那就不赘述,请参照他事他说加以侦察:
本表率程式仅以Yahoo 奇摩作为范例标的,实际上若要应用时请注意其剧情授权合约与豁免权利条约,小编仅以此表率显示HTML Agility Pack 的职能,并不意味接受此圭表即等同拿到Yahoo 奇摩的内容授权,若要援用则请小心是否有法定的源委授权,如因援用楷模程式而产生侵害权益难题,一切权利由援用者自负。 

Html Agility Pack 源码中的类大概有二十七个左右,其实不算三个很复杂的类库,但它的功用确不弱,为解析DOM已经提供了十足强盛的功用补助,能够跟jQuery操作DOM比美:)Html Agility Pack最常用的幼功类其实非常少,对剖析DOM来讲,就只有HtmlDocument和HtmlNode那多个常用的类,还应该有叁个HtmlNodeCollection会集类。

帮忙理工科程师具

HTML Agility Pack 本人有提供二个HAP Explorer 的工具,能够让开采人士可以高速的获知要动用的X帕特h 语法,以利开拓人士利用它来拆解深入分析HTML 的岗位资源信息。 

澳门新浦京娱乐场网站 31

只是小编感觉那套工具太过于阳节(可能Simon Mourier 对Windows Forms 或WPF 不熟),由此小编提议合营像FireFox 或是IE8 所提供的开垦者工具(Developer Tools)来机关建设布局XPath 会相比切合,何况它们也都提供能够圈选网页的某八个部份并标示其HTML 地点的本事,那样要建设布局XPath 也会十分的快。

 

参照小说:

 HTML深入剖判利器HtmlAgilityPack

[c#蜘蛛程序之HTML解析利器HtmlAgilityPack]()

开源项目Html Agility Pack完结神速分析Html

[生龙活虎款非常不利的html转xml工具-Html Agility Pack]()

 

HTML Agility Pack的操作起来还是很麻烦,下边大家要介绍的这么些组件是ScrapySharp,他在2个方面针对Html Agility Pack进行了包装,使得分析Html页面不再难熬,幸福指数直线上涨到90分哈。

ScapySharp有了多少个真正的浏览器包装类(管理Reference,Cookie等),别的二个正是使用相像于jQuery同样的Css接收器和Linq语法。让大家选拔起来十二分的爽。它的代码放在 。也得以由此Nuget增加

澳门新浦京娱乐场网站 32

上边大家来看风流罗曼蒂克段拆解深入分析新浪的博客著作的代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using HtmlAgilityPack;
using ScrapySharp.Extensions;
using ScrapySharp.Network;

namespace HTMLAgilityDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            var uri = new Uri("http://www.cnblogs.com/shanyou/archive/2012/05/20/2509435.html");)
            var browser1 = new ScrapingBrowser();
            var html1 = browser1.DownloadString(uri);
            var htmlDocument = new HtmlDocument();
            htmlDocument.LoadHtml(html1);
            var html = htmlDocument.DocumentNode;

            var title = html.CssSelect("title");
            foreach (var htmlNode in title)
            {
                Console.WriteLine(htmlNode.InnerHtml);
            }
            var divs = html.CssSelect("div.postBody");

            foreach (var htmlNode in divs)
            {
                Console.WriteLine(htmlNode.InnerHtml);
            }

            divs = html.CssSelect("#cnblogs_post_body");
            foreach (var htmlNode in divs)
            {
                Console.WriteLine(htmlNode.InnerHtml);
            }
        }
    }
}

Basic examples of CssSelect usages:

 

var divs = html.CssSelect("div");  //all div elements

var nodes = html.CssSelect("div.content"); //all div elements with css class ‘content’

var nodes = html.CssSelect("div.widget.monthlist"); //all div elements with the both css class

var nodes = html.CssSelect("#postPaging"); //all HTML elements with the id postPaging

var nodes = html.CssSelect("div#postPaging.testClass"); // all HTML elements with the id postPaging and css class testClass 

var nodes = html.CssSelect("div.content > p.para"); //p elements who are direct children of div elements with css class ‘content’ 

var nodes = html.CssSelect("input[type=text].login"); // textbox with css class login 

We can also select ancestors of elements:

var nodes = html.CssSelect("p.para").CssSelectAncestors("div.content > div.widget");

参考小说:

HTML Agility Pack:簡單好用的飞跃 HTML Parser

开源项目Html Agility Pack完结高效解析Html

c#中的jQuery——HtmlAgilityPack

Html Agility Pack功底类介绍及使用

.Net深入深入分析html文书档案类库HtmlAgilityPack完整使用表明--搜罗软件开拓更好用

Crawler-Lib Crawler Engine

发现百度重大词示例:BaiduTools.zip

本文由澳门新浦京娱乐场网站发布于www.146.net,转载请注明出处:澳门新浦京娱乐场网站:项目记录,网络爬虫利