搜索引擎的設計與實現_第1頁
搜索引擎的設計與實現_第2頁
搜索引擎的設計與實現_第3頁
搜索引擎的設計與實現_第4頁
搜索引擎的設計與實現_第5頁
已閱讀5頁,還剩51頁未讀, 繼續免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

web搜索引擎的設計與實現摘要隨著網絡的迅猛發展。網絡成為信息的極其重要的來源地,越來越多的人從網絡上獲取自己所需要的信息,這就使得像Google[40],百度[39]這樣的通用搜索引擎變成了人們尋找信息必不可少的工具。本文在深入研究了通用搜索引擎基本原理、架構設計和核心技術的基礎上,結合小型搜索引擎的需求,參照了天網,lucene等搜索引擎的原理,構建了一個運行穩定,性能良好而且可擴充的小型搜索引擎系統,本文不僅僅完成了對整個系統的設計,并且完成了所有的編碼工作。本文論述了搜索引擎的開發背景以及搜索引擎的歷史和發展趨勢,分析了小型搜索引擎的需求,對系統開發中的一些問題,都給出了解決方案,并對方案進行詳細設計,編碼實現。論文的主要工作及創新如下:1.在深刻理解網絡爬蟲的工作原理的基礎上,使用數據庫的來實現爬蟲部分。2.在深刻理解了中文切詞原理的基礎之上,對lucene的切詞算法上做出了改進的基礎上設計了自己的算法,對改進后的算法實現,并進行了準確率和效率的測試,證明在效率上確實提高。3.在理解了排序索引部分的原理之后,設計了實現索引排序部分結構,完成了詳細流程圖和編碼實現,對完成的代碼進行測試。4.在完成搜索部分設計后,覺得效率上還不能夠達到系統的要求,于是為了提高系統的搜索效率,采用了緩存搜索頁面和對搜索頻率較高詞語結果緩存的兩級緩存原則來提高系統搜索效率。關鍵詞:搜索引擎,網絡爬蟲,中文切詞,排序索引ABSTRACTWiththerapidlydevelopingofthenetwork.Networkbecameavitalinformationsource,moreandmorepeopleareobtainingtheinformationthattheyneedfromthenetwork,thismakingwebsearchenginehasbecomeessentialtooltopeoplewhentheywanttofindsomeinformationfrominternet.Inthispaper,within-depthstudyofthebasicprinciplesofgeneralsearchengines,thedesignandcoretechnologyarchitecture,combiningwiththeneedsofsmallsearchengineandinthelightofthe"tianwang",lucenesearchengine,Ibuildastable,goodperformanceandcanbeexpandedsmall-scalesearchenginesystem,this

articlenotonlycompletedthedesignoftheentiresystem,butalsobasicallycompletedallthecodingwork.Thisarticledescriblenotonlythebackgroundofsearchengines,butalsothehistoryofsearchenginedevelopinganddevelopingtrends,andanalysetheneedsofsmallsearchenginesandgivingsolutionsthetotheproblemswhichwasfoundinthedevelopmentofthesystem,andmakingadetailedprogramdesign,codingtoachieve.

Themainthesisofthearticleandinnovationareasfollows:1.withthedeepunderstandingoftheworkingprincipleofthenetworkspider.Iacheivednetworkspiderwithusingdatabasesystem.2.withthedeepunderstandingofChinesesegmentationandsegmentationalgorithmoflucenesystem,Imademyownsegmentationalgorithm,andgivealotofteststomysegmentationalgorithmtoprovidethatmysegmentationalgorithmisbetter.3.withthedeepunderstandingofsortedandindexalgorithm,Idesignedmyownsortedandindexalgorithmwiththedata-structIdesignedandcodingit,itwasprovidedavailableafterlotsoftests.4.afterdesignofsearchpart,Ifoudtheefficiencyofthepartisnotverypoor,soIdesignedtwo-stagecachedevicetoimpovetheefficiencyofthesystem.Keywords:searchengine,netspider,Chinesesegmentation,sortedandindex目錄第一章緒論 11.1搜索引擎出現的背景及意義 11.2搜索引擎的發展歷史及趨勢 11.3本文主要工作 31.4論文結構 4第二章系統結構 52.1概述 52.2系統結構 52.2.1爬蟲 62.2.2信息處理 62.2.3排序和索引 62.2.4搜索 62.3搜索引擎主要指標及分析 62.4開發語言 72.5小結 8第三章爬蟲 93.1概述 93.2爬蟲結構分析 93.2.1爬蟲初始化 103.2.2從網頁中提取url 113.2.3URL存儲 123.2.4從數據庫中提取url 123.3小結 13第四章信息處理 144.1概述 144.2轉換 154.3切詞 184.3.1中文切詞 194.3.2中文切詞測試 254.3.3英文切詞 274.3.4數字切詞 284.3.5符號處理 294.3.6詞語存儲 304.4小結 31第五章排序索引 335.1概述 335.2統計相關url 335.3排序 345.4索引 365.5小結 37第六章搜索 386.1概述 386.2實現搜索 386.3性能優化 416.4小結 42第七章總結與展望 437.1總結 437.3展望 44參考文獻 47致謝 49第一章緒論1.1搜索引擎出現的背景及意義網絡的出現以及發展對于世界發展的意義是極其重要的,它讓地球村的理念變成的現實,信息的傳輸不再受到時間和空間的限制。隨著網絡技術和應用的不斷發展,互聯網已經成為了信息的重要來源地,人們越來越依靠網絡來查找他們所需要的信息。我們所處的是一個信息爆炸的時代,Google的索引在1998年開始工作,當時他們收集了2600萬個頁面,2000年就突破了10億,到10年后的2008年達到了1,000,000,000,000,Google的數據庫變成了全球最龐大的索引之一[8],數量之龐大讓我們震驚。這么巨大的數字導致了一個問題,"RichData,PoorInformation"。我們就好像處在一個信息的迷宮,因此,如何有效快速的找到自己需要的信息成為了一個極其重要的問題。在沒有搜索引擎的時代,用戶希望尋找某方面的信息,就必須通過各種途徑或者是網站之間的連接尋找,可以這樣說,脫離的搜索引擎的網站,就像是信息海洋中的一個一個的孤島,用戶必將面臨巨大的搜索成本,同時必須付出大量的時間和精力。搜索引擎的出現改變了上述的現象[4],它通過程序的自動搜尋并建立索引,將這些信息孤島聯系起來,形成了一張巨大的信息網,并且運用分布式計算的巨大力量,能夠讓用戶從海量數據中摒除垃圾信息,獲取想要的知識。搜索引擎不僅僅是節省了用戶的時間,通過挖掉搜尋成本這座墻,它讓許許多多的不可能成為可能。1.2搜索引擎的發展歷史及趨勢搜索經歷了三代的更新和發展:[8]第一代搜索引擎出現于1994年。這類搜索引擎一般都索引少于1,000,000個網頁,極少重新搜集網頁并去刷新索引。而且其檢索速度非常慢,一般都要等待10秒甚至更長的時間。第二代搜索出現在1996年。第二代搜索引擎系統大多采用分布式方案(多個微型計算機協同工作)來提高數據規模、響應速度和用戶數量,它們一般都保持一個大約50,000,000網頁的索引數據庫,每天能夠響應10,000,000次用戶檢索請求。第三代搜索引擎年代的劃分和主要特性至今沒有統一的認識,不過至少可以肯定的是:第三代搜索引擎是對第二代搜索引擎在搜索技術上的改進,主要增加了互動性和個性化等高級的技術,為用戶使用搜索引擎獲取信息獲得更好的體驗。至于互動性的評價標準是什么,以及第三代搜索引擎到底比第二代搜索引擎增加了多少價值——尤其是為企業利用搜索引擎開展網絡營銷增加了哪些價值,目前并沒有非常令人信服的研究結論。這也就是目前所謂的第三代搜索引擎并沒有表現出太多優勢的原因之一?,F在,網絡上有很多著名的搜索引擎,百度,google,yahoo等等,百度從2005年誕生到現在成為全球最大的中文搜索引擎,可想而知,發展的速度的多么的快,人們對搜索引擎的的需求的多大,百度的日點擊率我無法在找到確切的數字,但是我們可以計算一下,截至2008年底,中國網民規模達到2.98億人[9],每個網民上網點擊百度的次數應該不少于十次吧,像我們要在百度上找資料的網名點擊率百次不止,所以百度的日點擊率是多么驚人。搜索引擎經過幾年的發展和摸索,越來越貼近人們的需求,搜索引擎的技術也得到了很大的發展。搜索引擎在將來的的發展趨勢大概有以下幾個方面:[10]1.提高對用戶輸入的理解為了提高搜索引擎對用戶檢索提問的理解,就必須有一個好的檢索提問語言,為了克服關鍵詞檢索和目錄查詢的缺點,現在已經出現了自然語言智能答詢。用戶可以輸入簡單的疑問句,比如“howcankillvirusofcomputer?”。搜索引擎在對提問進行結構和內容的分析之后,或直接給出提問的答案,或引導用戶從幾個可選擇的問題中進行再選擇。自然語言的優勢在于,一是使網絡交流更加人性化,二是使查詢變得更加方便、直接、有效。就以上面的例子來講,如果用關鍵詞查詢,多半人會用“virus”這個詞來檢索,結果中必然會包括各類病毒的介紹、病毒是怎樣產生的等等許多無效信息,而用“howcankillvirusofcomputer?”,搜索引擎會將怎樣殺病毒的信息提供給用戶,提高了檢索效率。2.對檢索的結果進行處理對檢索的結果處理,有以下幾個方向:其一,使用鏈接評價,就是將網頁的鏈接數量算作網頁評分因素之一,這樣搜索的結果就更加的能夠滿足用戶的要求,在這個方面google()的“鏈接評價體系”已經做出了相當出色的成績。其二,使用大眾訪問性,就是將訪問數量(也可以叫做點擊數量)算作網頁評分的因素之一,這樣想這樣的網站的分數會很高,而這樣的網站很多時候都是用戶想找的,這樣能夠提高搜索引擎的準確率。其三,去掉結果中的附加信息。有調查指出,過多的附加信息加重了用戶的信息負擔,為了去掉這些過多的附加信息,可以采用用戶定制、內容過濾等檢索技術。3.確定搜集返回,提高針對性在這個方面現在的發展的方向是:其一,垂直主題搜索。垂直主題的搜索引擎以其高度的目標化和專業化在各類搜索引擎中占據了一系席之地,比如象股票、天氣、新聞等類的搜索引擎,具有很高的針對性,用戶對查詢結果的滿意度較高。我認為,垂直主題有著極大的發展空間。其二,非www信息的搜索。搜索引擎提供了例如ftp等非www信息的搜索。其三,多媒體搜索。搜索引擎還提供了例如包括聲音、圖像等等多媒體信息的檢索。4.提供更優化的檢索結果在這個方面有兩個主要的發展方向:其一,純凈搜索引擎。這類搜索引擎沒有自己的信息采集系統,利用別人現有的索引數據庫,主要關注檢索的理念、技術和機制等。其二,元搜索引擎。元搜索引擎(metasearchenging)是將用戶提交的檢索請求到多個獨立的搜索引擎上去搜索,并將檢索結果集中統一處理,以統一的格式提供給用戶,因此有搜索引擎之上的搜索引擎之稱。它的主要精力放在提高搜索速度、智能化處理搜索結果、個性搜索功能的設置和用戶檢索界面的友好性上,查全率和查準率都比較高。1.3本文主要工作本文在深入分析通用搜索引擎基本原理、架構設計和核心技術的基礎上,結合開源搜索引擎lucene和天網搜索引擎的實現原理,設計并實現了一個可擴展,可復用的小型搜索引擎系統,本文的具體工作有以下幾個方面:1.詳細論述了系統結構,系統的設計原則以及目標。明確系統的功能,設計出詳細的系統流程圖。2.分析了網絡爬蟲的工作原理,利用數據庫設計出爬蟲部分的詳細流程圖,并實現了系統的爬蟲部分。3.詳細設計了系統的信息處理部分,并且給出了設計的流程圖,在中文切成部分參照lucene的原理,做出了算法上的改進,對改進后的算法實現,并進行了準確率和效率的測試,證明在效率上確實提高。4.根據排序和索引的原理,自己詳細設計了這個部分,完成了詳細流程圖,并實現。5.為了提高系統的搜索效率,采用了緩存搜索頁面和對搜索頻率較高詞語結果緩存的兩級緩存原則。1.4論文結構本文共分為七章第一章,緒論。主要闡述了論文的研究背景與意義、搜索引擎的發展現狀、發展趨勢、論文的主要工作和組織結構。第二章,系統結構。主要對整個系統進行的概念和功能進行了描述,并且對系統的各個部分進行了一個大概的介紹,并給出系統流程圖。第三章,爬蟲。對系統中的爬蟲部分的原理進行了詳細的說明,對爬蟲部分詳細設計了流程圖,并給出對爬蟲部分的代碼實現和對代碼進行一定程度的講解。第四章,信息處理。對信息處理部分的原理進行詳細的描述,詳細設計了流程圖,給出了信息處理部分各種切詞部分代碼實現,并且對代碼進行了一定程度了解說。第五者,排序索引。對系統的排序和索引兩個部分的原理進行詳細的描述,并對用來實現排序和索引的數據結構進行詳細的說明。給出流程圖。第六章,搜索。對系統的最后一個環節搜索進行了描述,給出實現搜索的消息步驟,并且對提高效率的兩級緩存策略給出了詳細的講解。給出流程圖。第七章,總結。對整個畢業設計的過程和項目進行了總結,并且分析了系統現有的不足,對不足之處給出了將進行改進的建議。第二章系統結構2.1概述搜索引擎[41](SearchEngines)就是指在WWW(WorldWideWeb)環境中能夠響應用戶提交的搜索請求,返回相應的查詢結果信息的技術和系統,是互聯網上的可以查詢網站或網頁信息的工具[2]。它包括信息搜集、信息整理和用戶查詢三部分。搜索引擎的服務方式分為兩種:目錄服務和關鍵字檢索服務。目錄服務是由分類專家將網絡信息按照主題分成若干個大類,用戶可以根據分類清晰地找到自己所需要的內容。關鍵字檢索服務可以查找包含一個或多個特定關鍵字或詞組的WWW站點。搜索引擎是互聯網的第二大核心技術,涉及到信息檢索、人工智能、計算機網絡、分布式處理、數據庫、數據挖掘、數字圖書館、自然語言處理等多領域的理論和技術,所以具有綜合性和挑戰性。2.2系統結構搜索引擎系統結構[1]分為爬蟲,信息處理,排序索引,搜索四個部分,系統結構圖如圖2-1所示;圖2-1系統流程圖2.2.1爬蟲爬蟲也可以稱作“網絡爬蟲程序”,“web爬蟲”,“網絡蜘蛛”,“網絡機器人”。網絡爬蟲是一個自動提取網頁的程序,它為搜索引擎從萬維網上下載網頁,是搜索引擎的重要組成。傳統爬蟲從一個或若干初始網頁的URL開始,獲得初始網頁上的URL,在抓取網頁的過程中,不斷從當前頁面上抽取新的URL放入隊列,直到滿足系統的一定停止條件。2.2.2信息處理信息處理指的是當爬蟲從萬維網上下載了網頁,對網頁中包含的信息進行處理,其中包括提取網頁中包含的url。為爬蟲的繼續提供所需要的url,這個事很重要的,因為沒有新的url出現的話,爬蟲程序就會停止,這樣就無法獲得全面的信息。信息處理還必須得網頁顯示的內容進行分析處理,把網頁的內容切成詞語。為下面的排序和索引部分提供相應的信息。2.2.3排序和索引在信息處理完成之后,每個網頁都會被切成很多個關鍵詞,同時每個詞語都會有很過個相關的網頁。排序所要做的事就是把每個詞語的相關的網頁按詞語的出現次數進行排序,這樣在進行搜索時結果的出現順序提供依據。接下來的索引程序就是以詞庫為索引關鍵字建立索引,這樣在搜索的時候就能夠在最短的時間找出我們想要的結果。2.2.4搜索在上述的工作完成之后,便可以為用戶提供搜索服務了,按照用戶的關鍵字或詞的輸入,按照所建立的索引在最短的時間內找到相應的結果,返回相應的數據,然后在網頁上顯示返回的結果,是用戶能夠選擇自己想要的信息。2.3搜索引擎主要指標及分析搜索引擎的主要指標有響應時間、召回率、準確率、相關度等。這些指標決定了搜索引擎的技術指標。搜索引擎的技術指標決定了搜索引擎的評價指標。好的搜索引擎應該是具有較快的反應速度和高召回率、準確率的,當然這些都需要搜索引擎技術指標來保障。畢業設計論文代做平臺《580畢業設計網》是專業代做團隊也有大量畢業設計成品提供參考QQ3449649974召回率:一次搜索結果中符合用戶要求的數目與用戶查詢相關信息的總數之比準確率:一次搜索結果中符合用戶要求的數目與該次搜索結果總數之比相關度:用戶查詢與搜索結果之間相似度的一種度量精確度:對搜索結果的排序分級能力和對垃圾網頁的抗干擾能力2.4開發語言本文在開發語言上選擇的是c#語言[5],因為C#在帶來對應用程序的快速開發能力的同時,并沒有犧牲C與C++程序員所關心的各種特性。它忠實地繼承了C和C++的優點。C#語言還有以下的優點:[15]1.簡潔的語法。語法中的冗余是C++中的常見的問題,比如"const"和"#define"、各種各樣的字符類型等等。C#對此進行了簡化,只保留了常見的形式,而別的冗余形式從它的語法結構中被清除了出去。2.精心設計面向對象在C#的類型系統中,每種類型都可以看作一個對象。C#提供了一個叫做裝箱(boxing)與拆箱(unboxing)的機制來完成這種操作,而不給使用者帶來麻煩,這在以后的章節中將進行更為詳細的介紹。C#只允許單繼承,即一個類不會有多個基類,從而避免了類型定義的混亂。在后面的學習中你很快會發現,C#中沒有了全局函數,沒有了全局變量,也沒有了全局常數。一切的一切,都必須封裝在一個類之中。你的代碼將具有更好的可讀性,并且減少了發生命名沖突的可能。3.完整的安全性與錯誤處理語言的安全性與錯誤處理能力,是衡量一種語言是否優秀的重要依據。。C#的先進設計思想可以消除軟件開發中的許多常見錯誤,并提供了包括類型安全在內的完整的安全性能。.NET運行庫提供了代碼訪問安全特性,它允許管理員和用戶根據代碼的ID來配置安全等級。變量是類型安全的。4.靈活性與兼容性在簡化語法的同時,C#并沒有失去靈活性。正是由于其靈活性,C#允許與C風格的需要傳遞指針型參數的API進行交互操作,DLL的任何入口點都可以在程序中進行訪問。C#遵守.NET公用語言規范(CommonLanguageSpecification,CLS),從而保證了C#組件與其它語言組件間的互操作性。元數據(Metadata)概念的引入既保證了兼容性,又實現了類型安全。2.5小結本章對基于因特網的搜索引擎結構和性能指標進行了分析,在這些原來的理解基礎之上利用c#技術完成了一個小的web搜索引擎,在接下來的章節將對搜索引擎結構中的網絡爬蟲設計進行說明,并給出關鍵部分的實現代碼。第三章爬蟲3.1概述網絡蜘蛛即WebSpider,是一個很形象的名字[3]。把互聯網比喻成一個蜘蛛網,那么Spider就是在網上爬來爬去的蜘蛛。網絡蜘蛛是通過網頁的鏈接地址來尋找網頁,從網站某一個頁面(通常是首頁)開始,讀取網頁的,找到在網頁中的其它鏈接地址,然后通過這些鏈接地址尋找下一個網頁,這樣一直循環下去,直到把這個網站所有的網頁都抓取完為止。如果把整個互聯網當成一個網站,那么網絡蜘蛛就可以用這個原理把互聯網上所有的網頁都抓取下來。對于搜索引擎來說,要抓取互聯網上所有的網頁幾乎是不可能的[6],從公布的數據來看,容量最大的搜索引擎也不過是抓取了整個網頁數量的百分之四十左右。這其中的原因一方面是抓取技術的瓶頸,無法遍歷所有的網頁,有許多網頁無法從其它網頁的鏈接中找到;另一個原因是存儲技術和處理技術的,如果按照每個頁面的平均大小為20K(包含圖片),100億網頁的容量是100×2000G字節,即使能夠存儲,下載也存在問題(按照一臺機器每秒下載20K計算,需要340臺機器不停的下載一年時間,才能把所有網頁下載完畢)。同時,由于數據量太大,在提供搜索時也會有效率方面的。因此,許多搜索引擎的網絡蜘蛛只是抓取那些重要的網頁,而在抓取的時候評價重要性主要的依據是某個網頁的鏈接深度。3.2爬蟲結構分析爬蟲部分分為爬蟲初始化,從網頁中提取url,對url進行存儲,從數據中提取url四個部分,爬蟲部分的流程圖如圖3-1所示,在本節將對爬蟲的工作原理進行詳細的描述:圖3-1爬蟲流程圖3.2.1爬蟲初始化爬蟲程序的開始是需要一個最初始的url,爬蟲將先下載這個url的內容,然后提取里面所包含的url,所以這個最初始的url是很重要的,如果沒有一個好的初始的url,這個url所包含的url會很少,那么爬蟲所能爬下的網頁的數量也將大受影響。得到了初始的url以后,就可以下載網頁的內容了。以下就是下載網頁的代碼:HttpWebRequestloHttp=(HttpWebRequest)WebRequest.Create(url);//創建連接loHttp.Timeout=500;//設置超時HttpWebResponseloWebResponse=(HttpWebResponse)loHttp.GetResponse();//獲取響應StreamReaderloResponseStream=newStreamReader(loWebResponse.GetResponseStream(),System.Text.Encoding.Default);//獲取返回的流html=loResponseStream.ReadToEnd();//讀取流loWebResponse.Close();//關閉連接有關于httpwebrequest類說明如下:[12].NETFramework使用HttpWebRequest和HttpWebResponse類來提供對HTTP協議的全面支持,而HTTP協議構成了所有Internet通信量中的絕大部分。每當靜態方法WebRequest.Create遇到以“http”或“https”開頭的URI時,在默認情況下將返回這些從WebRequest和WebResponse派生的類。在大多數情況下,WebRequest和WebResponse類提供生成請求所需的一切,但如果需要訪問作為屬性公開的HTTP特定功能,則可以將這些類的類型轉換為HttpWebRequest或HttpWebResponse。HttpWebRequest和HttpWebResponse封裝“標準HTTP請求和響應”事務,并提供對通用HTTP頭的訪問。這些類還支持大部分的HTTP1.1功能,其中包括管線、塊區、身份驗證、預身份驗證、加密、代理支持、服務器證書驗證以及連接管理。自定義頭和不是通過屬性提供的頭可存儲在Headers屬性中并可通過此屬性訪問。HttpWebRequest是WebRequest使用的默認類,不需要注冊它就可以將URI傳遞給WebRequest.Create方法。可以通過將AllowAutoRedirect屬性設置為true(默認值),使應用程序自動遵循HTTP重定向。應用程序將重定向請求,而HttpWebResponse的ResponseURI屬性則將包含響應請求的實際Web資源。如果將AllowAutoRedirect設置為false,則應用程序必須能夠將重定向作為HTTP協議錯誤處理。應用程序通過捕捉Status設置為WebExceptionStatus.ProtocolError的WebException來接收HTTP協議錯誤。Response屬性包含由服務器發送的WebResponse,并指示遇到的實際HTTP錯誤。3.2.2從網頁中提取url當把網頁的代碼下載完畢后,就需要對代碼進行一次遍歷,找出并提取其中的url,為爬蟲的繼續提供url,對代碼中的url的提取采用的是正則表達式的方法,比較代碼中所以匹配url正則表達式的部分,然后遍歷這個集合,逐條的讀取其中的url。以下為代碼:stringstrRegex=@"http://([\w-]+\.)+[\w-]+(/[\w-./?%&=]*)?";//url的正則表達式

Regexr=newRegex(strRegex,RegexOptions.IgnoreCase);//初始化一個regex對象,為比較作準備

MatchCollectionm=r.Matches(htmlCode);//比較并得出代碼中匹配的集合for(inti=0;i<=m.Count-1;i++)//遍歷集合,得出其中的url

{

boolrep=false;

stringstrNew=m[i].ToString();}3.2.3URL存儲在上面的部分得到了代碼中的url,接著用數據庫對得到url進行存取,在數據庫中創建兩個表,一個存儲已經下載過的url,一個存儲還沒有下載過的url,在網頁中得到的url,進行如下幾步處理:1.首先在已經下載過的url表中進行搜索,如果找到了,說明這個url的內容已經被下載過了,再次下載不僅浪費了網絡資源,更加浪費服務器的資源,所以對這樣的url丟棄。2.如果在下載過的url表中沒找到相同的url,說明程序沒有下載過這個url中內容,需要對其進行下載。于是在沒有下載過的url表中搜索,如果搜索到相同的url,說明這個url已經存在了,再次添加只會讓服務器對其進行重復的下載,浪費了資源,不需要在添加,丟棄。3.如果在沒有下載過的url表中找不到相同的url,說明這個url還沒有被添加過。則將這個url添加到沒有下載過的url表中。3.2.4從數據庫中提取url這個時候數據庫中已經存在了很多的沒有下載的url,而其數量在增加中,我們就可以開啟多線程程序,每個程序獨自的從沒有下載過的url表中提取一個url進行下載,解析,存儲。在下載完畢后將這個url從沒下載過的url表中刪除,并且在下載過的url表中添加。這個時候需要注意的幾個問題:1.那就是不能讓多個線程同時從一個服務器上進行下載,比如多個線程同時從這樣的大型服務器上進行下載,這樣服務器有可能認為受到了攻擊,會將服務器的ip列入黑名單中,這樣的話服務器以后都無法下載里的內容。2.超時問題,應該為每個下載設置一個等待的上限。在等待的時間超過了這個上限后,仍然無法完成下載的話,程序就有理由認為對這個url的下載時失敗的。失敗的原因很多,暫且不追尋它的原因是什么。程序就應該及時的停止下載,以免造成線程的浪費。3.3小結在本章中,首先介紹了爬蟲的基本概念,然后給出了爬蟲的結構圖,并逐一的對爬蟲中的每個程序模塊進行了詳細的講解。并且給出了關鍵部分的代碼實現。爬蟲是搜索引擎系統的開始部分,盡管實現起來沒有太大的難度,但是它是整個程序的開始,是整個程序的基石,以后的部分都是在它的基礎上形成的,所以要考慮完全。下面一章便開始對信息處理部分的設計進行詳細的描述,并且給出關鍵部分的代碼實現。第四章信息處理4.1概述圖4-1信息處理流程圖經過上面的處理程序已經成功的獲得了網頁代碼,但是程序需要的只是網頁中包含的信息的詞語,只有得到這些詞語,才能夠對詞語相關的網頁進行排序和完成索引,在這本章就將對網頁進行一系列的處理,以盡可能快的速度得到這些詞語。這些處理過程包含:轉換,切詞。信息處理的流程圖如圖4-1所示:4.2轉換圖4-2內容轉換流程圖根據上述所知程序要得到是組成一個網頁的詞語,程序現在擁有的是網頁的代碼,當然代碼中肯定包含了網頁中所有的文字信息[25],但是不要忘記,代碼同時也包含了許多的html標簽。這些標簽不僅僅只是html的標準標簽,同時還有用戶自定義的標簽,對這些標簽的處理我試過了如下的幾種方法:去掉標簽本身,但是對標簽中間包含的內容還是進行正常的處理,例如:<title>thisismyfirstwebpage!</title>程序在處理的時候會自動的去掉<title>和</title>兩個部分,然后對thisismyfirstwebpage!這個部分進行正常的處理,這中處理的方式會很好的切到網頁中所包含的文字信息,但是它有這樣幾個問題:首先,這樣的方式程序會對html中的每個標簽都進行如上的處理,一個html有時候標簽所占得字符是遠遠的多于它所包含的文字信息。這樣的話程序的效率會因為處理很多無用的標簽而浪費支援,減低了效率。面對像<style>………</style>這樣標簽,它中間的內容是無用的,它只是對網頁的顯示效果有用,但是上面的程序還是會對它中間的內容進行我們的切詞程序,這樣不僅大大的減低了程序的效率,還切刀了許多根本于網頁的內容無關的詞語,這樣就會降低搜索引擎的準確性。面對像<script>………</script>這樣的標簽,必須對它進行解析,才知道它運行后會得到什么結果,暫且不管能不能實現對它的解析,即使能夠寫出這樣的程序,但是不得不花大量的時間去想這個程序,而其最后這個程序也得花大量的資源堆網頁的<script>………</script>進行解析,所以這個問題否定了上面的方法的可行性。面對<style>和<script>這兩個標簽,采用的方法是過濾掉標簽中間包含的內容,對其他標簽,處理的方式與方法1是一樣的。這個方法似乎解決了方法1中的b,c兩個問題,但是真的是這樣嗎,我來分析一下這個方面的缺點:首先,跟方法1一樣,這樣的方式程序會對html中的每個標簽都進行如上的處理,我們知道。一個html有時候標簽所占得字符是遠遠的多于它所包含的文字信息。這樣的話程序的效率會因為處理很多無用的標簽而浪費支援,減低了效率。過濾了<script>標簽中間包含的內容,會丟失一定得信息,因為網頁的有些內容必須是在運行了<script>腳本之后得到的,這樣的話搜索引擎的準確率會因此降低。上面的兩個方法都有效率的問題,而且各自也有著其他的問題。經過了幾天的思考,找到了一個相對來說比較好的方法,這個方法如下:首先程序會使用到一個控件,它叫webbrowser,這個控件的功能是根據所給的html的代碼,它可以將網頁顯示出來,跟使用的IE的效果是一樣的,這樣的話,似乎程序將爬蟲下載好的代碼放到webbrowser中,在獲得控件document.body.innertext屬性就可以了,但是這其中還有一個問題:那就是控件的加載的時間問題,經過測試,我發現控件的加載時間是整個程序執行完了之后,也就是說即使在程序的開始處你把html代碼賦值到控件,然后在下面的程序中想使用document.body.innertext來獲得網頁內容,這個時候程序會報nullReferenceException錯誤,因為在這個時候控件還沒有加載,所以控件的內容還是空的。怎么解決個問題呢,本文使用了多進程使用另外一個程序來執行webbrowser控件的加載,這樣當這個程序執行完成之后加載了控件,可以在documentCompleted方法中得到document.body.innertext,然后程序進程間通信將轉換了的內容傳回原來的程序,進程間通信程序采用的消息隊列[13],關鍵代碼如下所示:轉換代碼:webBrowser1.DocumentText=htmlCode;//把html代碼賦值給控件webBrowser1.Select();//選中控件webBrowser1.DocumentCompleted+=newWebBrowserDocumentCompletedEventHandler(webBrowser1_DocumentCompleted);//將方法webBrowser1_DocumentCompleted加到控件的事件中}///<summary>///當控件加載完成時調用的方法///</summary>///<paramname="sender"></param>///<paramname="e"></param>publicvoidwebBrowser1_DocumentCompleted(objectsender,WebBrowserDocumentCompletedEventArgse){htmlTex=webBrowser1.Document.Body.InnerText();}進程間通信的代碼:internalclassTransmit{MessageQueuecodeQueue=null;//申明一個消息隊列stringcodeQueueName=@".\Private$\webSearchCode";//消息隊列的名字publicTransmit()//初始化,對消息隊列進行初始化{if(MessageQueue.Exists(codeQueueName))//如果消息隊列存在,獲得它{codeQueue=newMessageQueue(codeQueueName);}Else//如果消息隊列不存在,創建一個消息隊列{codeQueue=MessageQueue.Create(codeQueueName);}}publicvoidsend(refstringhtmlText,stringurl){codeQueue.Send(htmlText,url);//向消息隊列中發送一個消息}}4.3切詞經過了上述的程序的轉換過后,現在程序已經得到了網頁顯示的內容,就像我們在IE中對網頁進行全選,然后在復制,在記事本中粘貼出來的結果是一樣的,接下來就需要對這些內容進行切詞,網頁的詞語我們可以劃分為以下幾個部分,中文,英文,數字,其他的符號,對于不同的詞語程序應該采用不同的處理方式,所以需要對當前詞語做一個判斷,然后分類進行處理,對詞語類型的判斷可以采用正則表達式來進行,代碼如下:privateintjudge(stringstr){Regexrehanzi=newRegex("^[\u4e00-\u9fa5]{0,}$");//初始化中文的正則表達式Regexreshuzi=newRegex("^[0-9]*$");//初始化數字的正則表達式Regexreenglish=newRegex("^[A-Za-z]+$");//初始化英文的正則表達式if(str=="\n"||str=="\t"||str=="\r"){return3;}if(rehanzi.Match(str).Success){return0;//說明是漢字}elseif(reenglish.Match(str).Success){return1;//說明是字母}elseif(reshuzi.Match(str).Success){return2;//說明是數字}else{return3;//說明是其他的一些符號}return-1;}經過上述的判斷,我們就可以對不同的詞語采取不同的處理方式。4.3.1中文切詞圖4-3中文切詞流程圖中文切詞[19],就是要程序把中文的語句切成一個一個的詞語,這個工作是相當復雜的,本文把它分成了初始化詞庫,詞語定位,切詞比較三個部分,下面我將對每個部分進行詳細的講解和給出關鍵的代碼:a)初始化詞庫:要進行中文切詞,就需要一個中文的詞庫,沒有這個詞庫程序是無法完成的。本文用的詞庫是從網上下載的一個詞庫,不是很大,2M左右,詞庫下載完了,那么怎么用這個詞庫變成了一個很大的問題,查看了lucence(一個使用java語言完成的搜索引擎)的代碼,發現它是將整個詞庫導入到一個哈希表里面,然后把切下的詞到這個哈希表中查找,找到了就說明當前詞語是一個中文的詞。但是這樣的效率是很低下的,因為一個詞庫大概要有二十萬到三十萬個詞語,把它導入一個哈希表,這個哈希表太大了,它的查找效率應該是很低的,還有在切詞過程中,查找的次數是巨大了,如果每次查找哪怕多用很少的時間,對于整片文章來說,完成整個的切詞工作耗費的時間也是很多的。因此,本文對詞庫進行了如下的改進,因為每個詞語無論它的長度怎么變,它的首字是不會變的,這樣針對一個詞語,應該可以把查找的范圍縮小,只要查找的范圍縮小了,查找的效率也就能夠提高了。于是,本文把詞庫按照詞語的首字的拼音的前兩個字母進行了一個劃分,把原來的一個詞庫分成了93個,然后把詞庫導入到一個哈希表數組中,這樣每個詞庫的平均大小只有20k左右,大大的減小了,每個哈希表中所包含的詞語的數量也大大的減小了,針對一個詞語,它的查找始終是定位在一個哈希表的,是不會改變的,所以沒個詞語,經過一次定位以后,就可以在一個很小的范圍內進行查找。詞庫初始化的工作還沒有結束,還有一個很重要的事,那就是最大長度匹配,我們對一條語句進行切詞,應該要保證切下來的詞語是最少的,也就是沒個詞語都要盡量的長,例如:“中華人民共和國”,可以切成如下幾個詞語:“中華”,“中華人民”,“中華人民共和國”但是最終選擇的結果應該是最長的那個結果。這個就相當的困難了,因為切詞,詞語是一個字一個字加上去的,在以上面的例子為例,程序首先切下了“中華”兩個字,組成一個詞,然后在哈希表中進行查找,找到了,說明它是一個詞語,我們在切下“人”字加到詞語中,得到了“中華人”,這個詞語在詞庫中是沒有的,但是當在切下“民”加到詞語中時,組成了“中華人民”。怎么樣才能讓程序切到“人”字的時候不停止,而是繼續往下切詞呢?解決得辦法就是程序在構造一個詞庫,原來的詞庫是一行存一個詞,現在改變一下,把詞語全部連起來,每個詞語中間加上一個“,”,這樣就可以區分詞語了,然后把新構造的詞庫讀到一個string數組中,這樣就可以使用string類型特有的contains方法來判斷詞庫當中是不是包含了這個詞,還是上面的例子:在string中會有這樣一段“,中華人民共和國,”,當切詞切到“中華人”的時候,調用string的contains方法,返回的true,切詞程序就會繼續往下走了,通過這樣就能夠實現最大長度匹配了。關鍵代碼如下:publicstaticHashtablemenuList=newHashtable();//存放用于查找詞語屬于的列表publicstaticstring[]dicText=newstring[93];//存放不以行分的詞庫的字符串publicstaticvoidsetWordHT(){stringpath="";stringcopyPath="";stringwordText="";FileStreamfCreate;FileStreamwordFS;StreamReaderwordSR;FileStreamfileOpen;StreamWriterfileWriter;boolneedWrite=false;for(inti=0;i<93;i++)//初始化哈希表詞庫{wordHT[i]=newList<string>();wordText="";path="word\\"+menuList[i].ToString()+".txt";copyPath="word\\"+menuList[i].ToString()+"Copy.txt";if(!File.Exists(copyPath)){fCreate=File.Create(copyPath);fCreate.Close();needWrite=true;}wordFS=newFileStream(path,FileMode.Open,FileAccess.Read);wordSR=newStreamReader(wordFS,System.Text.Encoding.Default);stringword=null;while((word=wordSR.ReadLine())!=null)//構造新的詞庫{wordHT[i].Add(word.Trim());stringtest=word.Trim().ToString();wordText+=word.Trim()+",";}fileOpen=newFileStream(copyPath,FileMode.Open,FileAccess.ReadWrite);fileWriter=newStreamWriter(fileOpen,System.Text.Encoding.Default);if(needWrite)//將新詞庫寫到記事本中{fileWriter.Write(wordText);}fileOpen.Close();wordFS.Close();}}publicstaticvoidsetCopyDic(){FileStreamdicCopyStream;BinaryReaderdicCopyBR;stringdicCopyPath="";for(inti=0;i<93;i++)//完成對string數組的初始化工作{dicCopyPath="word\\"+menuList[i].ToString()+"Copy.txt";dicCopyStream=newFileStream(dicCopyPath,FileMode.Open,FileAccess.Read);dicCopyBR=newBinaryReader(dicCopyStream,System.Text.Encoding.Default);byte[]content=newbyte[dicCopyStream.Length];dicCopyBR.Read(content,0,(int)dicCopyStream.Length);dicText[i]=System.Text.Encoding.Default.GetString(content,0,content.Length);dicCopyStream.Close();}}//結束setCopyDicb)詞語定位:詞庫初始化完成之后,便開始切詞程序,得到中衛詞語的首字,就需要完成一個工作,因為詞庫是有93詞庫組成的,而這些詞庫是靠拼音的前兩個字母來定位的,所以詞語要準確的定位了一個相應的包含有它的詞庫,就需要把詞語的首字轉換成拼音,把中文轉換為拼音的類是在網上尋找的別人已經寫好了的,但是其中有其中有幾個特殊的拼音需要程序來定位。這些拼音是:“jv”,“lv”,“nv”,“xv”,“yv”。然后提取其拼音的前兩個字母,完成定位工作,還是以上面的例子為例:“中華人民共和國”,因為首字是“中”字,中的拼音是“zhong”,前兩個字母是“zh”,就可以準確的定位到包含“zh”的所有詞語的哈希表了。同時也完成了對剛剛初始化的string數組的定位工作,準確的定位到了包含“zh”的所有詞語的string,因為這個部分相對來說還是比較簡單的,代碼的實現就不給出了。c)切詞比較:這個事中文切詞部分最困難的部分了,下面將詳細的講解切詞比較的詳細步驟和給出實現的代碼,先切下語句開始的兩個字,組成一個詞語,然后按詞語定位得到的哈希表序號到相應的哈希表中進行查找,如果找到了,說明這個詞語是存在的,可以把它當作一個備選詞語,然后我們在切下一個字加到當前的詞語中,在到哈希表中進行查找,如果找不到,說明沒有這個詞語,但是程序不能在這個時候結束,因為必須實現最大長度匹配,這個時候是剛剛初始化的string數組發揮作用的時候了,使用剛剛定位的string的contains方法來判斷是否包含了當前詞語,這個時候會有兩種情況:1)如果包含了,說明當前的詞語可能一個更長的詞語的一部分,還是以“中華人民共和國”為例,“中華人”就是“中華人民共和國”的一部分,切詞程序就必須繼續切下一個字添加到當前詞中,然后在重復上述的哈希表的查找和string的contains方法。2)如果不包含,那么說明這個詞語不可能是一個更長的詞語的部分,對這個詞語的切詞工作可以結束了,例如:如果當前詞語是“中華的”,這個就不是“中華人民共和國”的一部分了,沒必要再切下去了。這個時候我們要做的工作就是把備選已經切好的詞語存放到我們存放詞語的鏈表中去。關鍵代碼如下:if((type=judge(oneWord))==0)//對當前字符的類型進行判斷,是漢字就到詞中,進行檢查{nowWords+=oneWord;if(findType==0)//判斷是用哈希表存詞的詞庫進行查詢還是用string存儲的詞庫進行查詢,表示先用哈希表存儲的詞庫進行查詢{if(Words.wordHT[theSequence].Contains(nowWords))//如果在哈希表中查詢到,說明存在這個詞語{if((standbyWord.Length)<(nowWords.Length))//如果當前查詢到的存在的詞語的長度大于已經存儲的詞語,則替換standbyWord=nowWords;findType=0;end++;}elseif(Words.dicText[theSequence].Contains(nowWords))//如果哈希表中沒有,但是string查詢到,則說明有可能存在包含當前文字的更長的詞語{findType=1;//改變查詢的方式end++;continue;}else//如果都查詢不到,那么說明當前的文字不可能組成任何一個詞語{storeNowWords(0,standbyWord,theSequence);nowWords="";standbyWord="";}}elseif(findType==1)//先用string存儲的詞庫進行查詢{if(Words.dicText[theSequence].Contains(nowWords))//如果string存儲的詞庫中包含了nowwords,說明有可能是個詞語或者是一個更長詞語的一部分{if(Words.wordHT[theSequence].Contains(nowWords))//如果哈希表存儲的詞庫中包含了nowwords,說明它是一個詞語{if((standbyWord.Length)<(nowWords.Length))//檢查當前詞語的長度是否大于已經存儲詞語的長度,大于就替換standbyWord=nowWords;findType=0;end++;}else//說明nowwords還不能構成一個詞語{end++;}}else//string存儲的詞庫中不包含nowwords,說明它不可能成詞{storeNowWords(0,standbyWord,theSequence);nowWords="";standbyWord="";}}}else//表示當前的字符不是漢字{storeNowWords(0,standbyWord,theSequence);nowWords="";standbyWord="";goToNextOne=false;}4.3.2中文切詞測試在完成了對中文切詞的程序的編寫之后,本文對中文切詞程序進行了測試工作。在準確性和效率方面對中文切詞進行了測試。對中文切詞的準確率測試流程如下:1.任意選取一段文本。Stringtest=“重慶大坪中學女子足球隊在土耳其砍瓜切菜戰勝世界諸強勇奪冠軍一事,經重慶的同行起底,經傅亞雨詳細追蹤詳細報道,三天后國人都知道了,這,其實是中國女子少年隊冒名頂替去打別人純粹的學生軍。感謝同行們有勇氣揭露部分真相,但重慶體育局方面聲明“此事和體育局足協無關,這只是重慶大坪中學個體行為”,這是在說謊,如無體育局和足協的配合,要調動整編制的中國少年女子足球隊出國打比賽,基本上連出國手續都辦不全,這就像調動了一個整編制軍隊去國外打擊海盜,中國軍方卻不知情,卻推說這是漁民們的個體行為”2.經

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論