这就是搜索引擎(2) 网络爬虫

1. 背景

互联网网页是通用搜索引擎主要的处理对象,目前互联网上的网页数量以百亿计,所以通用搜索引擎首要面临的问题是:如何设计出高效的下载系统,将海量的网页数据传输到本地,在本地形成互联网网页的镜像备份。这就是网络爬虫的功能。
image.png

2. 通用爬虫框架

下图是一个通用的爬虫框架

  1. 首先取一部分高质量的网页,将其链接地址作为种子url。
  2. 将这些种子url放入待抓取url队列中,处于待抓取队列的url会依次被读取和下载
  3. 下载后的页面会进入网页库,并从下载的页面中抽取出新的url(为了避免对同一url的重复抓取,还会从已抓取队列中对抽取出来的url进行去重)
  4. 将抽取出的新的url放入待抓取队列,就可以形成抓取循环。
  5. 当待抓取url队列为空时,代表爬虫已经抓取完了所有能够抓取的网页,此时被认为时完成了一轮完整的抓取过程。

image.png
绝大多数的爬虫都遵循这个爬虫抓取框架,但是根据使用场景不同,爬虫之间也有很多差异,大致可以分为三种。

  1. 批量型爬虫:有明确的抓取范围和目标,当完成目标后停止抓取。例如抓取一定数量的网页或者抓取到一定的时间。
  2. 增量型爬虫:会保持不断的抓取,同时对抓取到的网页还需要定期更新以防止页面变化。通用的商业搜索引擎爬虫基本都是这一类,这里讲的爬虫架构值得也是主要是增量型爬虫。
  3. 垂直型爬虫:主要关注特定主题或者特定行业的内容,例如只想抓取与游戏有关的网站。这类爬虫的难点在于如何识别网页的内容是否是指定的主题或者行业。为了节省抓取成本,往往要求爬虫在抓取网页之前就能够动态的判断某个url是否与主题相关。一些垂直搜索网站或者垂直行业网站就是此类爬虫。

3. 优秀爬虫系统的评价指标

既然通用的爬虫框架都大同小异,那么在设计一个优秀的爬虫系统之前首先要搞清楚,什么样的爬虫系统才是一个优秀的爬虫系统?

3.1 爬虫研发的目标

已知在资源有限的情况下,爬虫不可能抓取全部的互联网网页从爬虫产出的结果上来看,爬虫研发的目标可以简单描述为

  1. 尽可能的选择相对重要的页面进行抓取
  2. 对于已经抓取到的网页,尽快更新其内容以保证索引网页和互联网网页的对齐
  3. 在以上两点的基础上,尽可能扩大抓取范围,抓取更多之前没有发现的网页。

3.2 爬虫系统的特性

为了实现上面描述的目标,优秀的爬虫应当有以下几个特性。

3.2.1 高性能

互联网上有海量的网页数据,在此背景下,爬虫的抓取性能至关重要,爬虫的抓取性能对索引网页的数量和质量都有极大的影响。常见以每秒钟能够抓取的网页数量作为评价性能的指标,单位时间内能抓取的网页越多,爬虫的性能越高。

3.2.2 可扩展性

可扩展性指的是能否容易的通过增加抓取服务器和爬虫数量来达到提高抓取量的目的,描述的是未来爬虫性能增长的能力。

3.2.3 健壮性

当爬虫访问到非正常的情况时,需要有能力及时恢复,例如遇到被抓取服务器死机或者爬虫陷阱时能够正确处理,不能停止工作。
另一方面看,即使抓取的过程中停止工作,在重启爬虫时也要能够恢复之前抓取的内容和数据结构,不需要将所有工作从头做起。

3.2.4 友好性

友好性包含两方面

  1. 保护网站的部分私密性(遵循robot禁抓协议)
  2. 减少被抓取网站的网络负载(在抓取时通过策略考虑每个网站的负载)

4. 抓取策略

抓取策略是指从待抓取url队列中取出url进行抓取时,队列中url的优先顺序。其目的在于优先选择重要的网页进行抓取。(对于如何评价网页的重要性,将在之后的链接分析中讲到)

4.1 宽度优先遍历策略(bfs)

bfs是设计策略时最简单的想法,即新抽取的网页直接放到待抓取队列的末尾,看似简单,实际效果很好,因为入链更多的网页能够被更快抓到,而入链从侧面体现的网页的重要。

4.2 非完全PageRank策略

PageRank时故著名的连接分析算法,用来衡量网页的重要性。因此可以想到在url待抓取队列中使用PageRank来对url进行排序。但PageRank是一个全局性算法,需要有所有网页的信息才能计算可靠的结果,但爬虫抓取的时候只能看到一部分页面,所以无法计算出可靠的PageRank分。
如果在不完全的互联网页面子集中去试图计算PageRank分,就得到了非完全PageRank策略的基本思路:将待抓取队列中的url和已经下载的网页url一起形成集合进行PageRank的计算,当然如果每次抓到一个网页就重新计算,显然会有很大的计算开销,所以采用了一个折中的方式:每次新下载了K个网页,就重新计算,在计算之前,新下载的网页用所有入链网页的PageRank汇总来替代,作为临时的PageRank。
这种非完全的PageRank策略效果略优于bfs,但由于局部信息下计算出的PageRank和实际差异很大,因此部分情况效果并不是很好,同时会产生抓取过程中更大的计算开销。

4.3 OPIC(Online Page Importance Computation)

OPIC可以认为是一种改进之后的PageRank算法,思路是给每个网页赋予初始现金,网页被下载后将现金平均分给包含的链接,按照现金大小排序。这么做的优势是计算速度远远快于PageRank,同时也不需要全局信息。实验下来这种做法也要略优于bfs。

5. 网页更新策略

由于互联网页面可能发生变动,因此要重新抓取已下载的网页,需要确保本地页面和互联网与页面保持一致。网页更新策略的目的是决定何时重新抓取之前下载过的网页,以尽可能使得本地下载网页和互联网原始也页面内容保持一致。

5.1 历史参考策略

历史参考策略基于一种假设:过去频繁更新的网页,将来也会频繁更新。因此为了预估网页的更新时间,可以参考网页的历史更新情况来做出决定。

5.2 用户体验策略

用户体验策略是从用户体验出发,认为一些搜索结果在被搜索时排序靠后,即使互联网网页内容与索引内容不对齐也不会对用户体验有大的影响,因此这种前提下网页的更新时机,取决于网页内容变化带来的搜素质量变化(通过搜索排名变化来衡量),对搜索质量影响越厉害的网页,抓取越优先。

5.3 聚类抽样策略

以上两种策略需要保存依赖网页的历史更新信息,如果保存所有网页的历史信息,会带来大量的额外负担,同时对于首次抓到的网页,没有历史信息,自然也没有参考因素。
聚类抽样策略对网页进行聚类,同一类别的网页认为有相同的更新频率,对于某个类别的周期,只需要对其中网页进行采样,就能计算出所有其他网页的更新周期。

6. 暗网抓取

这里的暗网指的是按照常规方式很难抓取到的互联网页面,例如机票的查询结果页面,需要在url里面标注起点、终点、时间等信息

6.1 查询组合问题

一些垂直搜索网站会给用户提供多个输入框,每个输入框代表了对象某方面的属性,例如招聘网站在搜索时提供了职位类别,行业类别,工作地点等信息,帮助用户筛选匹配的岗位。

如果对所有查询的排列组合都拿出来进行查询,会有很多冗余信息,错误信息,也会给网站造成很大压力。一种解决方案是定义一个富含信息模板(对于某个固定的查询模板,如果给模板内每个属性都赋值,形成不同的查询组合,提交之后返回的页面如果差异较大,则这个是富含信息模板)
我们在查询时,只查询富含信息模板,就可以大大查询次数。那么如何试探一个查询模板是否是富含信息模板呢?Google的技术方案使用了ISIT算法

  • 从一维模板开始,对一维模板逐个考察,如果是富含信息模板,则将其扩展到二维逐个考察,不断增加维度,直至无法找到富含信息模板。

6.2 文本框填写问题

对于没有选择的查询组合模板,往往只提供一个输入文本信息的搜索框,此时需要爬虫自动生成查询,对于这种场景需要人工给一些提示,生成一系列初始种子作为词表,然后将初始种子进行提交查询,下载页面并挖掘出新的种子(有点类似于通用爬虫挑选框架的结构)

  • 种子 -> 搜索 -> 下载页面 -> 抽取关键词 -> 作为种子继续搜索

7. 分布式爬虫

在面对海量的互联网页面内容时,为了提高抓取效率,分布式爬虫是商业通用搜索引擎必须采用的技术。分布式爬虫一般分为三个层级:分布式数据中心、分布式抓取服务器、分布式爬虫程序。
整个爬虫系统由多个分布式数据中心共同组成,例如欧洲的数据中心负责抓取欧洲国家的网页,由于地缘近,速度上也会快很多。每个数据中心由多台高速网络连接的分布式抓取服务器构成,每台服务器可以部署多个爬虫程序。
同一数据中心有多台抓取服务器,不同机器之间的分工协同方式也会有差异,常见的主要是主从式分布爬虫和对等式分布爬虫。

7. 1 主从式分布爬虫

主从式分布爬虫有一台服务器专门对其他的服务器提供url分发服务,其他机器进行实际的网页下载,由url服务器维护待抓取url队列。其中主服务器承担了对所有服务器的消息传递以及url分配,还要考虑到负载均衡等问题,当待抓取url队列巨大时,url服务器很容易成为整个系统的瓶颈。

7.2 对等式分布爬虫

对等式分布爬虫的每台服务器承担相同功能,各自负担一部分url的抓取工作,服务器接收到url的时候,判断url是否应该由自己抓取,如果不是则将其发送给对应的服务器。如何判断url是否属于自己抓取?一般采用hash的方式来计算url的值和服务器编号是否匹配,但是这种场景下一旦出现服务器的变更(扩容或者缩容或者故障),所有待抓取的url分布都会发生变化,对整个系统会产生很大的影响。因此实际上会采用一致性哈希的方式,来尽可能降低服务器变更对系统的影响。

posted @ 2022-11-27 20:06  Hugh_Locke  阅读(316)  评论(0编辑  收藏  举报