老狗啃爬虫-小说爬虫上手之前生今世
摘要:
当下,随着互联网的快速发展,网页信息数据更加丰富,无论是现在还是可预见的将来,数据量都将会是指数级的暴涨,这时候如何有效的提取筛选这些信息为己所用,已经成为一种挑战。传统的搜索引擎,在很多特定的场景、专门的领域,它也是乏力难支的。所以,很多定向抓取相关网页资源的网络爬虫应运而生
爬虫的前生今世
网络爬虫,是一种按照特定的规则,自动地抓取网站信息的程序或者脚本,他还有很多名称代号,如网页蜘蛛、网络机器人等等。

早期的网络爬虫,也就是搜索引擎爬虫,是搜索引擎们发明出来的。搜索引擎在面对浩瀚的互联网网页信息时,如何能够设计出高效的数据收集处理系统,将海量的数据存储在本地,完成网站页面的索引和镜像,是非常迫切和实际的问题。在他们这一套操作的最前端,就是游走在各个网站的搜索引擎爬虫,吭哧吭哧不辞辛劳的来抓取网页信息。
当下,随着互联网的快速发展,网页信息数据更加丰富,无论是现在还是可预见的将来,数据量都将会是指数级的暴涨,这时候如何有效的提取筛选这些信息为己所用,已经成为一种挑战。传统的搜索引擎,像百度谷歌雅虎等,作为我们日常检索的辅助工具还行,但是在很多特定的场景、专门的领域,它也是乏力难支的。所以,在今天,很多定向抓取相关网页资源的网络爬虫应运而生,这些到处活跃着的爬虫,为我们在数据的星辰大海中提炼出简洁明了有价值的信息,这种爬虫,有人称之为聚焦爬虫。
爬虫操作的基本姿式
在今天,爬虫的应用已经非常普遍,经过几十年的发展,其技术框架也已相对成熟,无论怎么爬怎么抓,都跑不出一些基本的东西。
基本流程
几乎所有的爬虫系统流程都差不多,如下图示:

一般来说,在设计爬虫的最初,会从网站页面中精心挑选一部分页,一般是首页、栏目列表页等,然后将这些网页的链接作为种子URL,放入待抓取URL队列。接下来,就把待抓取URL队列中的链接,进行逐个读取下载,对于已经成功获取到页面信息的URL链接呢,有三个重要工作:
一是要将其数据进行提取分析与存储;
二是要将此页面提取到的链接进行分析筛选,放入待抓取URL队列;
三是要将其本身移出待抓取队列,并放入已抓取URL队列。
如此操作循环递归,直至遍历完所有的目标网页,即爬虫完成工作。
页面分类
上面是一个通用爬虫系统的常规流程,通过这个流程我们可以发现,爬虫工作基本就是围绕着链接和其页面进行的,归纳总结他们的规律,我们可以将其页面分为如下几类:
待下载页面:这个是我们通过种子链接,顺藤摸瓜获取到即将被爬虫处理的;
已下载页面:这个是已经被爬虫处理过的,这里要注意防重复,少做无用功;
已过期页面:已过期,考虑到现在网站页面数量比较大,爬虫抓取过程不识一蹴而就的,可能在后续的抓取过程中,已经处理完了的页面又发生更新,导致产生所谓的抓取过期。关于这个,就要根据我们的实际需要,看是否进行策略应对,毕竟页面再度更新,可能会导致内容不同。
根据网站的内容结构和爬虫的工作状态,还可以分为以下两类:
可探知页面:这个指的是,通过种子URL,我们可以顺藤摸瓜找得到的页面;
未知孤岛页面:有时候网站结构上的设计缺陷或者是刻意而为、权限所致,会导致一部分页面很难通过种子URL探到,这时候我们就要根据具体需求,进一步的发掘种子或采取更复杂的策略,在合法合规的前提条件下,尽量扩大探知范围,减少未知页面的存在。
从爬虫工作的角度来理解页面的分类,有助于我们在爬虫程序设计时做更加周全的考虑,这种分类本身也是一种学习和理解的工具。
策略分类
在爬虫的工作流程上,虽然说大概都大差不差,但在不同的使用场景,具体的细节上还是有偏重和差异的,一般根据爬虫工作的策略,我们可以将其分为三类:
A、广度优先策略
爬虫算法的广度优先策略一般指根据网站设计的结构层级,在抓取过程中,在完成当前层次的处理后,才进行下一层次。该算法策略的设计和实现相对简单。
在网站内容的抓取过程中,像就某个品类的信息,想尽可能覆盖更多的网页,一般推荐使用广度优先策略。所以,有很多研究将广度优先策略应用于聚焦爬虫的设计中。其基本思想就是认为与种子URL在逻辑上并行规则内的网页具有更高概率的主题相关性。还有一种是将广度优先策略结合使用到网页过滤技术中,即先用广度优先策略抓取网页,再将其中无关的网页过滤掉,不过这样随着抓取网页的增多,大量的无关网页将被下载,从算法的效率上来说也会大打折扣。
B、深度优先策略
爬虫算法的深度优先策略一般讲的是爬虫开始抓取工作,选择一个链接进入,分析这个网页中的URL,选择其中一个再进入分析,继续相同的操作。如此一个链接一个链接地循环递归,直到处理完这一条路线之后再继续下一个。该算法策略的设计和实现也相对比较简单。
一般从权重的角度来说,首页提供的链接往往最具价值,权重较高,但每深入一层,网页价值和权重都会相应地开始下降。这可能也验证了一个事实,距离种子URL层级越近则页面越重要,而过度深入抓取到的网页可能价值上比较低。还有一个就是,随着抓取深度的增加,会有大量的回路链接,导致频繁的重复,从而影响抓取效率。深度优先策略的爬虫算法,也要留意可能会陷入网站根据反扒策略设计的陷阱中,也就是通常所讲的爬虫陷阱。
综上所述,在爬虫策略的应用中,深度优先策略的使用场景也越来越少,更多的是从算法角度的理解。
C、最佳优先策略
爬虫算法的最佳优先策略是一种综合方面的应用体现,它指的是在网站的抓取过程中,根据网站本身的结构特点,按一定的网页分析算法,预测待选URL与爬取目标网页的相似度,或与目标主题的相关度,再选取评估较好的一个或几个URL进行抓取。该算法策略的实现在逻辑上是相对复杂的。
在爬虫的工作过程中,最佳优先策略倾向于只访问经过网页分析算法预测为高价值的网页,但这同时也会存在一个问题,就是在爬虫抓取路径上的很多相关网页可能会被忽略,造成抓取不完整等缺陷,所以最佳优先策略经常被用在对局部同类同属高相关的页面处理上。在实际应用中,通过对最佳优先策略进行具体场景应用进行改进,处理好跳出局部最优点,可以在覆盖绝大部分页面的前提下,将无用无关页面的抓取数量降低30%~90%,这在性能和效率上是很大的提升。
我们一般设计的爬虫,更多的也是考虑最佳优先策略的原则。
优秀爬虫该有的气质
对不同的使用场景来说,一套爬虫系统是否优秀,评定标准跟有所不同,但优秀的爬虫算法设计,都要具备以下气质:
1、性能好
当下,互联网上的数据浩渺如星辰大海,哪怕是单独一个网站,数据量都是很大的,所以,爬虫的性能因素,就是一个至关重要的问题。一般我们的理解,爬虫的性能说的就是爬虫抓取网页的速度,也就是单位时间内抓取的页面数量越多,性能就越好。
在提高爬虫的性能方面,单机上我们考虑的就是两个方面,一个实下载带宽,一个是本地存储。带宽问题上在目标网站不受影响的前提下,我们尽可能的多开线程,并发进行;本地存储的问题上我们就要设计合理的数据结构、设计性能优越的处理程序。
2、拓展性强
一般,我们设计爬虫方案的时候,要考虑单机的瓶颈问题。单机爬虫性能再好,也是绕不过单个环境的系统瓶颈的,当海量数据面前,单个机器不能满足需要的时候,就要设计采用分布式方案的爬虫系统,按需加机器,派出更多的爬虫大军!
事实上大型的网络爬虫本身就是分布式的,典型如搜索引擎谷歌百度,他们在全世界很多服务节点上都有成群的机器,有负责专门抓取的,有负责专门处理运算的,有负责专门存储的等等。虽然一般我们用不到他们那么庞大的算量,但他们采用的那些优秀方案思想,我们在设计爬虫系统时是可以借鉴的。
3、容错性好
设计爬虫的时候,除了循规蹈矩的普遍思路,有时候一些意外情况,也是让人猝不及防的。比如目标网站网页的代码,并不规范,我们常规的解析可能总出问题;也有可能对方的服务器环境配置比较低,这边稍微一并发那边就宕机了,还有一些网站会做一些反爬策略,例如爬虫陷阱等,对于这些非常规因素,在我们爬虫应用的时候非常普遍。针对这些异常情况,如何能有效调整规避并做一些容错策略,是非常必要的,要不然,机器动不动就超时崩溃了,卡那儿挂掉了,那是非常糟糕的。再不济,我们设计爬虫系统的时候也要考虑增量爬取方案,一定要避免我们服务挂一下,所有的工作再重头来,去重复那些没有意义的事情。
4、坚持原则
国有国法,行有行规,在爬虫所到之处,网站可以指定一个robot.txt的文件,这个文件就是爬虫禁抓协议。虽然说这个协议没有强制的约束效力,但也是行业内共同认可的君子协议。很多时候,处于很多原因,目标网站可能会考虑一些私密性,或者是原创版权等各种因素,并不希望网络爬虫上门爬抓,他们就可以在这个robot.txt文件里写明,哪个目录哪些链接禁止抓取,所以我们在设计爬虫的时候,是要考虑这个因素的,下手之前先过滤下robot.txt,也算是基本的尊重。
还有一种禁止抓取标记,就是网页html里的noindex和nofollow这两个标签。其中,noindex表示禁止索引,就是说不要收录该页,一般是针对搜索引擎的;nofollow表示禁止抓取该链接,基本就是说不欢迎爬虫入访。这两个标签的用法感兴趣的可以百度看看,也比较容易设置,我们在设计爬虫程序的时候,也是需要留意一下的,人家既然说不让爬了,非请勿进,已经拒绝了,还是就别打扰了,这是行业操守。
还有一个就是,不要影响目标网站的正常运行。在爬虫设计的推荐策略里,有个平衡礼貌策略的东西,扯成大白话就是,你爬就爬嘛,别给人弄宕机了。咱们说爬虫相较于人,一般会发起更为密集的请求,对于一些负载比较低的网站很容易给人弄瘫,我们爬人家网站是为了获取数据,一定要注意姿势优雅,做下相应的爬虫限制策略,把人搞崩了,我们也不能顺利的得到数据,损人不利己,不可为之。
如果咱们在设计爬虫系统的时候,能考虑到以上几个环节,那我们的爬虫必然是优秀的,就让我们的爬虫们欢快的喘着气儿尽情的去爬呀爬吧。
结语
关于网络爬虫,我们这个入门上手先讨论到这里,接下来我们将看一看,从技术,从开发的角度来看看,如何选择适合自己的技术方案。