您的位置:首页 > 编程语言 > C#

C# 爬虫 、 网页数据抓取 随记

2014-08-21 16:25 316 查看
第一次用 C# 写数据抓取,遇到各种问题。开始写模拟登录的时候发现有验证码,要突破验证码才能弄,好吧,然后去找验证码破解的代码,弄了半天摸不着门,然后只能硬着头皮继续弄,看了一大堆代码,也试了一大堆,发现都不通用,后来明白了点原理,首先去掉噪点,干扰线等等各种东西,然后还要将彩色的验证码转成黑白,还要进行字体切割,如果字体有粘连,对于我们这些初学者(门外汉), 那还是放弃吧,切割之后再进行每一个每一个像素进行编码,白色0,黑色1,好像是这样,我也没太懂,再读取字体库模型里面的字进行对比,如果达到百分比多少以上,就却认这个验证码是什么,一个一个进行对比,最后就组成了一个完整的验证码,弄了一天发现我既不会弄字体库,也不会用代码切字,不可能完成验证码破解,所以就放弃了破解,另寻他法。

网上说验证码可能会保存在cookie里面,好吧,抱着试试的态度去弄,模拟浏览器发送数据,请求验证码,FF调试, 发现cookie里面还真有验证码,就这样,验证码这个就过了,再来弄登录。

登录,首先要跟踪目标网页的逻辑,看它是怎么传递参数登录成功的。我这个就是先发送请求 加密用户名和密码,然后再把加密后的发送给后台进行登录,这个就没啥说的。这期间遇到的问题就是发送请求,弄了半天不成功,原因就是那时发送的一个ajax请求,必须设置调用了哪个方法,网站找的一般都是直接请求后台,而不是发出ajax请求,所以在这里又瞎捣弄了一通。

关键代码:

request.Headers.Add("X-AjaxPro-Method", "方法名");


登录成功了之后,就是到了抓取页面了,首先获取到抓取页面的html,再进行分析它是怎么提交数据,怎么返回的,都传了些什么参数等等。抓取页面没什么问题,然后就是模拟查询数据了,那网站是用asp.net写的,有很多的隐藏域控件,所以发送请求的时候有非常多的参数,都不知道是干嘛用的,反正我觉得有用的就只有查询单号就可以了,模拟发送了半天都报500错误,这个就是模拟的参数有问题,服务器读取不了,我把所有能设置都弄了一遍,一个一个对上,发现没有什么地方有错误,弄了2天,就卡在这里了,是在没办法,后来偶然间发现,提交的数据和页面隐藏域的数据有一点点不一样,特殊字符都是进过转码了,然后就想了想以前写的代码传参,发现传数据的时候,都是需要经过
UrlEncode转码,再进行传输的,隐藏域的值虽然是控件自动生成的,但传输应该也还是需要转码,想到这 ,然后二话不说,就开始对参数进行转码

HttpUtility.UrlEncode(string);
居然成功了,太烧脑细胞了,虽然对些老手来说,可能这些都不知道一提,但第一次接触还是有写麻烦的。

对了,其中还遇到一个问题,就是读取 html 之后获取 字符串html里面参数的问题,在页面上当然好获取,现在全是一堆字符串,真难搞,所以就找了个dll非常好用,支持 xpath ,和xmlDocument一样用法,

部分代码:

HtmlDocument htmlDocument = new HtmlDocument();
htmlDocument.LoadHtml(html.Replace("\r", "").Replace("\n", ""));
HtmlNodeCollection collection = htmlDocument.DocumentNode.SelectSingleNode("/html/body/div").ChildNodes;

foreach (HtmlNode htmlNode in collection)
{
var tempId = htmlNode.Attributes["id"].Value;
}


标红的部分就是 xpath 规则,

还可以根据属性来获取对应的节点:

htmlDocument.DocumentNode.SelectSingleNode("/html/body/div[2]/input[@id='__EVENTVALIDATION']");
这个是 :HtmlAgilityPack 下载地址:点击打开链接

最好多看看这个网站的评论。里面有许多人的问题,或许能帮到。

好了就写这么多,后面把代码整理一下发上来,然后开始循环抓取数据了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: