最近因为公司业务需要,又有机会撸winform了,这次的需求是因为公司有项目申报的这块业务,项目申报前期需要关注政府发布的相关动态信息,政府部门网站过多,人工需要一个一个网站去浏览和查阅,有时候还会遗漏掉,因此呢,我们打算用爬虫+移动端web来做,我主要负责爬虫和web Api。

爬虫篇

    爬虫主要采用.Net强大的开源解析HTML元素的类库HtmlAgilityPack,操作过XML的童鞋应该很快就可以上手,通过分析XPath来解析HTML,非常的方便的,还有一款不错的叫Jumony,没用过,对HtmlAgilityPack比较熟悉,所以首选了HtmlAgilityPack来作为主力军。

    HtmlAgilityPack的基本使用可以参考这篇 《开源项目Html Agility Pack实现快速解析Html》。

    效果图,多图慎入:

采集广西财政厅例子

  

    因为是政府发布的出来的信息,所以信息的对外开放的,只是机器代替人工来浏览,不会被和谐的,主要采集文章的标题、日期和文章内容,以广西财政厅网站为例子。

First

    加载网站这个就不用说了,先查看网站的字符编码,如图<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> ,然后设置HtmlAgilityPack中的OverrideEncoding属性,再开始加载,不然采集到的是乱码,没有意义。

htmlAgilityPack.OverrideEncoding = Encoding.UTF8;

Second

  

    分析文章列表,浏览器F12查看HTML标签情况,可以分析出XPath为:

//ul[@class='dzjzw_list_main_ul']//li

    文章内容的链接的XPath标签:

//a

    文章发布的时间XPath标签:

//span[@class='date']

示例流程代码:

//获取第一页的内容
HtmlNode row = GetHtmlDoc(htmlWeb, url);
//根据xpath获取列表
var list = row.SelectNodes("//ul[@class='dzjzw_list_main_ul']//li");
foreach (var data in list)
{
HtmlNode node = HtmlNode.CreateNode(data.OuterHtml);
HtmlNode a = node.SelectSingleNode("//a");
HtmlNode date = node.SelectSingleNode("//span['date']");
....
} /// <summary>
/// 这里偶尔会浏览网页失败的,所以失败了多浏览几次
/// </summary
public static HtmlNode GetHtmlDoc(HtmlWeb htmlWeb, string url)
{
try
{
var doc = GetDoc(htmlWeb, url);
if (doc == null)
{
int againIdx = ;
while (againIdx++ < )
{
System.Threading.Thread.Sleep();
doc = GetDoc(htmlWeb, url);
if (doc != null)
break;
}
if (doc == null)
{
var htmlData = HttpHelper.Get<string>(url).Result;//.GetStringAsync(url).Result;
return HtmlNode.CreateNode(htmlData);
}
else
{
return doc.DocumentNode;
}
}
return doc.DocumentNode;
}
catch
{
Log.Error("未能正确访问地址:" + url);
return null;
}
} /// <summary>
/// 加载网页
/// </summary>
public static HtmlDocument GetDoc(HtmlWeb htmlWeb, string url)
{
try
{
return htmlWeb.Load(url);
}
catch (Exception ex)
{
return null;
}
}

都可以使用 HtmlNode.InnerText 来获取到相关值,非常的方便。

Third

    文章详细内容也如此,通过分析XPath来分析即可,最头疼的是翻页的问题,因为政府网站使用的技术一般都是比较那个的,你懂的,有些使用到oncilck来触发的,有些表单提交,要具体问题具体分析了,用Fiddler和浏览器的F12大法来分析翻页数据来源,在这里的例子翻页也比较简单,通过拼接URL来进行翻页即可。

Fourth

    爬取到的之后,再来一个钉钉通知,在群里拉入一个机器人,可以参考钉钉的开发文档

  

    这样我们爬取的消息就第一时间通知到群里的小伙伴啦,是不是很炫酷,哈哈哈。

    项目demo已经上传,仅供学习

    码云:https://gitee.com/Backgrounder/Spider

    Git:https://github.com/EminemJK/Spider

Last

    评论区有提问说部分网站是动态渲染数据的,用XPath分析不到结果,如果数据不是来源于当前界面的HTML,那XPath是分析不到,这时候你需要看它的数据源来自哪里,用Fiddler或者浏览器F12抓一下数据源,类似这个网站(http://www.nnhrss.gov.cn/ecdomain/framework/nnrsw/djiaakgphfalbboelieaiobfgheoldlc.jsp),

查看好数据源,分析出它的数据源来自这个:
http://www.nnhrss.gov.cn/ecdomain/portal/portlets/newslist/newslistcomponent.jsp?goPage=1&pageNum=1&siteID=nnrsw&pageID=djiaakgphfalbboelieaiobfgheoldlc&moduleID=djichlhahfalbboelieaiobfgheoldlc&moreURI=/ecdomain/framework/nnrsw/djiaakgphfalbboelieaiobfgheoldlc/djichlhahfalbboelieaiobfgheoldlc.do&var_temp=eobjphbogdcnbboekapmnnfcbdankadp&currfolderid=null&showChildFlag=false&displayPageLinkFlag=true),
再用xpath直接对数据源分析即可。

————————————————————————————————————————————————————————————————————

根据评论区的大神也提供了其他好用的爬虫库,了解一下:

1> 一线码农    node+cheerio

2>newjajk       Chromedriver

3>ZUOXIANGE   anglesharp

本文已独家授权给脚本之家(ID:jb51net)公众号发布

C#+HtmlAgilityPack+Dapper走一波爬虫的更多相关文章

  1. 深入理解MVC C#+HtmlAgilityPack+Dapper走一波爬虫 StackExchange.Redis 二次封装 C# WPF 用MediaElement控件实现视频循环播放 net 异步与同步

    深入理解MVC   MVC无人不知,可很多程序员对MVC的概念的理解似乎有误,换言之他们一直在错用MVC,尽管即使如此软件也能被写出来,然而软件内部代码的组织方式却是不科学的,这会影响到软件的可维护性 ...

  2. MongoDB_走一波

    Mongodb 一.mongodb的介绍 mongodb的优势 易扩展:NoSQL数据库种类繁多,但是一个共同的特定就是去掉关系数据库的关系型特性.数据之间无关系,这样非常容易扩展 大数据,高性能:N ...

  3. ES6走一波 数组的扩展

    Array flat 数组实例的扁平化方法(浏览器支持不佳) 建议使用 lodash的 flatten

  4. ES6走一波 字符串的扩展

    ES6字符串扩展: 处理大码点字符 字符的Unicode表示法 \uxxxx表示一个字符串,超出 \u0000 ~ \uffff范围,必须用两个双字节形式表示. ES6改进为 将码点放到大括号 可正确 ...

  5. ES6走一波 Iterator

    Iterator---> for ... of 循环 Generator函数原生具有 Iterator接口,所以可采用数组的形式解构赋值

  6. ES6走一波 变量结构赋值

    Destructuring  变量的解构赋值 是一种模式匹配 ES6我关注点之一是用途  能否举些好例子是检验学习到位的方法之一 交换变量值 函数返回多个值 函数入参为对象.数组,内部使用更简洁 意义 ...

  7. ES6走一波 module

    ES6模块设计思想:  尽量静态化,使得编译时就能确定模块的依赖关系,输入.输出的变量.可做静态优化. ES6模块不是对象,而是通过export命令显示指定输出的代码,再通过import命令输入 ex ...

  8. ES6走一波 Proxy/Reflect

    Proxy:像拦截器,对目标对象修改等进行拦截,是一种元编程(meta programming),即修改JS语言本身. //生成proxy实例,两个参数都是对象,targetObj是要拦截的目标对象, ...

  9. ES6走一波 Generator异步应用

    Generator 函数的异步应用 JS异步编程 callback Promise(解决回调地狱) 事件 发布订阅 generator Thunk函数  屁股函数 两次高阶调用的函数 第一次调用的入参 ...

随机推荐

  1. $(function(){})和window.onload的区别

    (1)$(function(){}):DOM节点创建 完成才执行 (2)window.onload:页面所有资源(JS/CSS)加载完成才执行

  2. thinkphp中定义自己的函数

    可以在前台和后台的公共文件夹中common.php中定义自己的函数,这样就可以在控制器中调用,而不需要调用对象了 /** * @name addvtorandp * @author 黄峰1664253 ...

  3. ASP.NET CORE 自定义视图组件(ViewComponent)注意事项

    *红色字体为固定命名,蓝色为一般命名规则,黄色为ASP.NET CORE 默认查找文件名 概要:1.简单ViewComponent的用法 2.ViewComponent控制器返回值  3.注意事项 1 ...

  4. emqtt 试用(三)mqtt 知识

    一.概念 MQTT 协议客户端库: https://github.com/mqtt/mqtt.github.io/wiki/libraries 例如,mosquitto_sub/pub 命令行发布订阅 ...

  5. maven入门(1-4)使用eclipse构建maven项目

    1. 安装m2eclipse插件    要用Eclipse构建Maven项目,我们需要先安装meeclipse插件    点击eclipse菜单栏Help->Eclipse Marketplac ...

  6. 【Java】0X003 面向对象

    一. 什么是面向对象 都说Java是一门面向对象的语言,但什么对象?什么又是面向对象?以下都是我学到的知识和一点自己的理解. 对象是指包含属性和行为的主体. 比如,人有性别.血型.单眼皮或双眼皮等的特 ...

  7. Modelsim的使用——复杂的仿真

    相对于简单的仿真,复杂的仿真是指由多个文件.甚至调用了IP核.使用tcl脚本进行的仿真.其实仿真步骤跟图形化的差不多,只不过每一步用脚本写好,然后再在软件里面run一下,主要过程就是: 1.准备好各种 ...

  8. Hibernate(八):基于外键映射的1-1关联关系

    背景: 一个部门只有一个一把手,这在程序开发中就会设计数据映射应该设置为一对一关联. 在hibernate代码开发中,实现这个业务有两种方案: 1)基于外键映射的1-1关联: 2)基于主键映射的1-1 ...

  9. web开发 c/s结构 和 b/s结构

    web开发 c/s结构 和 b/s结构 c/s结构 --client/server 客户端/服务器机构 如qq b/s结构 -- browser/server 浏览器/服务器结构 如网站 mvc设计 ...

  10. UI前端开发都是做什么的以及html、css、php、js等究竟是神马关系

    第一个问题: 1.UI,是视觉方面的呈现.一个网页首先由UI完成整体设计,然后把每一个模块切图,例如组件.logo.版块等.常用工具:PS,AI,DW. 2.前端,是将UI的设计代码化,因为计算机无法 ...