爬虫3-爬虫防范

——参考博客 https://www.zhuyingda.com/blog/article.html?id=17

机器人协议 爬虫领域有一个“白道手段”——robots协议,这是一个君子协议,即用allow和disallow声明各个页面的爬取授权,但除了商业搜索引擎的爬虫程序,野生爬虫根本不会管你这个(明白了scrapy框架中的ROBOTSTXT_OBEY 默认为True)

1. 服务器端的检测

服务器端针对user-agent、referer、cookie等字段进行检查,但这种检查方式存在明显的缺点,这些字段都是可以轻易伪造的,甚至还能不断变换这些字段和ip代理,伪装成多个用户在访问,所以这种检查方式还是不太靠谱。

另一种检查方式是,服务器端可以检查浏览器http头指纹,根据声明的浏览器厂商和版本,来鉴别http header中的各字段是否符合该浏览器的特征。典型的就是PhantomJS 1.X版本采用的Qt框架,在http头里面有明显的Qt框架网络请求特征,可以被服务器直接识别拦截

还有一种变态的检测机制,服务器对所有的页面请求,在http response中种下一个cookie token,然后在这个页面内异步执行一些的ajax接口里面去校验来访请求是否含有cookie token,并将token传回表明这是一个合法的浏览器,否则说明刚刚下发token的用户只访问了页面的html,并没有执行js代码调用ajax请求,很可能就是个爬虫程序。

~思考:这些方法基本上都可以被selenium+chromedriver+ip代理绕过

2. 客户端的检测

结合参考博客,查询了js和html的知识看懂了博主的想法,在页面加入js代码进行检测确实是一种可靠的方法。

2.1 plugin对象的检查

navigator对象相关介绍:http://www.w3school.com.cn/jsref/dom_obj_navigator.asp

首先介绍navigator对象,Navigator 对象包含有关浏览器的信息,plugin : 插件。所以通过js代码,我们可以直接检查无头浏览器的重要信息。

if(navigator.plugins.length == 0) {
    console.log("It may be Chrome headless");
}

navigator.plugins会返回一个数组,里面的元素代表浏览器已安装的插件,无头浏览器通常是没有插件的。

2.2 language的检查

通过navigator.language可以获取浏览器界面的语言设置,navigator.languages可以获取一个数组,里面存储的是浏览器用户所有的次选语言。而无头浏览器的navigator.languages返回的是空字符串。

if(navigator.languages == "") {
    console.log("Chrome headless detected");
}

2.3 webGL的检查

普通的网页组成:HTML、JavaScript

WebGL网页组成:HTML5、JavaScript和GLESL ES(着色器语言 OpenGL ES)

WebGL通过H5中的<cavas>元素(画布)定于绘图区域,然后通过JavaScript内嵌GLSL ES在cavas中绘制三维图形

var canvas = document.createElement('canvas'); //获取cavas属性
var gl = canvas.getContext('webgl');  //获取webgl上下文
// WEBGL_debug_renderer_info扩展是WebGL API的一部分
// 借助此扩展,能够检索有关用户图形驱动程序的调试信息,这里主要获取vendor和renderer两个值
var debugInfo = gl.getExtension('WEBGL_debug_renderer_info');  
var vendor = gl.getParameter(debugInfo.UNMASKED_VENDOR_WEBGL);
var renderer = gl.getParameter(debugInfo.UNMASKED_RENDERER_WEBGL);

if(vendor == "Brian Paul" && renderer == "Mesa OffScreen") {
    console.log("Chrome headless detected");
}

有人对比了linux上的普通谷歌浏览器和无头模式下vendor和renderer两个值的区别

http://www.webhek.com/post/detecting-chrome-headless.html)

普通谷歌浏览器:vendor:'Google SwiftShader' renderer:'Google Inc.'

无头模式: vendor:'Brian Paul' renderer:'Mesa OffScreen'

“Mesa OffScreen”——它是没有使用任何 window 系统的渲染技术的名称

“Brian Paul” ——开源 Mesa 图形库的最初的程序。

当然不是所有的无头浏览器都是这个两个值,不过这里确实提供了一种参考思路。

2.4 浏览器hairline特性的检查

if(!Modernizr["hairline"]) {
    console.log("It may be Chrome headless");
}

Modernizr 是一个 JavaScript 库,可以检测用户浏览器的 HTML5、CSS3 特性的支持状况。

无头模式下没有hairline特征,这个特征是用来检测是否支持hidpi/retina hairlines的

2.5 图片加载失败

var body = document.getElementsByTagName("body")[0];
var image = document.createElement("img");
image.src = "http://iloveponeydotcom32188.jg";
image.setAttribute("id", "fakeimage");
body.appendChild(image);
image.onerror = function(){
    if(image.width == 0 && image.height == 0) {
        console.log("Chrome headless detected");
    }
}

在正常的chrome浏览器中,加载失败的图片的大小跟浏览器的zoom有关,但肯定不为0。而在无头浏览器里,这种图片的宽和高都为0

~思考:selenium+chromedriver正常模式,除了没有插件外其他4种方法应该都可以绕过?

2.6 反爬虫的银弹?

验证码虽然是一种有效的机器人检查方法,但是爬虫可以将验证码下载到本地,调用阿里云提供的验证码识别服务逃过检查,或者直接人工识别。而拖动滑块的验证码似乎也可以让代码重复执行拖动操作?但是按顺序点击应该无法绕过。

另一种谷歌成熟的验证技术也是非常有效方法——Google reCAPTCHA,基于用户鼠标、触屏等行为的验证技术

https://developers.google.com/recaptcha/


作者:bitterz
本文版权归作者和博客园所有,欢迎转载,转载请标明出处。
如果您觉得本篇博文对您有所收获,请点击右下角的 [推荐],谢谢!
原文地址:https://www.cnblogs.com/bitterz/p/10202211.html