位图:如何实现网页爬虫中的URL去重功能?

------ 本文是学习算法的笔记,《数据结构与算法之美》,极客时间的课程 ------

网页爬虫是搜索引擎中的非常重要的系统,负责爬取几十亿、上百亿的网页。爬虫的工作原理是,通过解析已经爬取页面中的网页链接,然后再爬取这些链接对应的网页。而同一个网页链接有可能被包含在多个页面中,这就会导致爬取的过程中,重复爬取相同网页。如果你是一名负责爬虫的工程师,你会如何避免这些重复的爬取呢?

最容易想到的方法就是,我们记录已经爬取的网页链接(也就是URL)在爬取一个新的网页之前,我们拿它的链接,在已经爬取的网页链接列表中搜索。如果存在,那就说明这个网页已经被爬取过了;如果不存在,那就说明这个网页还没有被爬取过,可以继续去爬取。等爬取到这个网页之后,我们将这个网页的链接添加到已经爬取的网页链接表。

思路非常简单,可我们该如何记录已经爬取的网页链接呢?需要用什么样的数据结构呢?

算法解析

这个问题要处理的对象是网页链接,也就是URL,需要支持的操作有两个,添加一个URL和查询一个URL。除了这两个功能性的要求之外,在非功能性方面,我们还要求这两个操作的执行效率要尽可能高。除此之外,因为我们处理的是上亿的网络链接,内存消耗会非常大,所以在存储效率上,我们要尽可能地高效。

回想一下,满足这些条件的数据结构有哪些呢?显然,散列晴、红黑树、跳表这些动态数据结构,都能支持快速插入、查找数据,但对内存消耗方面,是否可以接受呢?

我们拿散列表来举例。假设我们要爬取10亿个网页(像Google、百度这样的通用搜索引擎,爬取的网页可能会更多),为了判重,我们把这10亿网页链接存储在散列表中。你来估算下,大约需要多少内存?

假设一个URL的平均长度是64字节,那单纯存储这10亿个URL,需要大约60GB的内存空间。因为散列表必须维持较小的装载因子,才能保证不会出现过多散列冲突。而且,用链表法解决总被的散列表,还会存储表指针。所以,如果将这10亿个URL构建成散列表,那需要的内存空间会远大于60GB,有可能超过100GB。

当然,对于一个大型的搜索引擎来说,即便是100GB的内存要求,其实也不算太高,我们可以优胜分治的思想,用多台机器(比如20台内存是8GB的机器)来存储这10亿网页链接。这种分治处理思路,我们之前讲过多次。

对于爬虫的URL去重这个问题,刚刚讲到的分治加散列表的思路,已经是可以实实在在工作了。不过,作为一个有追求的工程师,我们

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值