(人工智能)基于Lucene与Heritrix的搜索引擎构建(6)
资料介绍:
NodeList nodes = parser.parse(NodeFilterFactory.createAndFilter(tag));
其中NodeFilterFactor是自己定义的节点过滤器工厂,它可以产生指定的节点过滤器。下一步的工作是判断nodes的个数,如果是零个说明该网页中不包含tag标记,所以返回false;反之,则返回true。
③ HtmlFileFilterForMovie类基本实现
该类继承自HtmlFileFilter类。
主要方法:public FileResultSet filtrateUnvaluedFile(FileResultSet source)
public boolean isValuable(String path)
过程描述:filtrateUnvaluedFile在这里实现了,它主要判断是否为Html文件并检验一些标记特征是否符合要求,首先实例化FileResultSet对象valuableReports,用于保留有价值的文件路径,再利用source的迭代器进行循环判断,如果符合放入valuableReports中,反之,继续循环。
最后返回valuableReports对象,此过程中用到了isValuable方法,以下是对isValuable方法的描述:
isValuable主要的功能是检验Html文件是否包含某些标记,它是结合实体xml配置文件进行检验的,比如影视实体的配置文件如下所示:
<movie>
<tag key="pic" type="div">
[资料来源:https://www.doc163.com]
<attribute type="class">main_home_movie_pics</attribute>
</tag>
……
</movie>
其中可以很清楚的看到对tag的描述,比如上例中,Html文件应该包含<div class=” main_home_movie_pics”></div>标记,可以通过EntityExtractorAssistant的实例ass抽取信息,EntityExtractorAssistant是基于Dom4J的xml解析器。接下来利用ass的方法getTags得到所有的标记,再利用父类中的containTag方法判断Html文件是否包含这些标记,最后如果全部包含返回true,反之,如果有一个不符合返回false。
(3) Extractor抽取器基本实现
① 基于分装器的抽取器基本实现
以HtmlExtractorForMovie为例描述一下这类抽取器的基本实现,如下:
基于分装器的抽取器主要的工作在于如何利用分装器将某些标记下的内容提取出来,比如说<div class=” main_home_movie_pics”></div>标记下有需要的内容。刚才简单介绍了实体配置文件,这里就利用这个配置文件对Html文件进行内容提取,大致流程如下:
首先定义实体实例,利用EntityExtractorAssistant将实体配置文件中的约束标记提取出来,再利用分装器从Html文件中将带有约束标记的内容提取出来,最后对内容做一下处理,将内容放入实体实例中,返回实体实例。
[资料来源:http://Doc163.com]
② 基于统计的抽取器基本实现
抽取器的实现部分主要集中在筛选算法上,其利用了标准方差的计算方法,实现过程如下:
int sum = 0;
int num = 0;
int len = sizeBlock.length;
// 获得还未被选取块个数及其总长度
for (int i = 0; i < len; i++)
if (!staBlock[i]) {
num++;
sum += sizeBlock[i];
}
// 定义还未被选取块平均长度
double avg = (double) sum / (1.0 * (double) num);
// 计算方差
double err = 0.0;
for (int i = 0; i < len; i++)
if (!staBlock[i]) {
double val = (double) sizeBlock[i] - avg;
val *= val;
err += val;
}
// 计算标准方差
return Math.sqrt(err) / (1.0 * (double) num);
(4) IndexBuilder索引构造器基本实现
IndexBuilder类基本方法实现如下:
主要方法:public void addEntity(Entity entity)
protected boolean hasExist(Entity entity)
过程描述:addEntity方法的功能是向索引中写入实体对象内容,利用IndexWriter类的方法write将封装了实体内容的Document写入索引中。最后关闭IndexWriter实例,结束添加实体。主要代码如下:
[资料来源:http://www.doc163.com]
//利用IndexWriter实例writer添加Document实例
writer.addDocument(EntityDocumentFactory.buildEntityDocument(entity));
hasExist方法主要是判断索引中是否含有了实体信息,其中以Entity中的属性keyAttribute为关键值检查。
这是IndexBuilder类的基本实现,在项目中还有三个类:JEIndexBuilder、ICT_IndexBuilder和StarndardIndexBuilder,它们继承类IndexBuilder类,主要实现addEntity方法。
4.2.2 用户接口子系统
(1) 搜索器基本实现
搜索器的实现需要有Lucene技术的支持。
主要方法:public EntitySet getSearchResults(String key)
实现过程:首先将key进行处理,利用分词器进行切分,然后实例化IndexSearcher为searcher,再利用实例searcher调用方法search得到Hits结果集,再对结果集进行分析处理。其实在这个过程中对分词器的选取应用了三个分词器JE,ICTCLAS和StandardAnalyzer,三个分词器原理已经在设计中提到,因为在构造索引用到的分词器和对输入的词进行切分的分词器是一个,必须相同。三个分词器可以对三个索引库进行搜索,但顺序并不是并行的,首先在ICTCLAS对应库中搜索,无结果再在JE对应库中搜索,最后如果前两中没有结果再在StandardAnalyzer对应库搜索。这样会返回更符合用户要求的信息,但也会带来效率问题。
[资料来源:http://www.doc163.com]
(2) 请求响应Servlet基本实现
因为应用类Ajax技术,在请求响应的Servlet中要以xml的格式传输数据,在实体内部定义一个可以将自己属性封装到xml格式字符串中是有必要的,在Servlet直接调用这个方法即可。
结 论
基于Lucene与Heritrix的搜索引擎构建,此课题的设计开发终于完成,在此过程中,遇到了困难,也收获了新知。
对源代码搜索引擎的开发和实现中,主要进行了以下工作:
(1) 在信息抓取模块,利用Heritrix对国内知名的网站www.bnb88.com和www.xinhuanet.com