◆ 南京工程學(xué)院仿真部 施建強(qiáng)(shiyu789@163.com)
網(wǎng)絡(luò)搜索的原理
搜索軟件是通過向搜索站點(diǎn)發(fā)出特殊搜索字串命令(各個(gè)站點(diǎn)的格式不一樣),然后對結(jié)果進(jìn)行處理后顯示出來,但如何發(fā)出搜索字符串、發(fā)出怎樣的字符串還需要對HTML有一定的認(rèn)識。我們知道對于網(wǎng)上信息的發(fā)送是通過表單的形式來進(jìn)行的,也就是說當(dāng)我們在網(wǎng)上點(diǎn)擊某些表單時(shí),通過表單中包含的默認(rèn)地址中的表單處理程序來接受所有包含在表單中的信息,這些信息有的是顯示的,而另外一些卻是隱藏的。您可以試著將一個(gè)包含有表單的網(wǎng)頁用Frontpage或者Dreamwaver打開,這時(shí)您就會發(fā)現(xiàn)有很多在瀏覽器里看不到的東西,這些隱藏的標(biāo)志在您發(fā)送表單時(shí)起著重要的作用。沒有這些標(biāo)志,發(fā)出的字符串很可能得不到服務(wù)器的應(yīng)答。
知道了這些,再來看程序所需發(fā)送的字符串,舉個(gè)例子來說:雅虎中文的搜索代碼是 http://cn.search.yahoo.com/search/gb?p=***,其中***代表的是所要搜索的字符串,而剩余的部分是處理字符串的服務(wù)器程序的地址。另外一個(gè)我們很常用的搜索引擎Yeah,它的搜索代碼相對復(fù)雜一些,是“http:
//www2.yeah.net/cgi-bin/query2.exe?query=***&start=0&REXP=AND” ,但基本的東西沒有變,它們都是使用了這樣一種形式:http://目標(biāo)URL?參數(shù)1名=參數(shù)1值&參數(shù)2名=參數(shù)2值&參數(shù)3名=參數(shù)3值……
對于HTTP協(xié)議,有幾種傳送數(shù)據(jù)的方法,其中比較常用的有GET和POST方法,對于使用GET方法進(jìn)行傳送數(shù)據(jù)的網(wǎng)站來說,使用上面的形式能夠通過一條查詢語句返回所需要查詢的內(nèi)容網(wǎng)頁,但對于使用 POST方法的網(wǎng)站,有可能返回不了查詢結(jié)果網(wǎng)頁,不過從筆者的經(jīng)驗(yàn)看,一般來說是能夠成功的。
實(shí)現(xiàn)方法
下面剖析現(xiàn)在流行的搜索軟件程序,并介紹使用VB制作自己的搜索軟件的方法。
啟動(dòng)VB 6.0,首先創(chuàng)建一個(gè)窗體,然后要對運(yùn)行環(huán)境進(jìn)行一下設(shè)置:具體來說,就是添加上必要的控件,一般情況下,如果您安裝了IE 4.0以上的瀏覽器,可通過點(diǎn)擊VB菜單中“工程->部件”,在彈出的部件對話框中找到有一欄寫著“Microsoft Internet Controls”的選項(xiàng)。利用它我們可以初始化一個(gè)瀏覽器的實(shí)例。當(dāng)您選中這個(gè)選項(xiàng)后,會發(fā)現(xiàn)工具欄中多了一個(gè)形狀如同地球的按鈕,這就是剛才選中的瀏覽器控件,雙擊這個(gè)圖標(biāo)按鈕在窗體上生成一個(gè)WebBrowser1的部件,接下來就使用這個(gè)部件來顯示查詢的結(jié)果。然后在窗體上放上一個(gè)文本框和一個(gè)按鈕,其實(shí)就這幾個(gè)部件已經(jīng)可以構(gòu)成一個(gè)最小的搜索程序基本結(jié)構(gòu)了。
程序的編制
假若窗體上有一個(gè)文本框Text1、一個(gè)標(biāo)簽Label1、一個(gè)瀏覽器WebBrowser1、一個(gè)按鈕Command1,其中文本框用于輸入關(guān)鍵詞,瀏覽器用于顯示查詢結(jié)果網(wǎng)頁,按鈕用于發(fā)出請求語句,點(diǎn)擊Command1的程序代碼可以這樣寫:
Private Sub Command1_Click()
Dim url As String
On Error Resume Next ’出錯(cuò)后繼續(xù)
If Text1.Text = “” Then
MsgBox “請先輸入關(guān)鍵字”
EndIf ’防止不輸入關(guān)鍵詞
url = “http://search.chinese.yahoo
.com/search/gb?p=” + Text1.Text
’將關(guān)鍵詞放入查詢語句中
Webbrowser1.Navigate url
’調(diào)用瀏覽器顯示查詢結(jié)果
End Sub
雅虎的查詢語句比較簡單,而對于比較復(fù)雜網(wǎng)站的查詢語句一定要注意的是各個(gè)關(guān)鍵參數(shù)之間一定要用“&”來隔開。雖然您只是學(xué)會了這一招,但已經(jīng)足夠利用網(wǎng)上的資源來編寫您的第一個(gè)程序了,因?yàn)榫W(wǎng)上所有類型的表單都能表示了,無論是查詢股票、軟件、書籍等都不外乎這種模式。只要您將查詢網(wǎng)頁調(diào)入 Frontpage、Dreamwaver等所見即所得的網(wǎng)頁編輯軟件中,這些網(wǎng)頁的源碼便會展現(xiàn)在您的面前,利用這些鏈接,再加上一個(gè)好的界面,就可以制作自己的搜索工具軟件了,不過要注意的是,有些表單的傳送路徑是相對路徑,這時(shí)要加上網(wǎng)站的地址鏈接。
程序的改進(jìn)
上面的方法比起直接訪問搜索站點(diǎn)的確能節(jié)省不少上網(wǎng)的時(shí)間,但并沒有將程序的優(yōu)勢全部發(fā)揮出來,我們現(xiàn)在繼續(xù)介紹另外一種檢索網(wǎng)頁的方法:
首先介紹一個(gè)控件Microsoft Internet Transfer(這個(gè)控件在安裝VB或者某些應(yīng)用程序的時(shí)候會自動(dòng)安裝),這個(gè)控件允許建立與其他計(jì)算機(jī)的連接,并傳送文件。它使兩個(gè)Internet協(xié)議HTTP和FTP的使用變得容易。當(dāng)正常訪問一個(gè)網(wǎng)頁時(shí),Internet Transfer用GET命令訪問網(wǎng)絡(luò)瀏覽器的一個(gè)文件。例如,如果打開了URL: http://www.computerworld.com
.cn/,瀏覽器將建立與地址是www.computerworld
.com的機(jī)器的連接,并傳送GET命令。HTML 將通過連接以普通文本的方式返回,因?yàn)榉祷氐膬?nèi)容只是所要的網(wǎng)頁的源文件,節(jié)省了很多用于傳送、顯示網(wǎng)頁中圖像的時(shí)間,速度要快了許多,而且最重要的是我們可以很方便地使用自己的邏輯對返回的源文件進(jìn)行正確地分析和格式化,重新整理網(wǎng)頁的查詢結(jié)果。
還用剛才的窗體,只是要在菜單中選擇“工程->部件”,在彈出的對話框中找到一項(xiàng)“ Microsoft Internet Transfer Control”,選中后,在工具欄中您就會發(fā)現(xiàn)增添了一個(gè)顯示有地球和計(jì)算機(jī)的小按鈕,雙擊這個(gè)按鈕會在窗體上加入一個(gè) Internet Transfer實(shí)例Inet1,完成了這些步驟后,現(xiàn)在準(zhǔn)備在實(shí)例工程中加入代碼。
Internet Transfer控件有一個(gè)事件StateChanged。這個(gè)事件的目的是當(dāng)不同的操作發(fā)生時(shí)通知用戶程序。例如:控件在與網(wǎng)絡(luò)服務(wù)器連接時(shí)是一種狀態(tài),檢索HTML是另一種狀態(tài)。當(dāng)前的狀態(tài)用事件過程的State 參數(shù)來表示。在示例程序的StateChanged事件中輸入如下代碼:
Private Sub Inet1_StateChanged(ByVal State As Integer)
Select Case State
Case 12 ’表明網(wǎng)絡(luò)連接檢索正常
stemp=Inet1.GetChunk(1024)
’使用GetChunk方法從緩沖區(qū)中一次提取1024個(gè)字節(jié)的文本,并存放在stemp臨時(shí)變量中
While stemp<>“”
’當(dāng)仍然返回信息時(shí)
LastResult=LastResult+stemp
’將整個(gè)網(wǎng)頁的源文件代碼放入LastResult變量中
stemp=Inet1.GetChunk(1024) ’循環(huán)
Wend
Case 11
MsgBox “未返回搜索結(jié)果”
End Select
End Sub
盡管StateChanged事件包含了這個(gè)示例程序代碼的主要部分,我們?nèi)匀恍枰贑ommand1的Click事件中加入代碼,以初始化這個(gè)請求。下面就是這段代碼:
Private Sub Command1_Click()
url =“http://search.chinese.yahoo
.com/search/gb?p=” +Text1.Text
Inet1.protocol=icHTTP
’指明控件協(xié)議類型
Inet1.Execute CStr(url),“GET /”
’發(fā)出請求
While Inet1.StillExecuting
DoEvents
Wend
End Sub
進(jìn)一步優(yōu)化
前面已經(jīng)提到,用這種方法返回的信息包含了搜索的結(jié)果網(wǎng)頁,同直接搜索的區(qū)別就是由于這樣返回的是源代碼,暫時(shí)存儲到一個(gè)臨時(shí)變量中,這樣一來,您可以將返回的信息直接存儲到一個(gè)文件中。還有另一種方法,這就是我們下面要提到的對代碼的優(yōu)化處理。
什么叫對代碼的優(yōu)化處理呢?因?yàn)榉祷氐慕Y(jié)果中包含許多其他沒有什么用處的修飾,比如表格、“banner”等等信息,而這些信息并不是我們需要的,去掉這些信息,只保留對我們來說有用的結(jié)果,這就是優(yōu)化。那么怎樣優(yōu)化呢?分析HTML語法您就會看到,許多信息都是包含在一些關(guān)鍵詞之間。舉個(gè)例子:對于插入的圖片來說,都是用“”來結(jié)尾,這樣就清楚了,只要把代碼中所有的滿足以上條件的語句刪掉,這樣代碼中就不會出現(xiàn)圖片信息,代碼如下:
Public Function picFilter(downCode)
’定義一個(gè)過濾圖片信息的過程
Dim pStart As Long, pStop As Long
Dim pString1 As String, pString2 As String
pString1 = “ pString2 = “>”
’分別將兩個(gè)關(guān)鍵詞定義
pStart = InStr(downCode, pString1)
’找到第一個(gè)圖片信息的起始位置
If pStart <> 0 Then
’如果代碼中有圖片信息的話
pStop = InStr(pStart, downCode, pString2) + 1
’從上面找的起始部位開始找到第一個(gè)用于結(jié)束圖片信息的“>”
Do While pStart <> 0
’只要仍舊有圖片信息就繼續(xù)處理
Mid(downCode, pStart, pStop - pStart) = Space(pStop - pStart)
’將代碼中的圖片信息用空格代替,實(shí)現(xiàn)刪除效果
pStart = InStr(pStop, downCode, pString1)
’重復(fù)上面的過程,刪除其他的圖片
If pStart = 0 Then Exit Do
’沒有圖片信息后,退出循環(huán)
pStop = InStr(pStart, downCode, pString2, 1) + 1
Loop
End If
picFilter=downCode
’將處理過后的代碼返回過程函數(shù)
End Function
接下來只要使用lastResult=picFilter(lastResult)就實(shí)現(xiàn)了對臨時(shí)變量中搜索結(jié)果代碼的圖片信息去除工作,以此類推,很容易去掉諸如“ 上面所說的是一種解決方法,但我們知道HTML語法中關(guān)鍵詞很多,如果都用以上的條件過濾的話,會使程序的效率大大降低,運(yùn)行速度也會減慢很多。有沒有更好的方法?有,不同的搜索引擎返回的結(jié)果有其獨(dú)特的編排方式。我們?nèi)砸匝呕槔灰纯雌浞祷氐慕Y(jié)果源代碼就會發(fā)現(xiàn):每一條信息的鏈接和主題部分排列都是以“ ”開始,以“”結(jié)束,而在“” 和接下來的第一個(gè)“<”之間的部分是該主題的簡單描述,這樣我們可以用下面的代碼來將雅虎搜索結(jié)果代碼中的有用信息提取出來:
Public Function yahooFilter(downCode)
Dim sString1 As String, sString2 As String, sString3 As String
Dim sStart As Long, sStop As Long
Dim string1 As String, string2 As String, lastString as string
sString1 =“ ”
sString2 =“”
sString3 =“<”
sStart = InStr(downCode, sString1)
’取得第一條主題信息的起始位置
Do While sStart <> 0
sStop = InStr(sStart, downCode, sString2)
string1 = Mid(downCode, sStart + 4, sStop - sStart)
’將第一條主題信息存放在string1變量中
sStart = InStr(sStop, downCode, sString1)
’從第一條主題信息的結(jié)束部位開始查找該主題的簡單描述
sStart = sStop + 4
sStop = InStr(sStart, downCode, sString3)
’取得該主題描述部分的結(jié)束位置
If sStop = sStart Then
’判斷是否只有主題而沒有描述的信息
string2 = “”
ElseIf sStop <> sStart Then
string2 = Mid(downCode, sStart, sStop - sStart - 1)
’取出主題描述部分
End If
lastString = lastString + “ ” + string1 + string2
’將提煉的結(jié)果存放在臨時(shí)變量中
Start = InStr(sStop, downCode, sString1)
’重新定位下一條信息的起始位置
Loop ’循環(huán)
yahooFilter = lastString
End Function
經(jīng)過了上面復(fù)雜的處理,將結(jié)果寫到一個(gè)網(wǎng)頁文件中,然后調(diào)用瀏覽器顯示,就會出現(xiàn)整整齊齊的結(jié)果。
現(xiàn)在比較流行的搜索軟件,比如 SearchX98、Crazysearch,它們都符合上面所說的原理,但它們各自都有自己的一些獨(dú)特之處,比如SearchX98 能夠連續(xù)搜索多個(gè)引擎,其實(shí)就是發(fā)出一條搜索指令后,程序本身連續(xù)向各個(gè)搜索引擎發(fā)出搜索指令,將返回的結(jié)果經(jīng)過簡單的處理生成一個(gè)頁面,其他的內(nèi)容搜索更是最簡單地直接發(fā)出搜索指令而已。而對于 Crazysearch,您只要打開注冊表,就會發(fā)現(xiàn)其中文搜索只能搜索中文雅虎,英文只能搜索Excite,號稱注冊版本能夠搜索1000條記錄,其實(shí)您只要分析一下雅虎的搜索代碼就會發(fā)現(xiàn),其中有一個(gè)關(guān)鍵詞是“n=”,代表一次搜索返回的結(jié)果數(shù)目;另外一個(gè)是“b=”,代表從第幾條記錄開始顯示,就是這兩個(gè)關(guān)鍵詞起到了重要的作用,但Crazysearch的獨(dú)特之處在于返回的搜索結(jié)果以表格方式排列,直觀醒目。
結(jié)束語
本文剖析了現(xiàn)在流行的搜索軟件并介紹了使用VB 6.0制作搜索軟件的辦法。在搜索軟件方面, 當(dāng)然還有很多工作可以去做, 希望此文能起到拋磚引玉的作用。
|