接触爬虫一段时间后,多多少少都会遇到反爬的问题。这里就简单讲一些反爬原理、反扒方式,同时说一些对付这些机制的方法。这里所提到的只不过是蜻蜓点水罢了。
原因
反爬的出现大多归咎于:
- 爬虫访问过于频繁,给服务器造成压力
- 数据资产流失
出于利益保护意识,很多网站都不希望自己的数据被爬,那么他们应对的措施就是反爬虫!
反爬机制与破解机制
身份识别反爬
请求参数
User-Agent
user-agent是何物
user-agent是一种请求头,服务器可以从它对应的值来识别用户端的一些信息。它通常由浏览器标识、版本信息、渲染引擎标识组成。
绕过原理
一般情况下,我们通过浏览器访问某网站的方式:
爬虫访问某网站的方式:
说白了,你可以把那只当作是套了头套伪装成浏览器的臭虫!user-agent相当于那个头套,欺骗服务器。
应对方式
所以爬虫实际上是模拟浏览器对服务器发送请求来得到数据。当然爬虫默认是遵守Robot协议的,既然是只臭虫了,还遵守什么协议。如果不加user-agent是及其容易被服务器识别出是爬虫(裸奔的感觉)。
道高一尺,魔高一丈。不是加了user-agent就万能了,比如将常用的请求头放入服务器的黑名单,当有网络请求时检测它们的请求头判断是不是爬虫,如果是就不允许访问。不过这种很容易产生误伤,正常客户会莫名躺枪。
说回正题,user-agent不能单一写死,可以试试fake-useragent
fake-useragent是一个python库,用前先安装:
|
|
以下是在Scrapy中实现的方法
- 在settings.py上使用
|
|
- 在middlewares.py中使用
先关掉settings.py中的UserAgent
|
|
之后在process_request()中修改:
|
|
- 在spider上添加
|
|
Cookie
原理(该原理摘自《python3 反爬虫原理与绕过实战》)
Cookie不仅可以用于Web服务器的用户身份信息存储或状态保持,还能够用于反爬虫。大部分的爬虫程序在默认情况下只请求HTML文本资源,这意味着它们并不会主动完成浏览器保存Cookie的操作。
Cookie反爬虫指的是服务器端通过校验请求头中的Cookie值来区分正常用户和爬虫程序的手段,这种手段被广泛应用在Web应用中,例如浏览器会自动检查响应头中是否存在Set-Cookie头域,如果存在,则将值保存在本地,而且往后的每次请求都会自动携带对应的Cookie值,这时候只要服务器端对请求头中的Cookie值进行校验即可。
服务器会校验每个请求头中的Cookie值是否符合规则,如果通过校验,则返回正常资源,否则将请求重定向到首页,同时在响应头中添加Set-Cookie头域和Cookie值。
应对方式
- 手动处理
这种方式比较简单,就是直接用抓包工具把cookie信息粘贴到headers中。不过这种方法有弊端,cookie有时效性和变化性,如果过了有效期或者自身的值变动了,这种方法使用起来就很鸡肋。
|
|
- 自动处理
这种方法可以使用session对象实现自动处理,用构造函数requests.Session()返回一个session对象。这个对象可以像requests一样像服务器发送请求,在请求过程中产生cookie。此时session对象会自动保持cookie值。
|
|
行为识别反爬
请求频率
爬虫行为与普通用户最明显的区别就是,爬虫的请求频率太高了。
IP
IP 反爬原理
正常用浏览器发送请求,速度不会太快、请求间隔随机、请求次数少。但是爬虫却和这些相反。它发送的请求速度快,间隔固定,量大。通过这几点就可以识别是否是爬虫。
如何应对IP反爬
有攻就有防,对付IP反爬还是算比较简单的。只需要换一个别的IP去访问就行。
通俗的举个例子:现在有个政策是防止未成年沉迷游戏,规定非放假日不得玩游戏,直到满18岁成年为止这些束缚才能解开。小A未满18岁,但是玩游戏受到限制,无法体现出他对游戏的热爱,于是他拿着妈妈的身份证去绑定游戏实名验证,从而逃过了这个束缚
这个例子的身份证就是一个典型的代理IP作用。实际上真正给服务器发送请求的是代理端,然后代理端将得到的响应返回给请求端。
应对方式
- 设置代理IP(单一IP)
|
|
- IP代理池(多IP)
这里推荐一个开源的IP代理池ProxyPool ,不用重复造轮子,直接使用就行
ProxyPool简介
爬虫代理IP池项目,主要功能为定时采集网上发布的免费代理验证入库,定时验证入库的代理保证代理的可用性,提供API和CLI两种使用方式。
使用
- clone代码
|
|
- 安装依赖
|
|
- 修改配置
|
|
运行
- 启动Redis,即打开redis-server.exe(得先安装Redis)
- 方法一:启动调度程序
1
python proxyPool.py schedule
- 写个demo读取数据库中的代理
1 2 3 4 5
import redis r = redis.StrictRedis(host="127.0.0.1", port=6379, db=0) result = r.hgetall('use_proxy') print(result.keys())
结果:
- 方法二:启动webApi服务
1
python proxyPool.py server
启动后打开http://127.0.0.1:5000/ 将会看到:
在爬虫中使用
|
|
结尾
还有很多种反爬手段,比如说数据加密反爬(CSS数据偏移/数据图片/特殊编码/自定义字体/js逆向加密)、验证码反爬等。这些没有提到是因为我还才疏学浅,还没有研究透彻,就不拿出来说了。等我研究透彻了,会开新的文章。
参考
- python3 反爬虫原理与绕过实战