记录自己爬虫的一些感想
因工作中会有一点爬虫的任务,从开始接触到现在能爬取一般的网页,就在这里记录自己的经历,我思故我在嘛。但不是专业爬虫工程师,而且本菜鸟完全把这里当做了自己的笔记本,所以语言措辞未加修整,也是把大家当做自家兄弟来看,嘻嘻。
那时候刚进公司,什么也不懂,第一个任务是爬取网站上的ip,维护一个小的实时有效ip池,供公司大佬们做爬虫使用。之前也没有接触过爬虫,好在我是接手项目,不是自己重新开始写,让我写也搞不出来嘛。需求已经很明确了,项目也大概给我讲了一下,就是普通的java项目,ant构建。这个项目做得事情就是1、爬取网页上的免费ip。2、验证ip有效性后去重入库。所以我要做的就是第一步,这就是我做爬虫的开始了。
想一想还是挺有意思的,我爬虫就是为了抓取给别人做爬虫使用的ip?好吧,就是这样的。而且我也可以使用ip,但是我抓取的频率较低,所以没有使用ip。就是那时候接触公司的爬虫框架,这个框架是公司自己写的,还是挺不错的,代码规范,逻辑清晰,也很全面,代码我也看过,但是自愧到现在我也写不出一个一样的项目。使用的是java,包装了Apache的httpclient,就是这样了,有了框架,我的工作就很简单了,因为流程全都是一样的,况且现在连这个流程我也免了,因为我接手了项目,这个之前也是在用着的。
终于要开始了。。。我首先是寻找目标网页,当然是找软柿子捏了,找了大概二十来个目标,我也没有BFS,DFS,如果想抓取两页就取两个URL,所以看到这里大家就明白了,我这个时候接触的爬虫就是下载页面,然后解析内容,拿到自己想要的数据,也可能是那时候的页面还算简单,感觉就是还算挺顺利,完全没感受到什么前后端分离,数据和页面在一起,天然拿得到,唯一遇到的反爬虫就是有的网页上的ip和端口加密了,下载来的数据和页面看到的就是不一样,但是请教了公司大佬,三下五除二搞定,因为当时没有记录,现在忘记怎么做的了(这就是我现在写这篇文章的原因了,现在的事情都快要忘记了),大概是使用了某些数学运算转换一下,算是比较简单的干扰。还有一种是使用图片展示结果,这个确实束手无策,因为我自己也没有识别过图片,公司有人能识别,但是要看是什么样的图片,简单的就可以弄,如果要花时间很多,就需要考虑了,当时也没必要为了一个网页搞这个,所以我直接忽略了这个网站,心里想,算你厉害,中间还了解了爬虫与反爬虫的爱恨情仇,一些有趣的故事,大家都是道高一尺,魔高一丈的做着,也没见谁彻底压倒过谁,现在似乎感觉有所倾斜,反爬虫更厉害了,可能是一般的爬虫人员都是单兵作战,面对的却是一个团队,当然不排除也有很厉害的人,结果现在大家的成本都变的越来越高了。这阶段我接触的爬虫就是下载http页面,给我一个URL,给你里面的内容。
后来,越来越多的网页前后分离,这也是趋势了。此阶段拿到的URL访问之后直接是数据,纯数据,解析起来方便多了,直接就是json,那还解析个毛啊。唯一的注意就是参数,有些是get请求,URL传参数,有些是post,body里带参数,body里有直接text的,有json的,有些需要cookie,有时需要考虑cookie的有效期。这就是理想的情况了,遇到这种最开心,比以前更简单了。但是这时候也就出现了验证码,禁ip。对于需要验证码的,这就要识别验证码了,这个可以自己做,也可以使用第三方,权衡成本做选择。对于禁ip的,就是要换ip了,所以也就有了我刚开始的工作,也可以直接买别人的ip,或者自己搭ip服务器。关于cookie,遇到cookie一直有效的,不用换的,直接抓包获取,对于需要登陆账号的,有些cookie也是一直有效,至少是长时间有效,但是如果是需要频繁换账号的,就需要从初始URL一直访问下去,得到cookie后继续访问下一个URL。还有就是遇到参数加密的,有些如果你是传入固定参数,自然不用破解,使用加密后的字符串就行,如果你是变化的参数,就需要研究一番了。多数是js加密,需要找到js,因为前端总是要和服务端通信的,这就是我们的起点,找到开始访问服务端的地方,一步一步往回走,回溯这些参数哪里来的,怎么来的,最后会有一个源头。最终不管是复杂还是简单,都是这样的套路来。
这个时候的工具就是fiddler,没有系统学习过fiddler,所以现在我用到的功能就是几点:
- 抓取请求,理清网站的大致逻辑,看看传递的是什么参数,得到的是什么结果。如果是固定加密参数或者长期有效cookie,直接从fiddler里面取。
- 模拟请求,在测试阶段,可以使用fiddler的composer模拟请求,看是否通过。
- 转发请求,通过rules->customize rules打开fiddlerScript添加自己的规则对拦截的请求做处理,一般是转发请求到自己的应用,以便修改或者获取参数。
- 替代服务端响应,autoresponder,调试js可以使用,能替换js,这里的功能,使用上一点也可以做到,如果你不修改参数,使用这个代替就简单一些。
关于爬取一系列相关的网页,也就是做一件事情,这时候就是要理清前端和服务端交互的逻辑,分析哪些参数是哪一步请求得来的。我最近有一个任务就是这种,其中的逻辑我想了很久,才大致有个轮廓,现在爬虫已经写完,而且工作的不错,但是我也不能确定服务端的逻辑就是我想的那样。这个网站最开始很简单,没有很多反爬虫措施,我写的也顺利,后来陆续升级,添加了很多,网站在此期间也一度不稳定,我都怀疑人生了,总觉得是自己代码问题,经历了网站的改进,体验一把反爬虫的爱恨情仇,印象好深刻o(╥﹏╥)o。首先我是用使用了ip的,如果不使用ip,就需要填写验证码,我为了简单的来,就使用了ip。从第一步开始,就会生成一个csrf参数,好在这个参数是服务端生成后返回来的,后面的每一步请求都必须带上这个参数,同时这个参数应该和ip绑定了(一个ip可以对应n个csrf,清理cookie后会变),我试过中间换ip,失败。经过一系列请求后,到达A请求,之前是直接请求A,可以过,后来一直过不了,无意间测试发现,等待十几秒,再请求A,就可以过,瞬间惊呆,还有这种操作,事后想来也有道理,当初没仔细分析,手工在页面请求这一步时候也会弹出等待页面,提示最多需要60秒处理请求,这一步猜测就是等待csrf验证和绑定ip阶段。之后会有desc参数,一共有两个,这个参数经过分析js,发现是用一个叫fingerprint的参数产生的,这个fingerprint可以看做浏览器的指纹,据说识别浏览器成功率是94%。主要是根据浏览器的useragent,plateform,插件信息等进过MurmurHash算法加密后生成,生成了fingerprint后,再加上发送请求之前的最后五点鼠标位置及其时间戳生成一个desc,另一个desc直接根据fingerprint生成。这是目前的版本,不知道下次升级什么时候。
曾经还遇到过,对传给服务器的所有参数进行加密处理生成新的sign参数,作为新的参数连同之前的参数一起传给服务器,由服务器验证是否合法,这个也是要分析js,但是当时没有弄出来,使用了替代方案。最近看到一个超级复杂的,不过没有继续分析,就是他不给你调试,按F12后直接无限debug,这个查了一下类似在js里写的无限循环debugger,好像每次还生成新的栈,无限耗用内存,浏览器最后卡死。这种可以禁掉浏览器的debug来解决,但是自己也不能打断点debug了,减少了分析的手段,很有效果啊。想到的方法就是替换js,使用删除了这种含有debugger代码的版本替换,这就要先寻找对应代码在哪里,然后做处理了。我没有尝试,目前没有经验。而且不是专业前端,好多写法都搞不懂,js写法又比较灵活多样,代码经过压缩后展示,分析起来还是挺费劲的。我没接触过专业爬虫工程师,但是总感觉也好辛苦,和我们一样,作为搬砖的兄弟,混口饭吃,谋生不易(排除爬虫大佬o(╥﹏╥)o)。