当前位置: 首页 > 后端技术 > Python

如果有人问你爬虫技术,请让他看这篇文章

时间:2023-03-25 21:26:30 Python

web是一个开放的平台,这也奠定了web从20世纪90年代初诞生到今天近30年的蓬勃发展。然而,俗话说得好即败,而开放的特性、搜索引擎、简单易学的html、css技术,让web成为互联网领域最流行、最成熟的信息传播媒介。但是现在作为商业软件,网页平台上的内容信息的版权是没有保障的,因为相对于软件客户端来说,你网页中的内容可以用很低的成本实现,技术门槛也很低一些爬虫明白了,这就是本系列文章要探讨的内容——网络爬虫。许多人认为,网络应该始终遵循开放精神,页面上呈现的信息应该毫无保留地与整个互联网共享。不过,我认为,随着IT业发展到今天,web已经不再是当年与pdf一争高下的所谓“超文本”信息载体了。它已经是基于轻量级客户端软件的思想。存在。商业软件发展到今天,web不得不面对知识产权保护的问题。试想,如果原创的优质内容得不到保护,抄袭盗版在网络世界泛滥,其实不利于网络生态的健康发展。也很难鼓励生产更多优质的原创内容。未经授权的爬虫抓取程序是危害原始网页内容生态的罪魁祸首。因此,为了保护网站内容,首先要考虑如何防范爬虫。从爬虫攻防角度来说,最简单的爬虫就是一个几乎所有服务端和客户端编程语言都支持的http请求。只需要向目标页面的url发起httpget请求,浏览器加载页面的时候就可以获取到url。完整的html文档,我们称之为“同步页面”。作为防御方,服务端可以根据http请求头中的User-Agent来判断客户端是合法的浏览器程序还是脚本抓取程序,从而决定是否将真实的页面信息内容发送给你.这当然是最小的防御手段。爬虫作为攻击方,完全可以伪造User-Agent字段。甚至,只要你愿意,在http的get方法中,请求头的Referrer、Cookie等所有字段都可以很容易被爬虫仿冒爬取。这时候服务器就可以根据你声明的浏览器厂商和版本(来自User-Agent),通过浏览器http头的指纹来识别你的http头中的各个字段是否符合浏览器的特性。如果匹配,则将其视为爬虫。该技术的一个典型应用是在PhantomJS1.x版本中,由于底层调用了Qt框架的网络库,http头具有明显的Qt框架网络请求特征,可以直接识别并拦截由服务器。另外还有一个比较变态的服务端爬虫检测机制,就是在所有访问页面的http请求的http响应中植入一个cookietoken,然后到这个页面异步执行的ajax接口去检查检查是否访问请求中包含一个cookietoken,返回token说明这是一次合法的浏览器访问,否则说明刚下发token的用户访问了页面html但是没有访问执行完js后调用的ajaxhtml请求,很可能是爬虫。如果不带token就直接访问一个接口,说明你没有请求html页面,直接在页面中向应该ajax访问的接口发起网络请求,这显然证明你是可疑的爬虫。知名电商网站亚马逊就是采用这种防御策略。以上就是基于服务端验证爬虫程序可以玩的一些套路。基于对客户端js运行时的检测,现代浏览器赋予了JavaScript强大的能力,所以我们可以将页面的核心内容全部做成js异步请求ajax获取数据渲染到页面上,明显提高了爬虫的爬行能力内容门槛。依靠这种方式,我们将反爬虫和反爬虫的战斗从服务端转移到了客户端浏览器中的js运行时。接下来说说爬虫爬取技术结合客户端js运行时。刚才说的各种服务端验证,对于普通的python和java语言编写的http爬虫来说,都有一定的技术门槛。毕竟,Web应用程序是未经授权的爬虫程序的黑匣子。很多事情都需要一点一点的去尝试,而一套花费大量人力物力开发的爬虫程序,作为防御方的网站只要轻松调整一些策略,攻击者需要花费同样多的钱有时间再次修改爬虫的爬取逻辑。此时,你需要使用无头浏览器。这是什么技术?其实说白了就是让程序操作浏览器访问网页,这样写爬虫的人就可以通过调用浏览器暴露给程序的API来实现复杂的爬取业务逻辑。其实这并不是近几年的新技术。曾经有基于webkit内核的PhantomJS,基于Firefox浏览器内核的SlimerJS,甚至还有基于IE内核的trifleJS。如果你有兴趣,可以看看这里和这里的两个无头浏览器。收集列表。这些headless浏览器程序的原理其实就是将一些开源的浏览器内核C++代码进行改造封装,实现一个简单的无GUI界面渲染的浏览器程序。但是这些项目的通病是因为他们的代码是基于fork官方webkit等某个版本内核的主干代码,所以无法跟进一些最新的css属性和js语法,还有一些兼容性问题,不如release版本的GUI浏览器运行稳定。其中最成熟、使用最多的应该是PhantonJS了。这种爬虫的识别我以前写过一篇博客,这里不再赘述。PhantomJS存在很多问题,因为它是单进程模型,没有必要的沙箱保护,浏览器内核的安全性较差。此外,该项目的作者已声明将停止维护该项目。现在GoogleChrome团队已经在Chrome59release版本中开放了headlessmodeapi,并开源了一个基于Node.js调用的headlesschromiumdirver库。我也为这个库贡献了一个centos环境部署依赖安装列表。HeadlessChrome可谓是HeadlessBrowser中独树一帜的杀手锏。由于本身是chrome浏览器,所以支持各种新的css渲染特性和js运行时语法。基于这种方式,作为攻击方的爬虫几乎可以绕过所有服务器端的验证逻辑,但是这些爬虫在客户端的js运行时仍然存在一些漏洞,比如:基于插件对象的检查if(navigator.plugins.length===0){console.log('可能是Chromeheadless');}基于语言的检查if(navigator.languages===''){console.log('Chromeheadlessdetected');}基于varcanvas=document.createElement('canvas');vargl=canvas.getContext('webgl');vardebugInfo=gl.getExtension('WEBGL_debug_renderer_info');varvendor=gl.getParameter(debugInfo.UNMASKED_VENDOR_WEBGL);varrenderer=gl.getParameter(debugInfo.UNMASKED_RENDERER_WEBGL);if(vendor=='BrianPaul'&&renderer=='MesaOffScreen'){console.log('Chromeheadlessdetected');}基于浏览器hairline特性检查if(!Modernizr['hairline']){console.log('可能是Chromeheadless');}检查基于错误的imgsrc属性var生成的img对象body=document.getElementsByTagName('body')[0];varimage=document.createElement('img');image.src='http://iloveponeydotcom32188.jg';image.setAttribute('id','fakeimage');body.appendChild(图像);image.onerror=function(){if(image.width==0&&image.height==0){console.log('Chromeheadlessdetected');}}根据上面一些浏览器特性的判断,基本可以秒杀市面上绝大部分无头浏览器程序。在这个层面上,实际上是提高了网络爬虫的门槛,要求编写爬虫程序的开发者不得不修改浏览器内核的C++代码,重新编译一个浏览器,以及,以上几点的特点,对浏览器内核的改动其实不小。如果你尝试过编译Blink内核或者Gecko内核,你就会明白“脚本小子”有多难~更进一步,我们根据浏览器的UserAgent字段描述的浏览器品牌和版本型号信息,属性jsruntime、DOM、BOM的各个原生对象和方法都可以查看其特性是否符合该版本浏览器的要求。特征。这种方法被称为“浏览器指纹检测”技术,它依赖于大型网站收集各类浏览器的API信息。作为编写爬虫程序的攻击者,可以在HeadlessBrowserruntime中预先注入一些js逻辑来伪造浏览器的特性。另外,在研究RobotsBrowserDetect浏览器端jsapi的使用时,发现了一个有趣的trick。您可以将预注入的js函数伪装成本机函数。看看下面的代码:varfakeAlert=(function(){}).bind(null);console.log(window.alert.toString());//functionalert(){[nativecode]}console.log(fakeAlert.toString());//function(){[nativecode]}爬虫攻击者可能会预先注入一些js方法,用一层代理函数作为hook包裹一些nativeapi,然后用这个伪造的jsapi覆盖nativeapi。如果防御者根据toString函数后[nativecode]的检查来判断这个,那么就会被绕过。所以需要更严格的检查,因为bind(null)的fake方法在toString之后没有函数名,所以需要检查toString之后的函数名是否为空。这个技术有什么用?这里再延伸一下,有一个RobotDetect的方法是针对反爬卫士的,就是在js运行的时候主动抛出一个alert。更长的延迟,因为浏览器中的alert会阻塞js代码的运行(实际上在v8中会以类似进程挂起的方式挂起isolatecontext的执行),所以作为攻击者的爬虫程序可以选择使用上面的技巧,就是在页面上运行所有js之前,预先注入一段js代码,hook所有的alert、prompt、confirmforged等弹窗方法。如果防御者在弹窗代码前先检查自己调用的alert方法是否为native,这种方式就会被阻断。反爬虫银弹目前反爬虫和机器人检测方式是最靠谱的验证码技术。但是,验证码并不意味着必须强制用户输入一串字母数字。也有很多基于用户鼠标、触摸屏(移动端)等的行为验证技术,其中最成熟的是GooglereCAPTCHA,它是基于机器学习的。区分用户和爬虫。基于上述诸多对用户和爬虫的识别和区分技术,网站防御者最终应该做的是屏蔽该ip地址或者对该ip的访问用户强加高强度验证码策略。这样,攻击者就必须购买ip代理池来抓取网站信息内容,否则单个ip地址很容易被屏蔽而无法抓取。爬虫和反爬虫的门槛提高到ip代理池的经济成本水平。除了robotprotocol之外,在爬虫爬取技术领域还有另外一种“白道”方式,叫做robotsprotocol。您可以访问网站根目录下的/robots.txt。比如我们看一下github的机器人协议。Allow和Disallow声明了每个UA爬虫的爬取权限。然而,这只是君子之约。虽然有法律上的好处,但它只能限制那些商业搜索引擎的蜘蛛程序,而你不能限制那些“野爬虫”。写在最后,网页内容的爬取与反击,注定是一场魔幻高低的猫鼠游戏。你永远无法用某种技术完全堵住爬虫的路。Whatyoucando这只是增加了攻击者的捕获成本,实现了对未授权捕获行为的更准确理解。