MicrocomputerApplicationsVol.26,No.7,2010
研究与
设计 微型电脑应用
2010年第26卷第7期
文章编号:1007-757X(2010)7-0021-02
基于
Java的多线程
网络爬虫设计与实现
姜梦稚
摘要:网络爬虫是目前比较流行的一种网页检索工具,其也需要不断优化和改进。通过描述网络爬虫设计与实现中所碰到的
问题,提供解决这些问题的方法,并给出实现这些目标的网络爬虫设计方法,提供该设计的Java语言版实现。关键词:网络爬虫;链接检索;文字匹配;爬虫设计;多线程中图分类号:TP316文献标志码:A
0
引言
目前,对于全球大多数互联网用户来说,
搜索引擎是其准确获得所需要信息或者知识的最有效的工具。但是对于所有的搜索引擎来说,最重要的性能指标有两个:查全率和查准率。查全率与搜索引擎搜集的网页数量和质量有关。本文介绍的是用于搜集网页,提高查全率的最重要的网络爬虫的主工具—网络爬虫(WebCrawler)。要作用是搜集互联网的网页,也可以用它来定期搜集某个网站的内容,跟踪判断网站的发展,或者做站内搜索引擎。从网络爬虫的
工作原理来看,“网络爬虫”是一个比较形象的名字,它是在互联网内,通过网页链接,从当前网页爬到下一个网页来进行网页内容搜集的工具。它所需完成的工作[1]如下:(1)在一个网页上,获取网页的标题和网页中的摘要;(2)将搜集到的网页标题,链接,网页的摘要放入数据库中;(3)根据当前网页的内容,搜集网页中的链接信息,并根据链接顺序搜索相应链接网页的内容。
1
WebCrawler中的若干问题
不同的WebCrawler,在设计的时候侧重各有不同,本文所介绍的WebCrawler在设计的时候主要考虑解决以下几个问题:(1)WebCrawler遍历网页中的所有链接,并且能对所搜索的网页进行搜索深度的限制;(2)WebCrawler能够提取出网页中的摘要和标题信息,并且保存到数据库中;(3)要求能够对已有的搜索引擎的搜索结果再优化,提高所设计的Crawler的扩展能力;(4)要求能够采用多线程的方式,提高搜索的效率。针对前述的四个目标,在设计Crawler的时候,具体考虑了如下一些问题。首先Crawler的搜索深度的问题,网页中的链接关系是相当复杂的,一组网页之间可以互相包含,网页A中的链接可以指向网页B,同时网页B中的链接也可以指向网页A。因此,网页的搜索深度必须作一定的限制,不能无限制的递归搜索;其次网页的搜索方式也有差别,有(BFS),有些采用了深度优先策略些爬虫采用广度优先策略(DFS)[2],考虑到实现时采用多线程,且所设计的Crawler需在搜索的深度上作了限制,所以采用深度搜索的方式。对于搜集所有url链接,可以有不同的方式,本文采用的正则
表达式。尽管具体的实现有多种方式,搜集链接也可以采用后面所提到的HtmlParser包,但是采用正则表达式,是一种方便,快捷的手段,Java语言也提供对正则表达式的支持。多线程
程序是编程中比较复杂的问题,除了对线程的调试比较困难外,对线程所使用的资源的控制也同样复杂。在Java平台下对多线程的编程有充分支持,因此在设计Crawler的多线程实现时,采用了Synchronous关键字,原子数(AtomicInteger)和线程池[3],通过使用线程池,在应用启动的时候,设置所需创建的线程数量,一旦线程池为空,则挂起当前请求,等待空闲的线程出现;原子数则可以保证程序中的计数以互斥的方式操作,保证了递增和递减操作的原子性;而Synchronous保证了不同线程在访问数据的时候不会出现两个线程同时访问一个数据。本文中实现的Crawler中第三个考虑的问题就是获取网页的内容、提取网页摘要信息和标题信息。网页内容的获取方式有多种,比较
常用的就是想网页发出一个Http请求,并获取返回的字符流。考虑到实现这种请求/响应方式的复杂性,本文采用了HtmlParser[4]包来具体实现网页内容的获取。对于标签的获取采用两种方式,一种是采用HtmlParser包来获取,另外一种提取文本的方式也可以使用正则表达式[5],在构造合适的正则表达式时,需要考虑到标签的特殊结构,为了提高文字的抽取效率,可以对一段html源码首先过滤掉一些不需要的标签。采用HtmlParser包除了能够获得网页的内容外,该包还能提供一系列的获取网页内容的工具类,获取特定标签,并通过标签筛选规则的运用,获取包含