郭永利,盧穎穎
隨著互聯(lián)網(wǎng)技術(shù)的飛速發(fā)展,互聯(lián)網(wǎng)中的信息量也越來(lái)越大,如何更加有效地利用這些信息資源,已經(jīng)越來(lái)越受到人們的關(guān)注?;ヂ?lián)網(wǎng)中存在的信息來(lái)源十分廣泛,與此同時(shí),存在的形式也是多種多樣,包括圖像、文本、視頻、音頻等不同的形式,面對(duì)著不同來(lái)源,不同形式的海量信息,如何準(zhǔn)確、快速地找到自己所需要的信息成為我們?cè)谑褂没ヂ?lián)網(wǎng)時(shí)候所面臨的一個(gè)問(wèn)題,因此,開發(fā)一個(gè)搜索引擎就非常必要。目前,成熟的搜索引擎如 Lycos、Yahoo、Google、百度等各有優(yōu)點(diǎn)[1],如Google比Yahoo能更快、更準(zhǔn)確搜索到所需信息,百度中文搜索引擎支持網(wǎng)頁(yè)信息檢索,圖片,F(xiàn)lash,音樂(lè)等多媒體信息的檢索等,而本文搜索引擎的開發(fā)是通過(guò)網(wǎng)絡(luò)爬蟲抓取信息,然后再通過(guò)一定的技術(shù)對(duì)網(wǎng)頁(yè)信息進(jìn)行提取、處理,將抓取到的信息存放在索引數(shù)據(jù)庫(kù)中,通過(guò)一些查詢接口實(shí)現(xiàn)信息檢索,幫助用戶在海量的信息中迅速地、準(zhǔn)確地找到用戶真正感興趣的信息。
搜索引擎是指根據(jù)一定的策略、運(yùn)用特定的計(jì)算機(jī)程序從互聯(lián)網(wǎng)上搜集信息,在對(duì)信息進(jìn)行組織和處理后,為用戶提供檢索服務(wù),將用戶檢索相關(guān)的信息展示給用戶的系統(tǒng)。搜索引擎主要包括全文索引、目錄索引、元搜索引擎、垂直搜索引擎、集合式搜索引擎、門戶搜索引擎與免費(fèi)鏈接列表等。全文搜索引擎是目前廣泛應(yīng)用的主流搜索引擎[2-3]。它可以對(duì)被索引的文章中的每一個(gè)詞建立索引,在用戶檢索時(shí),檢索程序就會(huì)根據(jù)事先建立好的索引進(jìn)行查找,并將查找的結(jié)果反饋給用戶。本文的主要工作就是使用 Java設(shè)計(jì)并實(shí)現(xiàn)了一個(gè)Web全文搜索引擎,搜索引擎結(jié)構(gòu)設(shè)計(jì)如圖1所示:
圖1 搜索引擎結(jié)構(gòu)
創(chuàng)建搜索引擎的第一步就是要設(shè)計(jì)一個(gè)程序在海量的互聯(lián)網(wǎng)信息中漫游,并抓取網(wǎng)頁(yè)信息。這個(gè)程序被稱為網(wǎng)絡(luò)蜘蛛,網(wǎng)絡(luò)蜘蛛也被稱為自動(dòng)搜索機(jī)器人,它主要用于分析網(wǎng)頁(yè)上的每一個(gè)超鏈接,并根據(jù)超鏈接鏈到其他網(wǎng)頁(yè)中的超鏈接[4],網(wǎng)絡(luò)蜘蛛結(jié)構(gòu)設(shè)計(jì)如圖2所示:
圖2 網(wǎng)絡(luò)蜘蛛結(jié)構(gòu)
搜索引擎對(duì)網(wǎng)絡(luò)蜘蛛抓取到的網(wǎng)頁(yè)信息進(jìn)行整理,這一過(guò)程稱為“創(chuàng)建索引”。索引器結(jié)構(gòu)設(shè)計(jì)如圖3所示:
圖3 索引器結(jié)構(gòu)
搜索引擎每時(shí)每刻都要收到來(lái)自大量用戶的幾乎是同時(shí)發(fā)出的查詢,它按照每個(gè)用戶的要求檢查自己的索引,在極短時(shí)間內(nèi)找到用戶需要的資料。檢索器結(jié)構(gòu)設(shè)計(jì)如圖4所示:
圖4 檢索器結(jié)構(gòu)
互聯(lián)網(wǎng)可以看成一個(gè)超級(jí)大的“圖”,網(wǎng)絡(luò)蜘蛛的遍歷網(wǎng)頁(yè)算法采用圖的寬度優(yōu)先遍歷(BFS)算法,其爬行策略實(shí)現(xiàn)算法如下[5]:
1)將入口URL入隊(duì)至待訪問(wèn)URL的隊(duì)列中去。
2)URL從待訪問(wèn)URL隊(duì)列出隊(duì),使用開源HTML解析庫(kù)HTMLParser對(duì)給出的入口URL進(jìn)行解析,判斷抓取到的URL是否在已訪問(wèn)URL集合中,若不在,則將URL存儲(chǔ)在待訪問(wèn)URL的隊(duì)列中去(入隊(duì)),若存在則什么也不做。
3)使用HTMLParser對(duì)出隊(duì)的URL進(jìn)行解析,解析該URL的標(biāo)題、內(nèi)容、關(guān)鍵詞、創(chuàng)建時(shí)間等信息。
4)使用Lucene為HTMLParser解析到的網(wǎng)頁(yè)信息創(chuàng)建索引。
5)出隊(duì)的URL添加至已訪問(wèn)URL集合中去。
6)重復(fù)(2)~(5)的過(guò)程。
(1)數(shù)據(jù)結(jié)構(gòu):隊(duì)列和散列表(哈希表)
首先要構(gòu)建用于存儲(chǔ)抓取到的URL待訪問(wèn)的URL隊(duì)列,在構(gòu)建隊(duì)列時(shí)需要考慮以下兩方面因素:
1)隊(duì)列中將要存儲(chǔ)的元素個(gè)數(shù)非常之多并且數(shù)量無(wú)法確定;
2)在隊(duì)列的隊(duì)頭和隊(duì)尾處經(jīng)常進(jìn)行刪除和添加操作。
針對(duì)以上兩點(diǎn),使用java集合類LinkedList的鏈?zhǔn)酱鎯?chǔ)結(jié)構(gòu)來(lái)實(shí)現(xiàn)未訪問(wèn)URL隊(duì)列。這個(gè)未訪問(wèn)URL隊(duì)列主要用來(lái)存儲(chǔ)爬蟲抓取到的 URL,通過(guò)一系列的出隊(duì)入隊(duì)操作實(shí)現(xiàn)對(duì)網(wǎng)頁(yè)的寬度優(yōu)先遍歷。
(2)要構(gòu)建散列表。在根據(jù)未訪問(wèn)URL隊(duì)列對(duì)URL進(jìn)行抓取和解析的時(shí)候,還需要一個(gè)數(shù)據(jù)結(jié)構(gòu)散列表來(lái)存儲(chǔ)已經(jīng)訪問(wèn)過(guò)的URL來(lái)避免對(duì)同一個(gè)URL的重復(fù)抓取和解析。在URL從未訪問(wèn)隊(duì)列出隊(duì)以后,首先,判斷一下,它有沒(méi)有在這個(gè)數(shù)據(jù)結(jié)構(gòu)中,只有當(dāng)該URL不在這個(gè)已訪問(wèn)URL集合中時(shí)才對(duì)其進(jìn)行其他操作。否則,將該URL丟棄。這個(gè)數(shù)據(jù)結(jié)構(gòu)需要具有以下兩個(gè)特點(diǎn):
1)結(jié)構(gòu)中存儲(chǔ)的URL不可以重復(fù)。
2)由于URL數(shù)量眾多,考慮到查找性能問(wèn)題,需要該結(jié)構(gòu)能夠快速地查找。
針對(duì)以上兩點(diǎn),采用Java集合類HashSet來(lái)實(shí)現(xiàn)存儲(chǔ)已訪問(wèn)URL的散列表集合類。
這個(gè)已訪問(wèn)URL集合主要是記錄網(wǎng)絡(luò)蜘蛛已經(jīng)訪問(wèn)過(guò)的URL,在網(wǎng)絡(luò)蜘蛛訪問(wèn)一個(gè)從未訪問(wèn)URL隊(duì)中出隊(duì)的U RL時(shí),首先判斷一下這個(gè)URL是否已經(jīng)在已訪問(wèn)URL集合中存在,不存在的時(shí)候再進(jìn)行訪問(wèn),這樣可以避免對(duì)同一URL多次不必要的訪問(wèn)。
(3)網(wǎng)絡(luò)蜘蛛抓取網(wǎng)頁(yè)
HTMLParser是用一個(gè)純java寫的html解析庫(kù),它不依賴于其它的java庫(kù)文件,主要用于改造或提取html。它能超高速解析html,而且不會(huì)出錯(cuò)。使用HTMLParser的HTML鏈接提取功能提取網(wǎng)頁(yè)中的鏈接的過(guò)程如下:
1)創(chuàng)建過(guò)濾器,過(guò)濾a標(biāo)簽中的URL:NodeFilter filt er = new TagNameFilter("a");
2)創(chuàng)建解析器:Parser parser = new Parser();
3)使用 parser.setURL(url)和setEncoding()設(shè)置需要解析的URL和編碼方式;
4)獲取解析的結(jié)果:NodeList list = parser.extractAll NodesThatMatch(filter);
5)遍歷得到的解析結(jié)果;
6)在將解析到的URL存入未訪問(wèn)URL隊(duì)列之前需要對(duì)其進(jìn)行一些檢查,把一些錯(cuò)誤的鏈接或者是無(wú)法訪問(wèn)的鏈接過(guò)濾掉。
使用Lucene創(chuàng)建索引,Lucene是一個(gè)開放源代碼的全文檢索引擎工具包[6-8],即它不是一個(gè)完整的全文檢索引擎,而是一個(gè)全文檢索引擎的架構(gòu),提供了完整的查詢引擎和索引引擎。Lucene提供了五個(gè)基礎(chǔ)的類,對(duì)文檔進(jìn)行索引,下面是使用Lucene為HtmlDoc實(shí)例創(chuàng)建索引的相關(guān)操作。
1)創(chuàng)建分詞器,這里使用的是Lucene默認(rèn)的分詞器;
2)設(shè)置IndexWriter類的相關(guān)配置:
3)設(shè)置索引的保存路徑:
4)創(chuàng)建 Lucene索引器:IndexWriter writer = new IndexWriter(dir,iwc);
5)創(chuàng)建Document對(duì)象:Document doc = new Document();
6)為Document對(duì)象添加HTMLField域;
7)添加 Document至索引器中去:writer.addDocument(doc);
8)關(guān)閉索引器:writer.close();
1)創(chuàng)建IndexReader對(duì)象讀取索引器創(chuàng)建的索引;
2)創(chuàng)建分詞器Analyzer對(duì)用戶輸入的字符串進(jìn)行分詞處理;
3)使用IndexReader對(duì)象創(chuàng)建檢索器IndexSearcher;
4)使用分詞器 Analyzer創(chuàng)建QueryParser對(duì)象,解析用戶輸入的檢索字符串;
5)取得解析檢索字符串返回的Query對(duì)象;
6)使用 Query對(duì)象執(zhí)行檢索將默認(rèn)排序結(jié)果放置到TopDocs結(jié)果集;
7)得到檢索結(jié)果總數(shù)量:hitsSize = results.totalHits;。
1)設(shè)置高亮顯示html標(biāo)簽
2)創(chuàng)建高亮顯示對(duì)象:Highlighter highlighter = new Highlighter(formatter,scorer);
3)設(shè)置高亮顯示附近字符串大?。篎ragmenter fragmenter = new SimpleFragmenter(200);
4)設(shè)置高亮:highlighter.setTextFragmenter(fragmenter);
用戶可以在檢索器的文本框內(nèi)輸入需要檢索的關(guān)鍵詞,點(diǎn)擊搜索按鈕,檢索器將自動(dòng)顯示與關(guān)鍵詞相關(guān)的檢索結(jié)果,搜索“上海車展”檢索器返回檢索結(jié)果效果。如圖5所示:
圖5 檢索結(jié)果示意圖
搜索引擎是一種信息檢索服務(wù)系統(tǒng),它可以幫助用戶在互聯(lián)網(wǎng)上快速地查找對(duì)自己有用的信息。通過(guò)網(wǎng)絡(luò)爬蟲抓取信息,然后在通過(guò)一定的技術(shù)對(duì)網(wǎng)頁(yè)信息進(jìn)行提取、處理,將抓取到的信息存放在索引數(shù)據(jù)庫(kù)中,通過(guò)一些查詢接口實(shí)現(xiàn)信息檢索。本搜素引擎的設(shè)計(jì)與實(shí)現(xiàn)是基于全文搜索進(jìn)行的,設(shè)計(jì)了網(wǎng)絡(luò)蜘蛛、索引器和檢索器的結(jié)構(gòu),并利用Jav a語(yǔ)言進(jìn)行了搜素引擎的實(shí)現(xiàn),通過(guò)檢索實(shí)驗(yàn),檢索速度<=200ms,該搜索引擎是一個(gè)比較高效的檢索工具,但是系統(tǒng)實(shí)現(xiàn)的網(wǎng)絡(luò)蜘蛛并非真正意義上的全自動(dòng),而是必須給定網(wǎng)頁(yè)入口并告訴網(wǎng)絡(luò)蜘蛛要抓多少?gòu)埦W(wǎng)頁(yè),它才能正常抓取網(wǎng)頁(yè),同時(shí)檢索策略有待進(jìn)一步改進(jìn),以便進(jìn)一步提升檢索速度。
[1]孫宏.搜索引擎技術(shù)與發(fā)展綜述[J].計(jì)算機(jī)光盤軟件與應(yīng)用,2012(14):10-15.
[2]李國(guó)芳.全文搜索引擎快速搭建的設(shè)計(jì)與實(shí)現(xiàn)[J].計(jì)算機(jī)與現(xiàn)代化,2012(11):18-21.
[3]克羅夫特(美).搜索引擎:信息檢索實(shí)踐[M].北京:機(jī)械工業(yè)出版社,2010:69-83.
[4]李浩.網(wǎng)絡(luò)蜘蛛的研究與實(shí)現(xiàn)[J].科技信息,2012(26):18-23.
[5]陳建峽.基于PageRank的Lucene排序算法優(yōu)化與實(shí)現(xiàn)[J].計(jì)算機(jī)工程與科學(xué),2012(10):19-23.
[6]劉敏娜.基于 Lucene的中文分詞技術(shù)改進(jìn)[J].咸陽(yáng)師范學(xué)院學(xué)報(bào),2012(02):25-28.
[7]麥肯德利斯等(美).Lucene實(shí)戰(zhàn)[M].北京:人民郵電出版社,2011:53-92.
[8]于天恩.Lucene搜索引擎開發(fā)權(quán)威經(jīng)典[M].北京:中國(guó)鐵道出版社,2008:134-182.