[计算机软件及应用]第三小组项目总结报告.doc_第1页
[计算机软件及应用]第三小组项目总结报告.doc_第2页
[计算机软件及应用]第三小组项目总结报告.doc_第3页
[计算机软件及应用]第三小组项目总结报告.doc_第4页
[计算机软件及应用]第三小组项目总结报告.doc_第5页
已阅读5页,还剩34页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

基于Web的文献管理与检索系统 项目总结报告2011/2012学年 第二学期 山东大学软件学院组长:魏迪迪组员:袁灿吴林谦熊敏张森牛宗辉蔡徐熠目录基于Web的文献管理与检索系统1项目总结报告1一、引言31.1编写目的3二、系统概述32.1 课题背景32.2 开发环境32.3 基本功能需求3三、系统体系结构43.1 系统总体结构43.2 系统构成43.3 系统用例图5四、对网页的抓取5 4.1 功能简介5 4.2 流程图6 4.3 关键代码6 4.4 Heritrix抓取8 4.5 实验结果10五、对网页预处理115.1功能简介115.2 流程图115.3关键代码125.4实验结果18六、建立索引216.1 功能简介216.2流程图216.3关键代码226.4实验结果24七.、查询检索257.1 功能简介257.2 流程图257.3 结构图267.4 关键代码267.5 实验结果28八.、Struts2后台308.1 功能简介308.2 流程图308.3 关键代码31九、系统用户界面前台339.1 功能简介339.2 流程图339.3 关键代码349.4 实验结果35十、测试3510.1 定义3510.2 参考资料3610.3 测试原则3610.4 测试环境3610.5 功能测试3610.6 性能测试38十一、任务分配38十二、代码中遇到的难题38十三、自我评价与心得体会391、 引言l 编写目的本报告对现有的开源项目Heritrix和Lucene的内部功能架构进行了分析论述,在理解其设计思想的基础上进行扩展利用,设计一个有关论文垂直搜索引擎。结合程序代码说明,一步一步地完成对指定网页的抓取、论文信息的抽取、建立索引。最后建立了Web查询界面完成对整个系统的构建工作。本报告总结在开发过程中遇到的问题、难点及具体的解决方案,在某些模块中应用的主要技术、优化算法等,无论是对研究垂直搜索技术,还是构建一个实用的垂直搜索引擎都有一定的参考和借鉴价值。2、 系统概述l 课题背景 随着网络的快速发展,Web已经成为人们获取科研信息的主要途径。基于Web的文献管理与检索系统是新一代的科研系统,是传统CS文献管理系统的延伸,集文献管理与检索(搜索)于一体。它对电子图书馆中的相关论文信息进行爬取、索引并进行整合,定向分字段抽取出需要的数据进行处理后再以某种满足用户个性化需求的形式返回给用户。它是一种轻型的文献管理与检索系统,目标在于为研究某特定领域内的用户提供高质量的个性化文献管理与检索服务。它的特点包括:面向特定领域,专业性强;是用户兴趣制导的,针对性强,为用户提供基于Web的文献管理与检索的主动服务。本课题以面向计算机领域的科研论文为设计实例,设计开发一个面向计算机领域科研工作者的,集文献管理与检索一体的新型系统。l 开发环境本项目开发工具主要使用了Eclipse3.5+Lucene3.0+Myeclipse+Tomcat5.5l 基本功能需求 用户进入检索界面以后可以输入自己感兴趣的内容的关键字等来检索相关信息,从而从中查找相关内容网站网址。 系统能从相应站点开始搜集网页,通过预处理将所搜集的信息进行相关处理,然后建立索引并保存于索引库中。具体要求:1:对于学术论文,要求分别提取:题目,作者(单位)(多名),摘要,关键字, 发表期刊信息(名称,出版社,时间,卷,期)等网页上提供的各种信息 分别进行处理2:系统能够正常运行,用户多种字段单独、组合进行检索3:检索结果能够按照相关度、文章发表时间等因素排序。3、 系统体系结构l 系统总体结构系统主要有四大功能模块:网页信息的抓取模块、对保存到本地的网页信息抽取模块、对结构化的论文信息文本文件建立索引并存入索引库、系统界面的模块。l 系统的构成1. 爬虫软件:爬虫也称为“网络蜘蛛”(Spider),是一个功能很强的WEB扫描程序。它可以在扫描WEB页面的同时检索其内的超链接并加入扫描队列等待以后扫描。因为WEB中广泛使用超链接,所以一个Spider程序理论上可以访问整个WEB页面。为了保证网络机器人遍历信息的广度和深度需要设定一些重要的链接并制定相关的扫描策略。本实验用的是开源爬虫Heritrix。2. 解析器:网页被抓取下来保存到本地磁盘后,我们还要对其进行进一步处理,抽取页面中有用的信息,即页面中描述论文的部分。最终使其按一定的格式保存起来(本文为了方便起见,先将其保存为文本文件)等待后面建立索引时使用。3. 索引与检索: 在建立索引时,应该先定义Lucene的Document格式,将论文的所有信息封装成逻辑文档。索引按照倒排文件的格式存放。索引中的内容应尽量少,只要能够满足用户检索就可以了检索是垂直搜索引擎的核心。检索器利用索引库中的索引来查找与用户查询相匹配的文档,计算各个文档和查询关键词的相关度,并将相关度大于阈值的文档按照相关度递减的顺序排列,返回给用户。4. 用户接口:提供可视化的查询输入和结果输出界面。一般来说,在输出界面中,垂直搜索引擎将检索结果展示为一个线形的文档列表,其中包含了文档的标题和超链等信息。l 系统用例图通过关键字搜索用户搜集网页信息预处理索引与检索系统4、 对网页信息的抓取l 功能简介(1) 爬虫模块:我们组的爬虫模块是基于heritrix的,首先下载heritrix,然后再电脑上配置成功,而我们组主要是通过修改和扩展其中的其相应组件中的方法和父类方法来实现我们所需要的功能:扫描指定站点获取我们需要的网页信息。并在抓取的过程中统计各种数据,并以日志文件的形式存储于磁盘上,便于在解析时的使用。(2) Heritrix的组建构成:中央控制器:crawlcontroller抓取范围策略组件:crawlscope链接制造器:frontier多线程处理:toepool、toethread处理器processor和处理器链抓取任务craworderWeb控制台程序l 流程图l 关键代码1. 由于很多网站上的robots协议规定哪些内容不能访问,所以将爬虫中的robots设置为永远返回false:private boolean considerRobotsPreconditions(CrawlURI curi) return false; 2. 其中在org.archive.crawler.filter包中可以添加我们自己定义的过滤条件。3. 其中在org.archive.crawler.fetcher中的方法定义我们从http或ftp亦或DNS中获取我们的网页内容:例如:其中的方法:fetchHttp类:4. 其中在org.archive.crawler.extractor中的方法定义我们从http或ftp亦或DNS网页中抽取我们先要的内容和连接:例如其中的方法:extractorHTML类:从html中抽取: 5. 其中在org.archive.crawler.writer中的方法定义我们从将从网页中获取的内容以镜像的方式存储于磁盘中:例如其中的类:mirrorwriterprocessor6. 扩展Heritrix的FrontierScheduler来抓取论文详细信息页面,设置好Heritrix的爬行起始页面后,如果不作限制它会把页面上的所有的链接页面抓取下来保存到本地磁盘。这样抓取下来的页面就会杂乱无章,不利我们抽取页面内容。由于这个蜘蛛程序留有很多方便扩展的接口,那么现在我们就对其FrontierScheduler来实现对论文详细信息页面的抓取。扩展关键代码如下:public class FrontierSchedulerForLunWen extends FrontierSchedulerprivate static Logger LOGGER=Logger.getLogger(FrontierSchedulerForLunWen.class.getName();/构造函数public FrontierSchedulerForLunWen(String name)super(name);protected void schedule(CandidateURI caUri)/取得URL的字符串String url=caUri.toString();try/URL选择策略if(url.indexOf()!=-1&url.indexOf(.html)!=-1)|url.indexOf(robots.txt)!=-1|url.indexOf(dns:)!=-1)getController().getFrontier().schedule(caUri);elsereturn;catch(Exception e)e.printStackTrace();其中URL选择策略中共设置了4种约束,即是URL中包含:并且包含.htmlRobots.txtdns:包含这些字符串的URL才可以被加入到Frontier的等待队列中。也就说可以以此来限制Heritrix的抓取行为。其中:l 并且包含.html:是论文详细信息描述页面的URL格式即满足“http: //qk/数字.html一格式。因此,肯定要让其通过约束,以使论文详细信息能够得以保存。l Robots.txt:是针对robots策略发出的URL所包含的字符串,因此也应当让其加入到Frontier中。l dns:是Heritrix在做域名解释时,发出的一个请求URL的前缀,很显然也需要将其加入Frontier中。l Heritrix抓取在抓取前,应先将FrontierSchedulerForLunWen这个类加入到Processoroptions文件中,才能在Heritrix的创建任务时用上这个扩展功能。如图6-1所示。1. 创建一个job选则with defaults2. 设置爬取条件3. 设置参数4. 保存修改:产生一个状态为pending的job5. 运行该jobl 实验结果结果保存在Heritrix的jobs目录下5、 对网页预处理l 功能简介 解析是负责将爬虫抓取到得url地址及其内容提取出来,将需要的内容(例如:作者名、摘要、关键字等等)提取出来并以txt格式的文件保存起来,为后来的索引提供内容。l 流程图l 关键代码1. 解析网页信息的基类Extractor代码。在这个类中,实现了大部分的公用方法,比如递归遍历一个目录、正则匹配等。如下所示:public abstract class Extractor static File path1=null;protected static final String NEWLINE = rn;/* * 表示所有结果的输出路径 */private String outputPath = ;/* * 表示当前正在被处理的文件 */private String inuputFilePath;/* * 表示当前所有被抓取的网页的镜象根目录 在Heritrix用mirror目录表示 */private String mirrorDir = ;/* * HTMLParser的实例 */private Parser parser;/* * 分隔符 */public static final String SEPARATOR = =;/* * 装载需要的网页文件 * */public void loadFile(String path) try parser = new Parser(path);inuputFilePath = path;parser.setEncoding(GBK); catch (Exception e) e.printStackTrace();/* * 获取输出的路径 */public String getOutputPath() return outputPath;/* * 设置输出的路径,通常在初始化Extractor时就应该做 */public void setOutputPath(String outputPath) this.outputPath = outputPath;public Parser getParser() return parser;/* * 使用正则来匹配并获得网页中的字符串 */protected String getProp(String pattern, String match, int index) Pattern sp = Ppile(pattern);Matcher matcher = sp.matcher(match);while (matcher.find() return matcher.group(index);return null;/* * 抽象方法,用于供子类实现。 其功能主要是解释网页文件 将产品信息保存到 * */public abstract void extract();/* * 获取正在处理的文件的路径 */public String getInuputFilePath() return inuputFilePath;public String getMirrorDir() return mirrorDir;public void setMirrorDir(String mirrorDir) this.mirrorDir = mirrorDir;public void setInuputFilePath(String inuputFilePath) this.inuputFilePath = inuputFilePath;/* 递归遍历一个目录 */static int count1= 0;public static void traverse(Extractor extractor, File path)throws Exception if (path = null) return;if (path.isDirectory() String files = path.list();for (int i = 0; i files.length; i+) traverse(extractor, new File(path, filesi);/System.out.println(i); else String pathname = path.getAbsolutePath();/System.out.println(pathname+*);path1=path;String name = path.getName();/处理维普论文if (!(path.getAbsolutePath().contains(index)&(path.getAbsolutePath().endsWith(.html) ) System.out.println(path);count1+;extractor.loadFile(path.getAbsolutePath();extractor.extract();Extractor基类有一个抽象方法extract(),它主要是供子类实现对不同格式的页面的解析。除了这个抽象方法外,这类中还有一些公用的方法和类属性,代码中已经对每个属性进行了详细的说明,其中最重要的2个属性是:l outputPath:它表明了当前处理器处理后,将文本文件写到哪个目录下。l mirrorDir:它用与标明Heritrix抓取完网页后的镜像目录,即mirror目录。2. 解析论文详细信息的类ExtractWeiPu代码。这个类继承于上面的Extractor类,在这类中主要实现了其父类的抽象方法extract()。分析论文详细信息页面的源文件代码,利用正则表达式和HTMLPaser工具相结合的方法抽取出论文的内容。关键代码如下:public void extract() / TODO Auto-generated method stubPattern p = Ppile(t|r|n);String url=null;BufferedWriter bw = null;String path2=test.path1.getAbsolutePath();1 对爬取的网页进行分析,找到你想要的内容的特点,就可以设置过滤条件2 设置过滤条件,把你想要的过滤出来/创建属性过滤器 NodeFilter attributes_filter = new AndFilter(new TagNameFilter(td), new AndFilter(new HasChildFilter(new AndFilter(new TagNameFilter(b),new HasAttributeFilter(class,black),new HasChildFilter(new TagNameFilter(a) );/创建摘要过滤器 NodeFilter abstract_filter = new AndFilter(new TagNameFilter(td), new HasAttributeFilter(class, sum); /创建作者过滤器 NodeFilter author_filter = new AndFilter(new TagNameFilter(strong), new HasAttributeFilter(class, gray);/创建标题过滤器NodeFilter title_filter = new TagNameFilter(h1);3 提取我们想要的内容(如提取URL、标题)/提取标题信息try /Parser parser = new Parser(path2);parser.setEncoding(UTF-8);/Parser根据过滤器返回所有满足过滤条件的节点NodeList title_nodes = parser.parse(title_filter);/遍历所有节点for (int i = 0; i title_nodes.size(); i+) Node node_title=title_nodes.elementAt(i);/用空格分割节点内部html文本String names = node_title.toPlainTextString().split( );StringBuffer title = new StringBuffer();/创建要生成的文本文件名for (int k = 0; k names.length; k+) title.append(namesk);/.append(-);bw = new BufferedWriter(new FileWriter(new File(this.getOutputPath()+ (new Date().getTime() + .txt);/获取当前提取页的完整URL地址int startPos = getInuputFilePath().indexOf(mirror) + 6;String url_seg = getInuputFilePath().substring(startPos);url_seg = url_seg.replaceAll(, /); url = http:/ + url_seg;4 写入txt文件/创建要生成的文件bw.write(url + NEWLINE);/写入当前提取页的完整URL地址bw.write(names0 + NEWLINE);/标题article.setUrl(url); article.setTitle(title.toString();System.out.println(article.getUrl();System.out.println(article.getTitle(); catch (Exception e) e.printStackTrace();5 关闭写入 tryif (bw != null)bw.close();catch(IOException e)e.printStackTrace();l 实验结果完成以上两个类的设计后,在Eclipse中运行ExtractWeiPu类中的main()方法后就可以将mirrorDir(镜像目录)下保存的论文详细信息页面中的内容解析出来,以文本文件的格式保存到outputPath设定的路径下。如图:Txt中存的内容如下图所示:每一行依次为URL、标题、作者、摘要、关键字、期刊来源、数据库。这样设置有利于接下来的创建索引。6、 创建索引l 功能简介本模块主要功能是为爬取并解析后的网页建立索引,为查询模块提供检索查询服务。基于lucene实现,模块只实现了对万方网站和维普网站解析结果的索引。利用lucene分别对万方和维普网站解析结果建立倒排索引,并调用lucene中的Optimize()方法对索引进行优化,并给出为文档建立索引大致时间,方便检验索引效率和进一步优化。l 流程图l 关键代码1. 实例化一个构造器IndexWriter indexWriter = new IndexWriter(directory,luceneAnalyzer,MaxFieldLength.LIMITED); 这个构造函数具有三个参数:l directory为索引文件存放的路径。l luceneAnalyzer分词工具 l MaxFieldLength.LIMITED它是一个boolean型变量,如果为true,表示要重写指定的存放索引目录下的索引文件;如果为false,表示在指定存放索引目录下已经存在的索引文件的基础上,向其中继续追加新的索引文件。代码如下:Directory directory = FSDirectory.open(new File(G:productIndex); Analyzer luceneAnalyzer = new SmartChineseAnalyzer(Version.LUCENE_30); IndexWriter indexWriter = new IndexWriter(directory, luceneAnalyzer, MaxFieldLength.LIMITED); File textFiles = fileDir.listFiles(); long startTime = new Date().getTime(); 2. 创建索引第一步并未创建索引,只是实例化了一个索引器,建立索引的过程是在一个IndexWriter索引器实例存在的前提下,通过为其添加Document,这样才能真正添加索引。代码如下:/增加document到索引去 for (int i = 0; i textFiles.length; i+) if (textFilesi.isFile()& textFilesi.getName().endsWith(.txt) System.out.println(File + textFilesi.getCanonicalPath() + 正在被索引.); String temp = FileReaderAll(textFilesi.getCanonicalPath(),GBK); for(int j=0;j6;j+) if(tempj=null) a=false; System.out.println(tempj); if(!a) continue; Document document = new Document(); Field FieldPath = new Field(url, temp0,Field.Store.YES, Field.Index.ANALYZED); Field FieldTitle = new Field(title, temp1, Field.Store.YES,Field.Index.ANALYZED); Field FieldAuthor = new Field(author, temp3, Field.Store.YES,Field.Index.ANALYZED); Field FieldAbs = new Field(abs, temp2, Field.Store.YES,Field.Index.ANALYZED); Field FieldKey = new Field(key, temp5, Field.Store.YES,Field.Index.ANALYZED); Field FieldDate = new Field(date,temp4, Field.Store.YES,Field.Index.ANALYZED); document.add(FieldPath); document.add(FieldTitle); document.add(FieldAuthor); document.add(FieldAbs); document.add(FieldKey); document.add(FieldDate); indexWriter.addDocument(document); 3. 优化索引,关闭写入/optimize()方法是对索引进行优化 indexWriter.optimize(); indexWriter.close(); 4. 测试索引时间/测试一下索引的时间 long endTime = new Date().getTime(); System.out.println(这花费了 + (endTime - startTime) + 毫秒来把文档增加到索引里面去!); 5. 遍历目录并读取txt public static String FileReaderAll(String FileName, String charset) throws IOException BufferedReader reader = new BufferedReader(new InputStreamReader( new FileInputStream(FileName), charset); String line = new String(); String tem = new String TYPE_NUM; int i=0; while (line = reader.readLine() != null) temi= line; i+; reader.close(); return tem; l 实验结果实验执行结果在磁盘上保存的索引用lukeall-3.4.0_1对索引进行了观察7、 查询检索l 功能简介 查询检索模块:我们所用的是基于lucene开源全文引擎工具包下的开发和应用。完成的任务是:接受用户输入的信息,与索引库中的存储的信息匹配,返回匹配成功的结果.其中分为综合查询、按作者查询、按论文题目查询、按摘要查询、按关键字、按日期查询。l 流程图l 结构图l 关键代码1. 把查询字符串转为query对象(模糊查询)。这里的queryString是我们要搜索的关键字;n为选择什么查询方式;firstResult为从第几个结果开始提取;maxResults为一页最多几个结果。private static void searchAndPrintResult(String queryString,int n, int firstResult, int maxResults) try System.out.println( / 对应的查询字符串为: + queryString);Query querytitle = parseTitle.parse(queryString);Query queryauthor = parserAuthor.parse(queryString);Query queryabs = parserAbs.parse(queryString);Query querykey = parserKey.parse(queryString);Query querydate = parserDate.parse(queryString);BooleanQuery booleanQuery = new BooleanQuery();booleanQuery.add(querytitle, Occur.SHOULD);booleanQuery.add(queryauthor, Occur.SHOULD);booleanQuery.add(queryabs, Occur.SHOULD);booleanQuery.add(querykey, Occur.SHOULD);booleanQuery.add(querydate, Occur.SHOULD);2. 搜索得到中间结果/ b, 搜索,得到中间结果IndexSearcher indexSearcher = new IndexSearcher(Configuration.getDirectory();TopDocs topDocs = indexSearcher.search(booleanQuery, 100);3. 根据内部编号得到Document数据/ 根据内部编号取出相应的Document数据ScoreDoc scoreDoc = topDocs.scoreDocsi;Document doc = indexSearcher.doc(scoreDoc.doc);4. 把Document转为Article,并添加到集合中/ 把Document转为ArticleArticle article = ArticleDocumentUtils.document2Article(doc);list.add(article); / 添加到集合中5. 实现相关度排序与时间排序。当n=1时,按时间排序;当n为其他时,按相关度排序。代码如下:public static TopDocs Paixu(int i,Query query,int firstResult,int maxResults) throws IOExceptionTopDocs topDocs = null;if(i=1)Sort sort = new Sort(new SortField(date, SortField.STRING);topDocs = indexSearcher.search(query, null, 100, sort);else topDocs = indexSearcher.search(query, firstResult + maxResults);return topDocs;6. 实现高亮/ 一、创建并配置高亮器Formatter formatter = new SimpleHTMLFormatter(, ); / 如果调用无参的构造方法,则默认为与Scorer scorer = new QueryScorer(booleanQuery); / 查询条件(获取要高亮关键字)Highlighter highlighter = new Highlighter(formatter, scorer);Fragmenter fragmenter = new SimpleFragmenter(200); / 指定摘要的字符数量,如果调用无参的构造方法,则默认为100个字符。 highlighter.setTextFragmenter(fragmenter)String text = highlighter.getBestFragment(Configuration.getAnalyzer(), title, doc.get(title);if (text != null) doc.getField(title).setValue(text); / 使用高亮后的文本替换原文本7. 实现分页。只需在main()方法中设置firstResult。如我们设置是10个一页,那么第二页就是从第11个开始,firstResult设置为10(0是第一个)。private static void searchAndPrintResult(String queryString,int n, int firstResult, int maxResults) for (int i = firstResult; i endIndex; i+) / 只取一段数据/ 根据内部编号取出相应的Document数据ScoreDoc scoreDoc = topDocs.scoreDocsi;Document doc = indexSearcher.doc(scoreDoc.doc);8. 实现精确查询。如标题精确查询booleanQuery.add(querytitle, Occur.MUST);l 实验结果模糊查询(相关度排序)。最上面为相关度得分。高亮显示:就是形成的html文件中相应内容一 内 容 对标题的精确查找(按时间排序)8、 Struts

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论