dySE:一个 Java 搜索引擎的实现,第 1 部分: 网络爬虫
2010-07-30 00:00:00 来源:WEB开发网接下来我们进行第二步操作,URL 的整理,即对之前获得的整个页面中 URL 集合进行筛选和整合。整合主要是针对网页地址是相对链接的部分,由于我们可以很容易的获得当前网页的 URL,所以,相对链接只需要在当前网页的 URL 上添加相对链接的字段即可组成完整的 URL,从而完成整合。另一方面,在页面中包含的全面 URL 中,有一些网页比如广告网页是我们不想爬取的,或者不重要的,这里我们主要针对于页面中的广告进行一个简单处理。一般网站的广告连接都有相应的显示表达,比如连接中含有“ad”等表达时,可以将该链接的优先级降低,这样就可以一定程度的避免广告链接的爬取。
经过这两步操作时候,可以把该网页的收集到的 URL 放入 URL 池中,接下来我们处理爬虫的 URL 的派分问题。
Dispatcher 分配器
分配器管理 URL,负责保存着 URL 池并且在 Gather 取得某一个网页之后派分新的 URL,还要避免网页的重复收集。分配器采用设计模式中的单例模式编码,负责提供给 Gather 新的 URL,因为涉及到之后的多线程改写,所以单例模式显得尤为重要。
重复收集是指物理上存在的一个网页,在没有更新的前提下,被 Gather 重复访问,造成资源的浪费,主要原因是没有清楚的记录已经访问的 URL 而无法辨别。所以,Dispatcher 维护两个列表 ,“已访问表”,和“未访问表”。每个 URL 对应的页面被抓取之后,该 URL 放入已访问表中,而从该页面提取出来的 URL 则放入未访问表中;当 Gather 向 Dispatcher 请求 URL 的时候,先验证该 URL 是否在已访问表中,然后再给 Gather 进行作业。
Spider 启动多个 Gather 线程
现在 Internet 中的网页数量数以亿计,而单独的一个 Gather 来进行网页收集显然效率不足,所以我们需要利用多线程的方法来提高效率。Gather 的功能是收集网页,我们可以通过 Spider 类来开启多个 Gather 线程,从而达到多线程的目的。代码如下:
/**
* 启动线程 gather,然后开始收集网页资料
*/
public void start() {
Dispatcher disp = new Dispatcher。getInstance();
for(int i = 0; i < gatherNum; i++){
Thread gather = new Thread(new Gather(disp));
gather.start();
}
}
在开启线程之后,网页收集器开始作业的运作,并在一个作业完成之后,向 Dispatcher 申请下一个作业,因为有了多线程的 Gather,为了避免线程不安全,需要对 Dispatcher 进行互斥访问,在其函数之中添加 synchronized 关键词,从而达到线程的安全访问。
小结
Spider 是整个搜索引擎的基础,为后续的操作提供原始网页资料,所以了解 Spider 的编写以及网页库的组成结构为后续预处理模块打下基础。同时 Spider 稍加修改之后也可以单独用于某类具体信息的搜集,比如某个网站的图片爬取等。
后续内容
在本系列的第 2 部分中,您将了解到爬虫获取的网页库如何被预处理模块逐步提取内容信息,通过分词并建成倒排索引;而在第 3 部分中,您将了解到,如何编写网页来提供查询服务,并且如何显示的返回的结果和完成快照的功能。
更多精彩
赞助商链接