当前位置: 首页 > 科技观察

Python爬虫技术的门户

时间:2023-03-11 22:52:15 科技观察

web是一个开放的平台,也奠定了web从1990年代初诞生到今天近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语法,存在一些兼容性问题,不如真正的GUI浏览器的发布版本运行稳定。其中最成熟、使用率最高的应该是PhantonJS。这种爬虫的识别我以前写过一篇博客,这里不再赘述。PhantomJS存在很多问题,因为它是单进程模型,没有必要的沙箱保护,浏览器内核的安全性较差。此外,该项目的作者已声明将停止维护该项目。现在GoogleChrome团队已经在Chrome59release版本中开放了headlessmodeapi,并开源了一个基于Node.js调用的headlesschromiumdirver库。我也为这个库贡献了一个centos环境部署依赖安装列表。HeadlessChrome可谓是HeadlessBrowser中独树一帜的杀手锏。由于本身是chrome浏览器,所以支持各种新的css渲染特性和js运行时语法。基于这种方式,作为攻击方的爬虫几乎可以绕过所有服务器端的验证逻辑,但是这些爬虫在客户端的js运行时仍然存在一些漏洞,比如:基于插件对象的检查if(navigator.plugins.length===0){console.log('ItmaybeChromeheadless');}基于语言的检查if(navigator.languages===''){console.log('Chromeheadlessdetected');}基于webgl的检查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');}基于对浏览器细线特征的检查if(!Modernizr['hairline']){console.log('ItmaybeChromeheadless');}检查基于错误的imgsrc属性生成的img对象varbody=document.getElementsByTagName('body')[0];variimage=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('Chromeheadlessdetected');}}根据上面一些浏览器特性的判断,基本可以秒杀市面上大部分的headless浏览器程序。在这个层面上,它实际上提高了网络爬取的门槛。要求开发者编写爬虫程序,需要修改浏览器内核的C++代码,重新编译浏览器。而且,上述这些特点对于浏览器内核的改动其实也不小。如果你尝试过编译Blink内核或者Gecko内核,你就会明白这对于一个“脚本小子”来说有多难~更进一步,我们还可以根据浏览器的UserAgent字段中描述的浏览器品牌、版本型号信息,JS运行时、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来覆盖本机api。如果防御者根据toString函数后[nativecode]的检查来判断这个,那么就会被绕过。所以需要更严格的检查,因为bind(null)的fake方法在toString之后没有函数名,所以需要检查toString之后的函数名是否为空。这个技术有什么用?这是一个扩展。反爬卫有一个RobotDetect方法,在js运行时主动抛出告警。文案可以写一些与业务逻辑相关的东西。普通用户点击OK按钮肯定会有1s甚至更长的延迟,因为浏览器中的alert会阻止js代码运行(实际上在v8中会以类似的方式暂停isolatecontext的执行到进程挂起),所以爬虫程序作为攻击者可以选择使用上述技术在运行页面所有js之前预注入一段js代码,hook所有的弹窗方法,如alert,提示,并确认。如果防御者在弹窗代码前先检查自己调用的alert方法是否为native,这种方式就会被阻断。反爬虫银弹目前反爬虫和机器人检测方式是最靠谱的验证码技术。但是,验证码并不意味着必须强制用户输入一串字母数字。也有很多基于用户鼠标、触摸屏(移动端)等的行为验证技术,其中最成熟的是GooglereCAPTCHA,它是基于机器学习的。区分用户和爬虫。基于上述诸多对用户和爬虫的识别和区分技术,网站防御者最终应该做的是屏蔽该ip地址或者对该ip的访问用户强加高强度验证码策略。这样,攻击者就必须购买ip代理池来抓取网站信息内容,否则单个ip地址很容易被屏蔽而无法抓取。爬虫和反爬虫的门槛提高到ip代理池的经济成本水平。除了robotprotocol之外,在爬虫爬取技术领域还有另外一种“白道”方式,叫做robotsprotocol。Allow和Disallow声明了每个UA爬虫的爬取权限。然而,这只是君子之约。虽然有法律上的好处,但它只能限制那些商业搜索引擎的蜘蛛程序,而你不能限制那些“野爬虫”。写在最后,网页内容的爬取与反击,注定是一场魔幻高低的猫鼠游戏。你永远无法用某种技术完全堵住爬虫的路。Whatyoucando这只是增加了攻击者的捕获成本,实现了对未授权捕获行为的更准确理解。