网站内容抓取(web不再面对知识产权保护的问题,如何反爬虫?(图))
优采云 发布时间: 2022-04-05 18:16网站内容抓取(web不再面对知识产权保护的问题,如何反爬虫?(图))
前言
网络是一个开放的平台,它为网络从1990年代初诞生到今天的蓬勃发展奠定了基础。然而,所谓的成败也很小,开放的特性、搜索引擎、简单易学的html和css技术,让web成为了互联网领域最流行、最成熟的信息传播媒介;但是现在作为商业软件,web是平台上的内容信息的版权是不能保证的,因为与软件客户端相比,你的网页内容可以通过一些爬虫程序以非常低的成本实现,并且技术门槛很低,这也是本系列文章要讨论的——网络爬虫。
有很多人认为,网络应该始终遵循开放的精神,页面上呈现的信息应该毫无保留地与整个互联网共享。但是,我认为随着今天IT行业的发展,网络不再是当年与pdf竞争的所谓“超文本”信息载体。它已经基于轻量级客户端软件的思想。存在。随着商业软件的发展,网络也不得不面对知识产权保护的问题。试想一下,如果原创的优质内容不受保护,网络世界中抄袭盗版猖獗,这其实有利于网络生态的健康发展。这是一个缺点,而且它'
未经授权的爬虫程序是危害web原创内容生态的罪魁祸首。因此,为了保护网站的内容,首先要考虑如何反爬。
从爬行动物的攻防来看
最简单的爬虫是几乎所有服务器端和客户端编程语言都支持的 http 请求。只要对目标页面的url进行http get请求,就可以获得浏览器加载页面时的完整html文档。我们称之为“同步页面”。
作为防御方,服务器可以根据http请求头中的User-Agent检查客户端是合法的浏览器程序还是脚本爬虫,从而决定是否使用真实的页面信息内容发送给你。
这当然是最小的小儿防御方法。作为进攻方,爬虫完全可以伪造User-Agent字段。甚至,只要你愿意,在HTTP get方法中,请求头的Referrer、Cookie等所有字段都可以被爬虫轻松处理。伪造。
这时,服务器就可以根据你声明的浏览器厂商和版本(来自User-Agent),使用浏览器http头指纹来识别你http头中的每个字段是否符合浏览器的特性。如果匹配,它将被视为爬虫。该技术的一个典型应用是在 PhantomJS 1.x 版本中,由于底层调用了 Qt 框架的网络库,http 头具有明显的 Qt 框架的网络请求特征,可以服务器直接识别。并被拦截。
另外,还有一个比较异常的服务器端爬虫检测机制,就是在所有访问页面的http请求的http响应中植入一个cookie token,然后在这个页面异步执行的一些ajax接口上学. 检查访问请求中是否收录cookie token,返回token表示这是一次合法的浏览器访问,否则表示刚刚发出token的用户访问了页面html但没有访问执行js后调用的ajax在 html 请求中,很可能是爬虫。
如果你不带token直接访问一个接口,说明你没有请求过html页面,而是直接向页面中应该通过ajax访问的接口发起网络请求,这显然证明你是一个可疑的爬虫。知名电子商务公司网站亚马逊采用了这种防御策略。
以上是基于服务器端验证爬虫程序可以玩的一些套路。
基于客户端js运行时的检测
现代浏览器赋予 JavaScript 强大的能力,所以我们可以将页面的所有核心内容作为 js 异步请求 ajax 获取数据然后渲染到页面中,这显然提高了爬取内容的门槛。这样,我们就将爬虫和反爬的战斗从服务端转移到了客户端浏览器中的js运行时。接下来说一下结合客户端js运行时的爬取技术。
刚才提到的各种服务器端验证,对于普通的python和java语言编写的HTTP爬虫程序,都有一定的技术门槛。毕竟,Web 应用程序是未经授权的抓取工具的黑匣子。很多东西都需要一点一点的去尝试,而一套耗费大量人力物力开发的爬虫程序,只要网站作为防御者可以轻松调整一些策略,攻击者也需要花费同样的时间再次修改爬虫的爬取逻辑。
此时,您需要使用无头浏览器。这是什么技术?其实说白了就是程序可以操作浏览器访问网页,这样写爬虫的人就可以通过调用浏览器暴露给程序的API来实现复杂的爬取业务逻辑。
事实上,这并不是近年来的新技术。曾经有基于webkit内核的PhantomJS,基于火狐浏览器内核的SlimerJS,甚至还有基于IE内核的trifleJS。如果你有兴趣,可以看看这里和这里有两个无头浏览器采集列表。
这些无头浏览器程序的原理其实就是对一些开源浏览器内核C++代码进行改造和封装,实现一个无需GUI界面渲染的简单浏览器程序。但是这些项目的通病是因为他们的代码是基于fork官方webkit和其他内核的某个版本的trunk代码,所以跟不上一些最新的css属性和js语法,还有一些兼容性问题,不如真实的GUI浏览器发行版运行稳定。
其中,最成熟、用得最多的应该是PhantonJS。之前写过一篇关于这种爬虫识别的博客,这里不再赘述。PhantomJS 有很多问题,因为它是单进程模型,没有必要的沙箱保护,浏览器内核的安全性较差。此外,该项目的作者已经宣布他们将停止维护这个项目。
现在谷歌浏览器团队已经在 Chrome 59 发布版本中开放了 headless mode api,并开源了一个基于 Node.js 调用的 headless chromium dirver 库。我还为这个库贡献了一个centos环境部署依赖安装列表。
Headless Chrome 可以说是 Headless Browser 中独一无二的杀手锏。由于它本身就是一个 chrome 浏览器,它支持各种新的 CSS 渲染特性和 js 运行时语法。
基于这种方法,爬虫作为攻击方可以绕过几乎所有的服务器端验证逻辑,但是这些爬虫在客户端js运行时还是存在一些缺陷,比如:
基于插件对象的检查
if(navigator.plugins.length === 0) {
console.log('It may be Chrome headless');
}
基于语言的检查
if(navigator.languages === '') {
console.log('Chrome headless detected');
}
基于 webgl 的检查
var canvas = document.createElement('canvas');
var gl = canvas.getContext('webgl');
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');
}
基于浏览器细线属性的检查
if(!Modernizr['hairline']) {
console.log('It may be Chrome headless');
}
检查基于错误的img src属性生成的img对象
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');
}
}
基于以上一些浏览器特性的判断,它基本上可以秒杀市面上大部分的Headless Browser程序。在这个层面上,网页爬虫的门槛其实是提高了,要求编写爬虫程序的开发者不得不修改浏览器内核的C++代码,重新编译一个浏览器,而以上特性对浏览器来说是很重要的。内核的改动其实不小,如果你尝试过编译Blink内核或者Gecko内核你就会明白对于一个“脚本小子”来说是多么的难了~
此外,我们还可以根据浏览器的UserAgent字段中描述的浏览器品牌、版本、型号信息,检查js运行时、DOM和BOM的各个native对象的属性和方法,观察特性是否符合浏览器这个版本。设备应具备的功能。
这种方法称为浏览器指纹识别技术,它依赖于大型网站对各类浏览器的api信息的采集。作为编写爬虫程序的攻击者,你可以在无头浏览器运行时预先注入一些js逻辑来伪造浏览器的特性。
另外,在研究Robots Browser Detect using js api在浏览器端的时候,我们发现了一个有趣的trick。可以将预先注入的js函数伪装成Native Function,看一下下面的代码:
var fakeAlert = (function(){}).bind(null);
console.log(window.alert.toString()); // function alert() { [native code] }
console.log(fakeAlert.toString()); // function () { [native code] }
爬虫攻击者可能会预先注入一些js方法,用一层代理函数作为钩子包裹一些原生api,然后用这个假的js api覆盖原生api。如果防御者在函数 toString 之后基于对 [native code] 的检查来检查这一点,它将被绕过。所以需要更严格的检查,因为bind(null) fake方法在toString之后没有函数名,所以需要检查toString之后的函数名是否为空。
这个技巧有什么用?在这里延伸一下,反爬虫防御者有一个Robot Detect方法,就是在js运行的时候主动抛出一个alert。文案可以写一些业务逻辑相关的。当普通用户点击OK按钮时,肯定会有1s甚至是alert。对于更长的延迟,由于浏览器中的alert会阻塞js代码的运行(其实在v8中,他会以类似进程挂起的方式挂起isolate context的执行),所以爬虫作为攻击者可以选择使用上面的窍门,就是在页面所有js运行前预先注入一段js代码,伪造alert、prompt、confirm等所有弹窗方法。如果防御者在弹出代码之前检查他调用的alert方法是否仍然是原生的,则这种方式被阻止。
对付爬行动物的灵丹妙药
目前最可靠的反爬虫和机器人巡检手段是验证码技术。但是,验证码并不意味着必须强制用户输入一系列字母和数字。还有很多基于用户鼠标、触摸屏(移动端)等行为的行为验证技术。其中,最成熟的是基于机器学习的谷歌reCAPTCHA。区分用户和爬虫。
基于以上对用户和爬虫的识别和区分技术,网站的防御者需要做的就是对该IP地址进行封锁或者对该IP的访问用户施加高强度的验证码策略。这样攻击者就不得不购买IP代理池来捕获网站信息内容,否则单个IP地址很容易被封杀,无法被捕获。爬取和反爬取的门槛已经提升到IP代理池的经济成本水平。
机器人协议
此外,在爬虫爬取技术领域,还有一种叫做robots协议的“白道”方式。Allow 和 Disallow 声明每个 UA 爬虫的爬取授权。
然而,这只是君子之约。虽然它有法律上的好处,但它只能限制那些商业搜索引擎的蜘蛛程序,你不能限制那些“野爬爱好者”。
写在最后
网页内容的爬取与反制,注定是一场魔高路高的猫捉老鼠游戏。你永远不可能用某种技术完全挡住爬虫的去路,你能做的就是增加攻击。用户爬取的成本,以及关于未经授权的爬取行为的更准确信息。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。