说起采集,其实我是个外行,以前拔过阿里巴巴的客户数据,在我博客的文章:C#+HtmlAgilityPack+XPath带你采集数据(以采集天气数据为例子) 中,介绍过采集用的工具,其实很Low的,分析Html,用开源的HtmlAgilityPack就很快解决问题了。我个人并不是技术特别深,所以只要是解决问题就OK了。但每一次需求并不是完全一致的,对上面那篇文章的采集,无需登录,是非常灵活的,但是这次碰到的稍微有点变态,虽然最后任务完成,但总结方案还是很low的,但觉得还是有必要分享出来,希望对以后碰到这个问题的人有用。

1.采集目目标特点与分析

由于采集目标比较商业性,不便于透露。所以文字多一点。大家仔细看。

目标网站特点以及初始需求:

1) 要求登录,并且登录安全验证非常严,怎么严就不说了,就是非常困难,动不动还得手机验证。

2) 网站数据经过分析,都是直接登录后通过https请求来获取JSON数据,解析就可以用,但是里面也有变态的地方,就是有些参数是加密的,直接扒历史数据有困难;

3) 初期网站每天需要采集的URL类型超过60+左右,但总的采集链接数超过2000+,因为一个类型的URL,有很多不同的区域的数据需要采集;

  最需要说明的是该项目所有的页面分析,解析和采集入库工作由2个毕业生来做,我也没时间去做很深入的研究,他们C#语法还不是很熟练,所以技术方案上不能太复杂,越简单越好。

  先看看我这方案的过程,由于工作太多,刚开始想法是很好的,但是越做到后面,发现越麻烦。  

2.方案第一版-Low到爆,别笑话

该采集最大的难点就是登录的问题,由于安全性太高,所以一开始我就彻底放弃了程序模拟登录的思路,虽然后面的过程有点曲折,但这也是新人很快能搞定所有采集的关键。否则在前面就不知道要花费多少时间。说说初步的想法:

1.既然登录后就可以采集数据,那就人工登录一次,做一个asp.net web页面,点击开始,就可以使用WebClient请求JSON数据。因为在同一个浏览器,登录的session啥都可以共享,我是这么想的。

2.请求数据后直接解析到数据库;

3.大量的URL多线程执行应该速度很不错,So,没啥压力;

大神一眼都能看出问题哈,想法很美好,现实是很残酷。

3.碰壁后的第二版方案

基本JSON的解析工作差不多让新人完成后,自己做了个asp.net 的web测试,真是xxx,获取不到JSON数据,一调试,才知道,WebClient请求这样搞是不行的,在web页面直接请求url也是不行的,就是所谓的跨域问题,虽然没搞过前端,但也能理解。好吧,这么low的问题,真的不好意思拿出来说,谁叫没动手试一下呢。那怎么破?所以有了第二版方案:

1.既然不能跨域,那就让你跨。在大石头和邱哥的提示下,用webbrowse来搞吧。

2.使用webbrowse控件手动登录后,直接在控件中请求新的URL,获取JSON值;对,这样看你跨不跨过去。。。测试一个链接也是可行的。

然后发现真的是 万事开头难,中间难,结尾更难。。。想法很美好,现实是很残酷!

  

4.最终方案第三版

4.1 该死的completed事件

按照方案2,很快所有的链接加进去了,开始采集,又杯具了。只有第一个链接能执行。。。调试,很快发现问题,也怪学艺不精,以前没用过webbrowse啊:

webbrowse请求url后,是不能马上获取到请求的html文本的,要在completed事件中处理获取到的html文本(JSON字符串)才行。怎么破?

既然要用事件,那也挺好,不断请求,不断解析,把处理逻辑加到事件中就好了。很OK,继续进行中。。。

4.2 没想到URL请求太快

没跑几个URL,xxx,问题又来了:当初由于采集的页面和链接太多,所以做了几个菜单,点击后分别采集不同的任务,但是点击后这个请求不断的发,这个事件执行是有问题的,很多没执行到,有一些中间变量值被覆盖了,请求太快啊。。。怎么破?那我就设置个长一点的时间,确保每次加载并处理完成才去请求下一次。好,说干就干,看了一下每个页面的解析,10秒足够了,那就搞10秒请求一次。。。。继续进行中

还是xxx,过几天这个网站改版了,改动很多,很无奈啊,但生活还得继续。还好我们的解析都是利用工具生成的东西,改起来很快。具体可以参考这篇文章:C#+HtmlAgilityPack+XPath带你采集数据(以采集天气数据为例子)

改版的一个主要变化是URL类型增加了很多,所以数据也增加了很多,以前是总共也就50-60个类型的链接需要采集,但是改版后,上升到2000+,增加了很多子类型的数据,你懂的。然后发现这个10秒一次,啥时候能采集完成啊。。。而且很明显,10秒对很多URL来说多很多,不是白白浪费吗。。。好吧,知道问题,那就想办法解决,如果连问题都不知道,那就杯具了。

都搞10秒不公平,那就搞个timer吧,定时执行,但是在请求之前和解析之后,动态修改这个timer的间隔执行时间,一秒也不浪费啊。比如请求之前设置间隔是10秒,事件里面解析之后设置为1毫秒。。。哈哈,So easy 。。。。

4.3 想开得和飞机一样快,但火车的速度都没到

xxx,跑了上百个之后,发现还是太慢,任务太多啊。。。每一个好几秒也hold不足。。。。那怎么破,分析一下原因,很明显请求加载速度很快,慢在处理那里,主要是事件处理那里不好加多线程。那怎么破,办法总比问题多。。。怕啥。。。

反正就是每天采集下,那弄个中间缓存呗。当然本地缓存也是可以的啊,这里特意用了一个windows版的redis做了个测试,目的是有2个,因为我们组的项目中redis用的比较广泛,新的毕业生来虽然没玩过,但我们日常也在说,以后项目也会用到,所以特意在这个地方教他们使用了一下,比使用Oracle当然更简单,平时他们都是用Oracle,所以理解起来也不费劲。所以新的方案又来了:

使用timer来控制发送请求的间隔,在完成事件中,把json值和相关解析要用到的变量缓存到redis中,然后开一个多线程从redis里面取值进行解析工作。。。所干就干,用了30行代码改造了一下,很快就测试。。。不得不说,Paralller.For好用啊,请求的速度提高到60-80个/秒,速度很快了,解析4个线程开起来,速度也杠杆的,没计算具体的时间,但是解析完也就比请求完多个几分钟。开发机安装东西太多,而且CPU比较鸡肋,所以开4个线程已经100%了,所以这个效率也够了。至此,整个系统的核心工作让2个新人折腾来折腾去,给他们思路,和简单的示例代码,就搞定了。

5.总结

当然过程的细节还有很多要注意,特别是解析工作,在前一篇文章中说过了。

其实从分析页面链接,到解析,到最后数据入库,代码给他们过指导,但大部分工作是新人完成的。这个过程让他们也对项目和数据有了很深的了解,自己也会更轻松一些,毕竟从头接触,出了问题,他们可以排查。在从头到尾的过程中,还有很多细节,他们自己也排查和发现了很多bug,但总归要给他们试错的机会,能改正就好。在总体方案的变化下,从解决碰到的问题,要简单的优化,多线程,redis使用,都有了直观的了解和认识(为什么要用,什么时候要用,为什么一开始不考虑?),多几行代码,速度瞬间提升。。。

解决问题的方法比问题要多,思路决定出路,用简单的方法解决问题就OK!

快速发现问题并能有解决方案是很重要的一个方面。

  方案整体代码不能提供,不过从百度拔的一些公共代码都在上面了,以及前面一篇文章中有介绍。其他都是细节问题,主要是这个方案过程比较曲折一点点。

再谈C#采集,一个绕过高强度安全验证的采集方案?方案很Low,慎入的更多相关文章

  1. 对EasyDarwin开源项目后续发展的思考:站在巨人的肩膀上再跳上另一个更高的肩膀

    2017 EasyDarwin现状 自从2012年EasyDarwin项目创立开始,经过了快5年了,时光飞逝,如今EasyDarwin已经发展成为了不仅仅是一个单纯的开源流媒体服务器项目了,已经是各种 ...

  2. Another Look at Events(再谈Events)

    转载:http://www.qtcn.org/bbs/simple/?t31383.html Another Look at Events(再谈Events) 最近在学习Qt事件处理的时候发现一篇很不 ...

  3. [转载]再谈百度:KPI、无人机,以及一个必须给父母看的案例

    [转载]再谈百度:KPI.无人机,以及一个必须给父母看的案例 发表于 2016-03-15   |   0 Comments   |   阅读次数 33 原文: 再谈百度:KPI.无人机,以及一个必须 ...

  4. 日志采集框架Flume以及Flume的安装部署(一个分布式、可靠、和高可用的海量日志采集、聚合和传输的系统)

    Flume支持众多的source和sink类型,详细手册可参考官方文档,更多source和sink组件 http://flume.apache.org/FlumeUserGuide.html Flum ...

  5. 程序员肺被切掉一块还得去加班... 再谈“工作996,生病ICU”

    如题,为什么要说再谈“工作996,生病ICU”,因为996问题早已不是一个新问题,在我最近刚出版的新书<SOD框架“企业级”应用数据架构实战>写作期间,爆发了一次程序员“起义”,出现了一个 ...

  6. 再谈SQL Server中日志的的作用

    简介     之前我已经写了一个关于SQL Server日志的简单系列文章.本篇文章会进一步挖掘日志背后的一些概念,原理以及作用.如果您没有看过我之前的文章,请参阅:     浅谈SQL Server ...

  7. Support Vector Machine (3) : 再谈泛化误差(Generalization Error)

    目录 Support Vector Machine (1) : 简单SVM原理 Support Vector Machine (2) : Sequential Minimal Optimization ...

  8. Unity教程之再谈Unity中的优化技术

    这是从 Unity教程之再谈Unity中的优化技术 这篇文章里提取出来的一部分,这篇文章让我学到了挺多可能我应该知道却还没知道的知识,写的挺好的 优化几何体   这一步主要是为了针对性能瓶颈中的”顶点 ...

  9. 浅谈HTTP中Get与Post的区别/HTTP协议与HTML表单(再谈GET与POST的区别)

    HTTP协议与HTML表单(再谈GET与POST的区别) GET方式在request-line中传送数据:POST方式在request-line及request-body中均可以传送数据. http: ...

随机推荐

  1. 百度MIP页规范详解 —— canonical标签

    百度MIP的规范要求必须添加强制性标签canonical,不然MIP校验工具会报错: 强制性标签<link rel="/^(canonical)$/"> 缺失或错误 这 ...

  2. 如何一步一步用DDD设计一个电商网站(四)—— 把商品卖给用户

    阅读目录 前言 怎么卖 领域服务的使用 回到现实 结语 一.前言 上篇中我们讲述了“把商品卖给用户”中的商品和用户的初步设计.现在把剩余的“卖”这个动作给做了.这里提醒一下,正常情况下,我们的每一步业 ...

  3. Apache Ignite高性能分布式网格框架-初探

    Apache Ignite初步认识 今年4月开始倒腾openfire,过程中经历了许多,更学到了许多.特别是在集群方面有了很多的认识,真正开始认识到集群的概念及应用方法. 在openfire中使用的集 ...

  4. .NET 提升教育 第一期:VIP 付费课程培训通知!

    为响应 @当年在远方 同学的建议,在年前尝试进行一次付费的VIP培训. 培训的课件:点击下载培训周期:10个课程左右,每晚1个半小时培训价格:1000元/人.报名方式:有意向的请加QQ群:路过秋天.N ...

  5. Js new到底发生了什么

    在Js中,我们使用了new关键字来进行实例化 那么在这个new的过程中到底发生了什么? 关于构造函数的return 正常来讲构造函数中是不用写return语句的,因为它会默认返回新创建的对象. 但是, ...

  6. 前端学HTTP之报文首部

    前面的话 首部和方法配合工作,共同决定了客户端和服务器能做什么事情.在请求和响应报文中都可以用首部来提供信息,有些首部是某种报文专用的,有些首部则更通用一些.本文将详细介绍HTTP报文中的首部 结构 ...

  7. [译]处理文本数据(scikit-learn 教程3)

    原文网址:http://scikit-learn.org/stable/tutorial/text_analytics/working_with_text_data.html 翻译:Tacey Won ...

  8. Win10 UWP开发系列——开源控件库:UWPCommunityToolkit

    在开发应用的过程中,不可避免的会使用第三方类库.之前用过一个WinRTXamlToolkit.UWP,现在微软官方发布了一个新的开源控件库—— UWPCommunityToolkit 项目代码托管在G ...

  9. JavaScript基础

    JavaScript基础 JavaScript是一门编程语言,浏览器内置了JavaScript语言的解释器,所以在浏览器上按照JavaScript语言的规则编写相应代码之,浏览器可以解释并做出相应的处 ...

  10. 使用rowid抽取数据方法以及大数据量游标卡住的应对

    平时工作的时候,经常会遇到这种事情,从一个大表A中,抽取字段a在一个相对较小B的表的数据,比如,从一个详单表中,抽取几万个用户号码的话单出来.这种时候,一般来说, 做关联查询: create tabl ...