很早就想写一篇关于爬虫的文章了,无奈最近工作比较忙,闲暇时间又基本全都投入到了学习新东西上面,所以这篇文章耽搁了好久(其实都是借口,时间挤挤还是有的,哈哈),特别是和群里面的小伙伴约好一起写的,结果小伙伴已经写了两篇了,我还没有开始,十分忧伤。答应人家这个周末会发一篇,所以今晚特来兑现承诺,抱歉,久等了。
我最开始接触爬虫是因为对这个东西比较好奇,慢慢接触之后.......额,上瘾了,根本停不下来。你会发现这个东西太有意思了,怎么可能会有这么好玩的东西。所以导致我花了好多的时间在爬虫上面,同时收获也是蛮大的。掌握了这门技术,基本可以改变你的日常上网习惯,和获取信息的思维,最重要的是还可以泡妞,(什么还可以泡妞的啊?),嗯,没错,还没上车的小伙伴抓紧打卡上车了。
首先我先声明一下,这篇文章不同以往,不会是那种很干,很枯燥,看完还会有懵懵的感觉的文章,我会有尽量活跃,略带幽默的记录一下我学习爬虫的经验以及感受。可能你看完我的文章不一定会学会爬虫,但是你很有可能会因为好奇就入坑。这样就很nice了,我的目的就在于此 。还有就是我本身最多算一个三流的业余虫师,当你看到此篇文章的时候一定要用怀疑的态度去阅读,如果我有讲述错误的地方,欢迎留言。下面正式带大家走进爬虫。
首先爬虫是个什么东西呢?其实很简单,爬虫就是一个获取资源,然后加工资源,最后得到并保存所需的数据的一个东西。下面就分这三个步骤为大家介绍一下。(以下主要以Python环境为主,最后也会推荐java环境下一些好用的工具。)
1、获取资源
我在Python环境下获取网络资源主要使用Requests,为什么要使用Requests呢?当然是简单,高效啊,使用Requests可以很容易的获取基于HTTP协议的网络资源。下面引用文档中的一句话:“非专业使用其他 HTTP 库会导致危险的副作用,包括:安全缺陷症、冗余代码症、重新发明轮子症、啃文档症、抑郁、头疼、甚至死亡。”从这句话中足以看出Requests 的自信以及威力。关于Requests 的具体使用方法我就不一一介绍了,太多了,在这里献上文档《Requests 文档》。既然现在我们已经有了获取资源的工具,那我们怎么获取资源呢?答案很简单,只需找出获取资源的接口,以及正确的参数即可。在这里推荐两款比较好用的工具,Google Chrome,以及Postman。前者用于找出资源的真正接口,以及参数。后者用于模拟调用这个接口。下面来介绍一下两款工具。想必Google Chrome大家都非常的熟悉了,一款非常好用的浏览器,并且也是一款非常好的前端调试工具。下面带大家看一下如何用Google Chrome找到我们要获取资源的接口,以我经常浏览的一个视频资源网站为例。打开一个页面后,按F12让浏览器进入调试模式,并看到如下信息。
1、Status 代表HTTP请求的状态码。
2、Type 代表请求的资源类型。
3、Initiator 代表引发此请求的引发者,即引发该请求的源码位置。
4、Size 代表所请求资源的大小。
5、Time代表完成请求的耗时。
我用红线圈起来了一条请求,从页面上的信息可以看出来它是图片请求,当我们点击这一条的Name栏位的时候,会弹出此条请求的具体信息。具体如下:
从上面的信息我们可以得到此条调用请求的地址(Request URL),以及请求的方式(Request Method),返回的状态码(Status Code)。以上三条可以说是此次调用的基础信息,也是必要信息。那其他的都没有用吗?也不是的,如果你看了Requests的文档你就知道,我圈起来的后面打叉的基本是一些标识以及一些HTTP协议的优化。最后一条是用户终端信息,大多数网站会校验的。下面我们去Postman里面试一下。
我们可以看见这个网站的资源只需要相应的资源地址就可以下载了,是不是好简单,哈哈,确实是好简单,(看我对你们多好,给你们找了个这么容易上手的站点。哈哈)。讲到这里基本最简单的资源获取思路大家应该已经明白了。POST请求同理,稍微比GET请求麻烦一点,(就是多拼凑一点参数)。一带而过了哈。
讲到这里有些小伙伴就要问了,我懒得去分析什么请求,特别是对方网站使用了ajax混淆技术,来防止我们爬虫。额,这种情况是比较头疼的,不过也有比较笨的方法,就是找一个容器把页面资源下载下来并运行其包含的js代码,当然Python中也有相应的工具库,我们可以通过传入原始数据,通过工具内核渲染完了之后拿到解析好的页面,就像你看见的一样。然后再进行数据抽取,验证,再去请求对应的接口地址就好了。没错此办法确实可行,就是效率不太好,多了好多无用的请求,如果可以接受的话确实是个偷懒的好办法。这里推荐selenium+phantomjs组合。有些人又要问了,就算是渲染完的页面我也懒得去解析,怎么办,还有办法吗?额,有的你可以利用selenium+浏览器驱动+浏览器内核,实现就像人一样的操作浏览器界面。不过开发阶段建议用正常浏览器,因为你可以看到脚本在操作浏览器,哪里出了问题更加直观一点,调试好了之后可以使用无界面浏览器内核。这样速度更快一点。有人要问了还有没有更加简单的,哎,洗洗睡吧,哈哈。。以上介绍的方法虽然简单但是有个明显的缺点,一旦网站的页面有变化就失效了,还需要从新修改脚本。
讲完了简单的资源获取的思路之后我来总结一些我遇到的问题,以及解决方法。
1、采集过快导致IP被封
解决办法基本有两种,第一种使用代理,此方案的采集速度完全取决于你的代理数量以及代理质量。第二种限速,找到此站点的限速规则,(不断尝试),然后通过此规则限制爬虫的采集速度即可,但是效率太慢,基本不能接受。
2、网站反爬虫策略
一般的网站都会有反爬虫策略,通过这些策略来判定你是否为机器人,一般简单的策略有,是否有终端信息,以及站点要求的默认特殊字段等,这一类属于参数校验类的都比较好解决,但是有的站点要求输入验证码,甚至拼图片的验证方式,还有识别图片中的内容,这就比较头疼,也没有什么比较好的方法。
3、基于用户信息的校验
有一些网站会在你浏览器本地保存一些数据,包括你的用户信息,以及一些用来识别你是否为机器人的一些信息。比如它会记录你的IP,填写表单或者数据的速度,访问速度等等。如果你这个用户频繁的切换IP,在多地登录,就可能被认定为爬虫,或者说是你填写表单太快了,也有可能被认定为爬虫。但是这些本地的数据有些是不加密的,咱们可以自己改,哈哈。还有一些加密的就比较麻烦,直接去翻JS找算法可能会累死,没有什么好的办法。还有一些会同时限制用户和IP,这种基本只能通过代理加多用户去解决了。
当然以上这些场景肯定是覆盖不全的,希望大家积极留言补充。
2、加工资源
所谓的加工资源就是数据抽取,或者叫做数据清洗。用大白话说就是:你去获取资源,站点把这个接口的所有东西都返回给你了,你要去这堆东西里面挑挑捡捡,把那些你需要的数据挑出来,然后校验这些数据是否正确。那些挑出来的并且正确的东西才是我们真正需要的。讲到这里必须介绍下我常用的一个工具库:“Beautiful Soup”,具体的使用方法见文档《Beautiful Soup》。可以根据不同的需求选择自己的解析器,如果没有特殊要求的话推荐使用lxml HTML。
看到这里可能有人会问问什么不介绍下XPath,当然要介绍啊,我比较喜欢用XPath这种方式去解析HTML资源,一方面是因为习惯问题,(用习惯了),另一方面是因为XPath解析的时候只加载你所指定的那部分内容,性能比较好一点。而基于DOM树的那种解析方式虽然简单,但是需要加载整个内容,相对来说不管是内存消耗,还是查找效率都要次一点。下面列举一些XPath的语法,以下截图来自“w3school”,原文地址《XPath》:
关于XPath 还有函数部分没有介绍,如果感兴趣可以去原文中查看使用方法。
下面介绍下数据验证的方法,什么叫做数据验证呢,简单的说就是你要爬取一部分手机号,你要验证下这些数据是不是真的有效的手机号。像这些文本数据我一般使用正则来验证其正确性,不过正则也有明显的缺点,就会性能消耗大,如果验证通过率低,而且表达式复杂建议大家采取分级验证。什么是分级验证呢?简单地说就是你先验证手机号是不是十一位数字,不满足就滤掉了,后面更加复杂的检验就不要进行了。再此我又要推荐一款工具了,可以说是正则神器:“RegexBuddy”,谁用谁知道。而且它支持好多种语言的正则,非常的方便。还可以debug。
最后要说到数据保存了,这一块其实没有什么特别的就像平常项目里面的持久化方案就好了,可能每个公司,每个人的习惯都不太一样。哈哈。。(一笑而过)
最后要讲到好玩的东西了,还有就是如何泡妞的,哈哈。你们可以去GitHub上面找一个叫做“ItChat”的项目,(开源不易,请点star),它是一个开源的微信号个人接口,其实就是基于weixinWeb的,跟爬虫的原理差不多,利用网页版的HTTP接口。用它可以实现什么好玩的功能呢?比如说消息自动回复,消息定制化批量发送,事件提醒,基于电脑的远程文件管理器,查天气,,,查。。。。。。一切爬虫可以查到的东西,(当然后台逻辑需要自己去开发)。这能泡妞吗?听我细细道来,你想啊,有了这个东西,每天你可以定时早上出门前给女朋友发送今天的天气,温度,适合的衣物等信息,或者是定时发送一些笑话啊没或者是你特定的消息,再或者是在你比较忙碌的时候在后台对接一个专门用于和女朋友聊天的机器人,让她在等你的时候不至于很无聊。(哈哈,亲身试验过,效果不错的。)还有更多更加好玩的东西等着我们去发现,比如QPython,在自己的手机上安装一套Python环境,可以进行开发调试,也可以部署web,或者爬虫之类的,唯一的缺点就是大部分工具库都不支持。
最后说下java中的爬虫常用工具,HTTPClient,Jsoup,等,其实跟Python中的大多数工具用法都是一样的,而且名字也都基本相同。学会哪一个,在学另一个都会触类旁通的。加油!!!!