1、UserAgent
UserAgent的设置能使服务器能够识别客户使用的操作系统及版本、CPU
类型、浏览器及版本等信息。对于一些网站来说,它会检查我们发送的请求中所携带的UserAgent字段,如果非浏览器,就会被识别为爬虫,一旦被识别出来,
我们的爬虫也就无法正常爬取数据了。
收集常见的useragent作为配置文件,每次访问的时候取出一个作为头部发送请求,需要注意的是同一个useragent如果访问频率太高也有可能被识别出来而被禁止,因此可以设置随机选取的策略,每一次访问都随机选取一个。此外对于那些支持m端的网站,有时会根据useragent识别是否为移动端,如果是可能会自动跳转到移动端,如果此时你正在爬取的是web端的话就有可能解析出问题,所以需要注意。
我们可以使用第三方库:
fromfake_useragentimportUserAgent
ua = UserAgent()
print(ua.random)
# Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.93 Safari/537.36
2、IP限制
IP限制在反爬虫中是非常常见的,一般来讲都会有这个限制。可以想像如果单位时间内你的访问次数非常频繁,对于服务器的压力是个不小的开销,因此当网站服务器判定你的访问频率超过某个阈值了,服务器就会对你的IP进行限制,通常限制的策略也不一样,有的可能是限制访问一定的时间比如一天,一周等等,也有可能是永久地限制。
基于IP的反爬限制我们可以通过自己取搭建一个IP池,所谓IP池就是一个拥有很多IP的容器,这个容器可以用一个队列来实现或这其他数据结构。我们需要从一些免费的IP网站上去爬取这些IP,但是这些IP都是不太稳定的,所以我们也需要一个检测模块,从容器中获取IP并检测它是否有效,对于有效的IP我们把它放到容器中,对于无效的IP就从容器中剔除。随后通过暴露接口的方式来获取这些IP,用一个图来表示整个过程:
虽然自己搭建IP池是个不错的方法,但是要知道那些免费的IP稳定性是很差的,因此如果是在生产环境中,对数据的完整性要求很高那么是不建议取这么做的,一般我们还是采取使用付费的IP,例如像阿布云这类的付费IP,这些IP 的稳定性都是比较高的,因此在生产环境中经常使用。
通过验证码来进行反爬取措施是比较常用的方法,特别是对一些要进行登陆的页面,在以前验证码还比较简单的时候可以通过一些简单的图像识别处理来通过,但是现在的验证码越来越复杂,并且已经达到了几乎迷惑人的识别的阶段,那么这个就不好处理了。
验证码识别可以采用一些简单的处理:二值化、中值滤波去噪、分割、紧缩重排(让高矮统一)、字库特征匹配识别。或者使用百度AI开放平台OCR技术。对于复杂的验证码就不要花时间去破解了,即使破解准确率也比较低,可以考虑借助于打码平台。对于模拟登陆我们可以采用维持一个会话的方式,这个也很简单,例如可以使用requests库来申明一个session对象,将我们登陆的信息以表单形式发送登陆后,通过这个会话发送get请求或者post请求。
Ajax动态加载的原理就是当访问一个URL时,会先加载网页源代码,然后会在浏览器中执行Javascript代码,这些代码会加载很多东西,这些请求都属于AJAX请求,通过这些请求会生成很多的数据,然后再将这些数据传输到网页中。所以对这些请求,你直接访问URL是没有数据的。
因此Ajax技术通过在后台与服务器进行少量数据交换,AJAX 可以使网页实现异步更新。这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新。在现在的网站中被广泛采用。
对于使用动态加载的数据,我们只能通过调试工具或者抓包工具去分析Ajax请求的过程,然后去模拟这个请求发送来获取数据,一般我们获取到的数据都是json的数据格式,我们只需要解析json字符串就可以。
对于某些网站会要求登录后才能访问,并且会对同一个账号进行访问的速度进行限制,例如同一个账号下,单位时间内超过某个固定的阈值就会进行限制。
我们可以通过模拟登录然后维持一个会话去发送请求,但是当访问数据较多时,可以研究服务器对账号进行限制的规律,例如笔者曾经写过一个爬虫,当一个账号访问在某个时间段内的次数超过100次后,就会对这个账号进行限制一个小时,此时就必须通过验证码输入后方可访问或者等待一个小时后可以继续访问。但是当你访问次数不超过100次时,再过10分钟就可以再次访问100次。这个解决方法可以通过打码平台解决,但是笔者为了给公司节省支出,采用了多个账号使用时间片的方式解决。我先准备多个账号获取到cookies,然后携带这些cookies取访问,每个cookies值访问90个请求,当前的cookies次数达到90次后,就使用下一个,依次轮转,当轮转一圈后保证时间间隔大于10分钟即可。并取得了很好的效果。
当然还有一种方式就是搭建一个cookies池,动态得获取cookies,然后携带这些cookies去访问。
这种方式常见于小程序或者APP的数据爬取,一般在post请求中较多。例如在某个post请求中会携带一些参数,这些参数中的某个字段是一串变化的字符串,这些字符串的生成一般是通过body中的参数以某种方式组合后做一个md5加密然后发送给服务器。例如很多网站会采用的signature签名机制。
对于这种没有别的办法,只能分析js代码,看看它是如何构造这段字符串的,然后通过Python中的库去模拟js构造的过程,然后发送请求。对于移动端的请求,例如在爬取小程序,就需要你能够获取小程序中的js代码,一般获取到的小程序的js代码都是经过混乱处理的,例如全篇的a,b,c,d作为变量名和函数名,这个需要你找到直接相关的代码段去分析构造过程。
对于APP的话,没办法,只能通过一部root后的安卓手机,反编译apk,然后拿到反编译后的代码,由于安卓用Java进行开发,因此需要你具备一定的Java基础。此外,你拿到的源码并不是完整的源代码,在反编译处理过后会有很多,未能正常反编译的代码。例如笔者就遇到过在某一个构造字符串的方法中(这个方法就是构造加密字段的方法)未能反编译出源代码,这就需要你能够阅读字节码指令,从这些字节码指令中,翻译出执行过程,这就需要你有一定的JVM的知识,笔者记得当时花了好几天才破解。因此对于这部份就需要具备一定的逆向经验。
有些通过ajax加载的json数据并不是json字符串,而是通过压缩或者进行了某种处理的,例如使用base64进行转换的数据。
对于这样的数据,我们可以通过Python中的一些库对压缩数据解压缩,但是你得知道这些数据是采用什么方式压缩的,一般可以去尝试用不同的方法解压缩看看哪种能得到正确的字符串。由于base64是可逆向的,如果使用这种方式直接逆向转换就行了。
爬虫中的反爬方式还是很多的,我这里只是列出了一些比较常见的方式以及解决方法。对于反爬虫和反反爬虫这对博弈的存在我们需要花时间和经历去研究。
本文的文字及图片来源于网络,仅供学习、交流使用,不具有任何商业用途,如有问题请及时联系我们以作处理
想要获取更多Python学习资料可以加
QQ:2955637827私聊
或加Q群630390733
大家一起来学习讨论吧!