爬虫技术的门道,这篇文章总结的最全

简介: Web是一个开放的平台,这也奠定了Web从90年代初诞生直至今日将近30年来蓬勃的发展。然而,正所谓成也萧何败也萧何,开放的特型、搜索引擎以及简单易学的HTML、CSS技术使得Web成为了互联网领域里最为流行和成熟的信息传播媒介;但如今作为商业化软件,Web这个平台上的内容信息的版权却毫无保证,因为相比软件客户端而言,你的网页中的内容可以被很低成本、很低的技术门槛实现出的一些抓取程序获取到,这也就是这一系列文章将要探讨的话题—— 网络爬虫 。

Web是一个开放的平台,这也奠定了Web从90年代初诞生直至今日将近30年来蓬勃的发展。然而,正所谓成也萧何败也萧何,开放的特型、搜索引擎以及简单易学的HTML、CSS技术使得Web成为了互联网领域里最为流行和成熟的信息传播媒介;但如今作为商业化软件,Web这个平台上的内容信息的版权却毫无保证,因为相比软件客户端而言,你的网页中的内容可以被很低成本、很低的技术门槛实现出的一些抓取程序获取到,这也就是这一系列文章将要探讨的话题—— 网络爬虫 。

有很多人认为Web应当始终遵循开放的精神,呈现在页面中的信息应当毫无保留地分享给整个互联网。然而我认为,在IT行业发展至今天,Web已经不再是当年那个和PDF一争高下的所谓 “超文本”信息载体 了,它已经是以一种 轻量级客户端软件 的意识形态的存在了。而商业软件发展到今天,Web也不得不面对知识产权保护的问题,试想如果原创的高质量内容得不到保护,抄袭和盗版横行网络世界,这其实对Web生态的良性发展是不利的,也很难鼓励更多的优质原创内容的生产。

未授权的爬虫抓取程序是危害Web原创内容生态的一大元凶,因此要保护网站的内容,首先就要考虑如何反爬虫。

从爬虫的攻防角度来讲

最简单的爬虫,是几乎所有服务端、客户端编程语言都支持的http请求,只要向目标页面的url发起一个http get请求,即可获得到浏览器加载这个页面时的完整html文档,这被我们称之为“同步页”。

作为防守的一方,服务端可以根据http请求头中的User-Agent来检查客户端是否是一个合法的浏览器程序,亦或是一个脚本编写的抓取程序,从而决定是否将真实的页面信息内容下发给你。

这当然是最小儿科的防御手段,爬虫作为进攻的一方,完全可以伪造User-Agent字段,甚至,只要你愿意,http的get方法里, request header的 Referrer 、 Cookie 等等所有字段爬虫都可以轻而易举的伪造。

此时服务端可以利用浏览器http头指纹,根据你声明的自己的浏览器厂商和版本(来自 User-Agent ),来鉴别你的http header中的各个字段是否符合该浏览器的特征,如不符合则作为爬虫程序对待。这个技术有一个典型的应用,就是 PhantomJS 1.x版本中,由于其底层调用了Qt框架的网络库,因此http头里有明显的Qt框架网络请求的特征,可以被服务端直接识别并拦截。

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

如果你不携带token直接访问一个接口,这也就意味着你没请求过html页面直接向本应由页面内ajax访问的接口发起了网络请求,这也显然证明了你是一个可疑的爬虫。知名电商网站amazon就是采用的这种防御策略。

以上则是基于服务端校验爬虫程序,可以玩出的一些套路手段。

基于客户端js运行时的检测

现代浏览器赋予了JavaScript强大的能力,因此我们可以把页面的所有核心内容都做成js异步请求 ajax 获取数据后渲染在页面中的,这显然提高了爬虫抓取内容的门槛。依靠这种方式,我们把对抓取与反抓取的对抗战场从服务端转移到了客户端浏览器中的js运行时,接下来说一说结合客户端js运行时的爬虫抓取技术。

刚刚谈到的各种服务端校验,对于普通的python、java语言编写的http抓取程序而言,具有一定的技术门槛,毕竟一个web应用对于未授权抓取者而言是黑盒的,很多东西需要一点一点去尝试,而花费大量人力物力开发好的一套抓取程序,web站作为防守一方只要轻易调整一些策略,攻击者就需要再次花费同等的时间去修改爬虫抓取逻辑。

此时就需要使用headless browser了,这是什么技术呢?其实说白了就是,让程序可以操作浏览器去访问网页,这样编写爬虫的人可以通过调用浏览器暴露出来给程序调用的api去实现复杂的抓取业务逻辑。

其实近年来这已经不算是什么新鲜的技术了,从前有基于webkit内核的PhantomJS,基于Firefox浏览器内核的SlimerJS,甚至基于IE内核的trifleJS,有兴趣可以看看这里和这里 是两个headless browser的收集列表。

这些headless browser程序实现的原理其实是把开源的一些浏览器内核C++代码加以改造和封装,实现一个简易的无GUI界面渲染的browser程序。但这些项目普遍存在的问题是,由于他们的代码基于fork官方webkit等内核的某一个版本的主干代码,因此无法跟进一些最新的css属性和js语法,并且存在一些兼容性的问题,不如真正的release版GUI浏览器。

这其中最为成熟、使用率最高的应该当属 PhantonJS 了,对这种爬虫的识别我之前曾写过一篇博客,这里不再赘述。PhantomJS存在诸多问题,因为是单进程模型,没有必要的沙箱保护,浏览器内核的安全性较差。

如今Google Chrome团队在chrome 59 release版本中开放了headless mode api,并开源了一个基于Node.js调用的headless chromium dirver库,我也为这个库贡献了一个centos环境的部署依赖安装列表。

headless chrome可谓是headless browser中独树一帜的大杀器,由于其自身就是一个chrome浏览器,因此支持各种新的css渲染特性和js运行时语法。

基于这样的手段,爬虫作为进攻的一方可以绕过几乎所有服务端校验逻辑,但是这些爬虫在客户端的js运行时中依然存在着一些破绽,诸如:

基于plugin对象的检查

基于language的检查

基于webgl的检查

基于浏览器hairline特性的检查

基于错误img src属性生成的img对象的检查

基于以上的一些浏览器特性的判断,基本可以通杀市面上大多数 headless browser 程序。在这一点上,实际上是将网页抓取的门槛提高,要求编写爬虫程序的开发者不得不修改浏览器内核的C++代码,重新编译一个浏览器,并且,以上几点特征是对浏览器内核的改动其实并不小。

更进一步,我们还可以基于浏览器的 UserAgent 字段描述的浏览器品牌、版本型号信息,对js运行时、DOM和BOM的各个原生对象的属性及方法进行检验,观察其特征是否符合该版本的浏览器所应具备的特征。

这种方式被称为 浏览器指纹检查 技术,依托于大型web站对各型号浏览器api信息的收集。而作为编写爬虫程序的进攻一方,则可以在 headless browser 运行时里预注入一些js逻辑,伪造浏览器的特征。

另外,在研究浏览器端利用js api进行 robots browser detect 时,我们发现了一个有趣的小技巧,你可以把一个预注入的js函数,伪装成一个native function,来看看下面代码:

爬虫进攻方可能会预注入一些js方法,把原生的一些api外面包装一层proxy function作为hook,然后再用这个假的js api去覆盖原生api。如果防御者在对此做检查判断时是基于把函数toString之后对[native code]的检查,那么就会被绕过。所以需要更严格的检查,因为bind(null)伪造的方法,在toString之后是不带函数名的。

反爬虫的银弹

目前的反抓取、机器人检查手段,最可靠的还是验证码技术。但验证码并不意味着一定要强迫用户输入一连串字母数字,也有很多基于用户鼠标、触屏(移动端)等行为的行为验证技术,这其中最为成熟的当属Google reCAPTCHA。
基于以上诸多对用户与爬虫的识别区分技术,网站的防御方最终要做的是封禁ip地址或是对这个ip的来访用户施以高强度的验证码策略。这样一来,进攻方不得不购买ip代理池来抓取网站信息内容,否则单个ip地址很容易被封导致无法抓取。抓取与反抓取的门槛被提高到了ip代理池经济费用的层面。

机器人协议

除此之外,在爬虫抓取技术领域还有一个“白道”的手段,叫做robots协议。你可以在一个网站的根目录下访问/robots.txt,比如让我们一起来看看github的机器人协议,Allow和Disallow声明了对各个UA爬虫的抓取授权。

不过,这只是一个君子协议,虽具有法律效益,但只能够限制那些商业搜索引擎的蜘蛛程序,你无法对那些“野爬爱好者”加以限制。

写在最后

对网页内容的抓取与反制,注定是一个魔高一尺道高一丈的猫鼠游戏,你永远不可能以某一种技术彻底封死爬虫程序的路,你能做的只是提高攻击者的抓取成本,并对于未授权的抓取行为做到较为精确的获悉。

这篇文章中提到的对于验证码的攻防其实也是一个较为复杂的技术难点,在此留一个悬念,感兴趣可以加关注期待后续文章进行详细阐述。

另外,欢迎对抓取方面感兴趣的朋友关注我的一个开源项目webster, 项目以Node.js 结合Chrome headless模式实现了一个高可用性网络爬虫抓取框架,借以chrome对页面的渲染能力, 可以抓取一个页面中 所有的js及ajax渲染的异步内容;并结合redis实现了一个任务队列,使得爬虫程序可以方便的进行横向、纵向的分布式扩展。

作者:5u9ar
链接:https://juejin.im/post/5a22af716fb9a045132a825c

相关文章
|
3月前
|
数据采集 机器学习/深度学习 搜索推荐
探索数据之海——网络爬虫与数据抓取技术的应用与发展
在当今信息爆炸的时代,获取大量高质量的数据成为各行各业的迫切需求。网络爬虫和数据抓取技术作为一种有效的手段,正在被广泛应用于各个领域。本文将深入探讨网络爬虫的原理、应用场景以及未来的发展趋势,为读者带来关于数据抓取技术的全面了解。
283 5
|
3月前
|
数据采集 搜索推荐 数据处理
探索数据的无尽可能性:网络爬虫与数据抓取技术
本文将深入探讨网络爬虫与数据抓取技术的重要性和应用,介绍其在信息收集、市场分析、学术研究等领域的广泛应用。我们将探索这一技术的原理、挑战和发展前景,并展望未来数据抓取技术的潜力。
58 0
|
2月前
|
数据采集 数据处理 开发者
Python爬虫技术在数据收集与分析中的应用
随着互联网信息的爆炸式增长,数据收集与分析变得愈发重要。本文将介绍Python爬虫技术在实际项目中的应用,探讨其在数据收集、清洗和分析过程中的作用,以及如何利用Python相关库提高爬虫效率。
|
6月前
|
数据采集 存储 JSON
使用Perl脚本编写爬虫程序的一些技术问题解答
使用Perl脚本编写爬虫程序的一些技术问题解答
|
13天前
|
数据采集 C# 数据安全/隐私保护
掌握 C# 爬虫技术:使用 HttpClient 获取今日头条内容
本文介绍了如何使用C#的HttpClient与爬虫代理IP技术抓取今日头条内容,以实现高效的数据采集。通过结合亿牛云爬虫代理,可以绕过IP限制,增强匿名性。文中提供了一个代码示例,展示如何设置代理服务器信息、请求头,并用正则表达式提取热点新闻标题。利用多线程技术,能提升爬虫采集效率,为市场分析等应用提供支持。
掌握 C# 爬虫技术:使用 HttpClient 获取今日头条内容
|
1月前
|
数据采集 存储 关系型数据库
Python爬虫-使用代理获取微信公众号文章
使用代理爬取微信公众号文章
52 0
|
1月前
|
数据采集 存储 JavaScript
PHP爬虫技术:利用simple_html_dom库分析汽车之家电动车参数
本文旨在介绍如何利用PHP中的simple_html_dom库结合爬虫代理IP技术来高效采集和分析汽车之家网站的电动车参数。通过实际示例和详细说明,读者将了解如何实现数据分析和爬虫技术的结合应用,从而更好地理解和应用相关技术。
PHP爬虫技术:利用simple_html_dom库分析汽车之家电动车参数
|
1月前
|
数据采集 数据可视化 数据挖掘
Python爬虫之Pandas数据处理技术详解
Python爬虫之Pandas数据处理技术详解
|
2月前
|
数据采集 开发框架 监控
Wt库网络爬虫技术与央行降息的完美结合:实战案例分析
Wt库网络爬虫技术与央行降息的完美结合:实战案例分析
|
7月前
|
数据采集 数据可视化 数据挖掘
爬虫技术对携程网旅游景点和酒店信息的数据挖掘和分析应用
爬虫技术是一种通过网络爬取目标网站的数据并进行分析的技术,它可以用于各种领域,如电子商务、社交媒体、新闻、教育等。本文将介绍如何使用爬虫技术对携程网旅游景点和酒店信息进行数据挖掘和分析,以及如何利用Selenium库和代理IP技术实现爬虫程序
289 0