網(wǎng)絡(luò )蜘蛛可以算得上是為Internet而開(kāi)發(fā)的最有用處的工具之一。時(shí)至今日,要想從以千萬(wàn)計的各不相同 的站點(diǎn)中獲取信息,舍網(wǎng)絡(luò )蜘蛛之外,焉有他哉?
一個(gè)典型的網(wǎng)絡(luò )蜘蛛(例如雅虎)工作的方式,是查看一個(gè)頁(yè)面,并從中找到相關(guān)信息, 然后它再 從該頁(yè)面的所有鏈接中出發(fā),繼續尋找相關(guān)的信息。以此類(lèi)推,直至窮盡。很快地,就可以在數據庫中獲得成 千上萬(wàn)的頁(yè)面和信息。這樣的工作方式就如同一張向外發(fā)散的蜘蛛網(wǎng),這正是“網(wǎng)絡(luò )蜘蛛”這個(gè)名稱(chēng)的由來(lái)。
接下來(lái)讓我們看看如何建立一個(gè)網(wǎng)絡(luò )蜘蛛。在此之前,我們先要了解幾個(gè)概念。
一、基本原理
我們可以用網(wǎng)絡(luò )蜘蛛搜尋很多東西。事實(shí)上,現在有一些特別用途的商用網(wǎng)絡(luò )蜘蛛,這些軟件為它們的開(kāi) 發(fā)者賺取了大把的鈔票,比如Altavista科技的一份許可證,就價(jià)值30萬(wàn)美元。以下是一個(gè)網(wǎng)絡(luò )蜘蛛的基礎原理:
* 從各個(gè)消息來(lái)源收集信息
從技術(shù)角度講,一個(gè)網(wǎng)絡(luò )蜘蛛應該可以不受限制地從任意來(lái)源獲取信息。來(lái)源多多益善。
* 準確度
不管是誰(shuí),遇見(jiàn)這樣的事情肯定都會(huì )崩潰——搜索引擎向你返回了一百萬(wàn)個(gè)結果,可是,只有最后兩個(gè)是 你需要的(這還算好的,如果是中間的兩個(gè)呢?)。所以好的網(wǎng)絡(luò )蜘蛛對其返回的結果應該有足夠的準確度, 而且在有些情況下,還要有特定的功能,也就是說(shuō),只返回特定類(lèi)型的信息——比如www.enfused.com的專(zhuān)為 搜索游戲設計的網(wǎng)絡(luò )蜘蛛,就只返回與游戲相關(guān)的東西。
* 相對更新
這依賴(lài)于你所使用的技術(shù)(下面我們會(huì )專(zhuān)門(mén)提到),網(wǎng)絡(luò )蜘蛛應該找回更新后的信息,或者至少是比較新 的信息。如果網(wǎng)絡(luò )蜘蛛總是找回一些幾年前的陳芝麻爛谷子,那你一定會(huì )比系統先一步崩潰。
* 相對快速
這就不用多說(shuō)了,如果沒(méi)有足夠的速度,那你的網(wǎng)絡(luò )蜘蛛再怎么準確,也是白搭。
二、基本技術(shù)
有好幾種方法可以構建網(wǎng)絡(luò )蜘蛛。第一種,稱(chēng)之為常規網(wǎng)絡(luò )蜘蛛,只是簡(jiǎn)單地進(jìn)行頁(yè)面尋找,搜索并獲得 你想要的東西。例如,用一個(gè)短語(yǔ)作為關(guān)鍵詞進(jìn)行搜索。第二種,特殊網(wǎng)絡(luò )蜘蛛,只尋找頁(yè)面的特定部分。這 種網(wǎng)絡(luò )蜘蛛在某些特定場(chǎng)合很有用(比如,你只想獲得某一個(gè)站點(diǎn)內的新聞標題)。
常規網(wǎng)絡(luò )蜘蛛是兩者中相對簡(jiǎn)單的一種。首先,你不需要預先知道目標頁(yè)面的情況。只需要在該頁(yè)面中, 以及在與其鏈接的頁(yè)面中,尋找你要的關(guān)鍵詞就可以了。你還可以在功能中設定,忽略掉那些在同一站點(diǎn)下的 鏈接,從而保證每一個(gè)結果都來(lái)源于不同的站點(diǎn)。
與之相對應,一個(gè)特定的網(wǎng)絡(luò )蜘蛛通常要求你預先知道一些目標頁(yè)面的情況,例如表格規劃等。舉個(gè)例子 ,如果你搜尋的是一個(gè)頁(yè)面中的新聞標題,你應該先知道限定此標題的HTML標記。如此你才可以直接搜索頁(yè)面 中正確的部分。在這種情況下,是否具備搜索該頁(yè)面的所有鏈接的功能顯得不是特別重要,因為你的網(wǎng)絡(luò )蜘蛛 很可能在別的頁(yè)面中無(wú)法找到標記,不能進(jìn)行工作。
運行網(wǎng)絡(luò )蜘蛛的時(shí)間也有所不同:你可以預先運行,也可以實(shí)時(shí)運行。預先運行意味著(zhù)當你的網(wǎng)絡(luò )蜘蛛運 行時(shí),所有搜集到的信息都存貯在一個(gè)數據庫中,以備以后使用。很明顯,如此你將不會(huì )獲得最新的數據,但 是如果你經(jīng)常運行網(wǎng)絡(luò )蜘蛛,這個(gè)問(wèn)題也不會(huì )有什么大礙。
實(shí)時(shí)運行意味著(zhù)你每次運行網(wǎng)絡(luò )蜘蛛所獲得的信息都不會(huì )被保存下來(lái),你只能現找現用。例如,如果你在 站點(diǎn)設置了搜索功能,在實(shí)時(shí)狀態(tài)下使用網(wǎng)絡(luò )蜘蛛,則無(wú)論何時(shí),只要有用戶(hù)輸入一個(gè)關(guān)鍵詞并點(diǎn)下“發(fā)送” 按鈕,你的網(wǎng)絡(luò )蜘蛛就將運行,而不是僅僅訪(fǎng)問(wèn)數據庫。盡管這可以保證你的數據總是最新的,但是卻不是大 多數站點(diǎn)的首選,因為網(wǎng)絡(luò )蜘蛛本身運行和返回數據都需要時(shí)間——而時(shí)間就是金錢(qián)呀!當然,所查找的資料 具有高度時(shí)間敏感性的時(shí)候例外。
三、構建網(wǎng)絡(luò )蜘蛛
那么如何用ASP構建網(wǎng)絡(luò )蜘蛛呢?答案是:Internet transfer control (ITC)。這個(gè)由 微軟提供的控件,將使你能夠通過(guò)ASP程序訪(fǎng)問(wèn)Internet資源。你可以用ITC搜尋Web頁(yè)面,訪(fǎng)問(wèn)FTP服務(wù)器,甚 至可以發(fā)送郵件標題。在本文里,我們將著(zhù)重討論搜尋Web頁(yè)面的功能。
有幾個(gè)缺陷必須先說(shuō)明一下。第一,ASP無(wú)權訪(fǎng)問(wèn)Windows的注冊表,這就使某些ITC正常存儲的常量和數 值不可用。通常你可以通過(guò)設置ITC為“不使用默認值”來(lái)解決這個(gè)問(wèn)題,這就需要你在運行過(guò)程中指明每一 次的值。
另一個(gè)更嚴重的問(wèn)題是關(guān)于許可證書(shū)的。由于A(yíng)SP不具備調用License Manager(一項Windows中的功 能,可以保證組件和控件的合法使用)的功能,那么當License Manager檢查當前組件的密鑰密碼,并將 其與Windows注冊表進(jìn)行比較后,如果發(fā)現它們不同,該組件將不會(huì )工作。因此,當你想把ITC配置到另一臺沒(méi) 有所需密鑰的計算機上時(shí),將導致ITC崩潰。解決的辦法之一是將ITC捆綁到另一個(gè)VB組件中,由VB組件復制 ITC的路徑和工具,從而進(jìn)行配置。這項工作很麻煩,但不幸的是,它是必不可少的。
下面是一些例子:
你可以用下面的編碼建立ITC:
現在strHTML保存著(zhù)strURL指向的整個(gè)頁(yè)面的HTML內容。要建立一個(gè)常規網(wǎng)絡(luò )蜘蛛,你現在只需要調用 instr() 功能來(lái)看看你尋找的串是否在當前位置即可。你也可以按照href標記尋找,解析當前的 URL,然后把它設置到Internet 控件的屬性中去,接著(zhù)再繼續打開(kāi)另一個(gè)頁(yè)面。用來(lái)查看所有鏈接的最 好方法是使用遞歸。
要注意的是,盡管這種方法很易于實(shí)行,卻不是非常準確和強大。今天的許多搜索引擎都可以進(jìn)行額外的 邏輯檢查,例如計算一個(gè)頁(yè)面中某一短語(yǔ)重復的次數,相關(guān)字詞的近似程度等,有些甚至可以用來(lái)判斷所搜尋 的語(yǔ)段與上下文的關(guān)系。這些功能將留待我們的讀者們自己去摸索。
四、特定網(wǎng)絡(luò )蜘蛛
相對的,一個(gè)特定網(wǎng)絡(luò )蜘蛛要復雜一些。如我們早先提到的,一個(gè)特定網(wǎng)絡(luò )蜘蛛會(huì )搜尋一個(gè)頁(yè)面的特定部 分,因而要求預先知道該部分相關(guān)的情況。讓我們先看看下面的HTML:
<HTML><HEAD><TITLE>My News Page</TITLE><META Name=&quo t;keywords" Content="News, headlines"><META Name="descr iption" Content="The current news headlines."></HEAD> ;<BODY BGCOLOR="#FFFFFF" TEXT="#000000" LINK="#FF3300 "VLINK="#CC0000" ALINK="#0000FF"><p><h3>Headlines&l t;/h3></p><!--put headlines here--><a href="/news/8094.asp ">Stocks prices fall</a><a href="/news/8095.asp">Ne w movies today</a><a href="/news/8096.asp">Bush and&nb sp;Gore to debate tonight</a><a href="/news/8097.asp"> Fall TV lineup</a><!--end headlines--></BODY></HTML>
在這個(gè)頁(yè)面內,我們只關(guān)心位于“put headlines here”和 “end headlines”這 兩個(gè)標記之間的東西。你可以構建一個(gè)只返回該區域查找結果的功能設置:
按照上面構建ITC控件的例子,你可以很容易地將strHTML中的“ <!--put headlines here-->”和 “<!--end headlines-->”作為參數傳 送到GetText中。
要注意,用于開(kāi)始和結束的標記都不一定要是實(shí)際的HTML專(zhuān)用標記——它們可以是你想使用的任何文本界 定符。在通常情況下,你不容易找到好的HTML標記來(lái)界定搜尋區域。你只能使用比較方便稱(chēng)手的標記——例如 ,你的首尾標記可以分別如下:
strStartTag = "/td><td><font face="arial" size=&q uot;2"><p><b><u>"
strEndTag = "<p></td></tr><tr><td><ums>&quo t;
一定要確定搜索的是HTML頁(yè)中比較獨特的標識,這樣你才可以準確地獲得你需要的東西。你也可以按照你 所返回的文本部分中的鏈接進(jìn)行搜尋,不過(guò)如果你不知道那些頁(yè)面的格式,你的網(wǎng)絡(luò )蜘蛛將無(wú)功而返。
五、保存信息
在大多數情況下,你會(huì )要求將收集到的信息保存在一個(gè)數據庫中,以備以后使用。你的需求也許包括很廣 泛的內容,但是在此之前,你要記住以下幾件事:
?、?
在你的數據庫中查找最新信息
如果你經(jīng)常使用網(wǎng)絡(luò )蜘蛛去查找一個(gè)站點(diǎn)內的新聞標題,你要先確定比較新的標題已經(jīng)存在于數據庫內。 然后將其與網(wǎng)絡(luò )蜘蛛返回的結果相比較,只添加更新過(guò)的部分。這樣可以防止你保存一大堆重復數據。
?、?
更新信息
也許你根本就不想從外部向數據庫中添加新信息。比如,如果你維護的是一個(gè)美國各州人口的網(wǎng)上索引, 你只需要在數據庫內部更新——你將不需要在表格內插入新的信息。
?、?
保存所需信息
如果你在查找標題,要確定你也同時(shí)查找了該標題指向的鏈接,并將其保存下來(lái)。如果沒(méi)有鏈接,你 也應該建立一個(gè)。例如,如果我從www.yoursite.com查找標題,并在www.mysite .com演示,而該標題與一篇在站點(diǎn)之外的文章有鏈接,那么我必須先保存http://www.you rsite.com這一鏈接,然后再保存其它鏈接到數據庫內,這些鏈接才可以正常訪(fǎng)問(wèn)。
六、結論
我們已經(jīng)簡(jiǎn)要介紹了如何構建一個(gè)比較完整的網(wǎng)絡(luò )蜘蛛。所有的基本功能都已涉及?,F在你需要做的就是 再在里面加上你自己的東西。
這一類(lèi)功能將被應用在一個(gè)COM對象或者一個(gè)獨立的應用軟件內。在ASP中設置這項功能非常方便, 但是你應該將你的編碼移到另外的地方,以提高速度和安全性。而且這樣也可以令其更容易被打包和傳送。
作者: 大眾網(wǎng)絡(luò )報 張黎 時(shí)間:2005-08-07 21:06 出處:編程愛(ài)好者網(wǎng)站



用vb構造網(wǎng)絡(luò )蜘蛛
什么是網(wǎng)絡(luò )蜘蛛
網(wǎng)絡(luò )蜘蛛是一種能自動(dòng)到網(wǎng)上查找信息的一種程序,該程序具有高度的自動(dòng)性,只要告訴他一個(gè)網(wǎng)站,他就可以從這個(gè)網(wǎng)站開(kāi)始依次通過(guò)該網(wǎng)站的鏈接自動(dòng)抓取鏈接內容以及網(wǎng)址,然后就順著(zhù)這些鏈接一直抓下去。
網(wǎng)絡(luò )蜘蛛可以方便的實(shí)現從網(wǎng)絡(luò )中抓取信息并且保存到當地數據庫。
智能型的網(wǎng)絡(luò )蜘蛛甚至可以抓取您指定的信息并自動(dòng)過(guò)濾掉不相關(guān)的信息,替代重復的人工操作。
網(wǎng)絡(luò )蜘蛛運行時(shí)必須設置種子網(wǎng)站,設置的種子網(wǎng)站必須可以鏈接下去,否則可能會(huì )造成蜘蛛停止工作。因此我們在設置種子網(wǎng)站時(shí)可以設置比較大型的、鏈接比較多的網(wǎng)站,當然您也可以設置多個(gè)種子網(wǎng)站以確保網(wǎng)絡(luò )蜘蛛能運行足夠長(cháng)的時(shí)間。
蜘蛛程序網(wǎng)站層次及其工作原理描述
序號 網(wǎng)站 層次 父序號
1 http://www.netfox.cn/ 1 0
2 http://www.sina.com.cn/ 2 1
3 http://www.cnnic.cn/ 2 1
4 http://www.baidu.cn/ 3 2
5 http://www.yahoo.cn/ 3 2
蜘蛛程序首先從層次1(http://www.netfox.cn/)開(kāi)始提取所有的網(wǎng)站鏈接,把所有網(wǎng)站鏈接記錄到數據庫(或者大數組等),并把這些網(wǎng)站鏈接標識為層次2;
當把層次2全部記錄到數據庫后,開(kāi)始從層次2中順序為第一的(這里指序號為2的網(wǎng)站)網(wǎng)站鏈接開(kāi)始提取其下面的的所有鏈接記錄到數據庫,并把這些網(wǎng)站鏈接標識為層次3;然后依次把層次為2的網(wǎng)站的所有鏈接記錄到數據庫,同時(shí)把他們的層次標識為層次3;
當層次3全部記錄數據庫后,開(kāi)始從層次3中順序為第一的網(wǎng)站鏈接開(kāi)始提取,依次類(lèi)推即可!
注意:程序要保留一個(gè)指針記錄當前正在操作的序號!另外您也可以增加一個(gè)父序號字段來(lái)記錄他們之間的繼承關(guān)系!
層次1表示為網(wǎng)絡(luò )種子;我們這里把網(wǎng)絡(luò )種子放在第一層,根據需要您可以設置一個(gè)或者多個(gè)網(wǎng)絡(luò )種子,實(shí)際上我們通過(guò)這個(gè)層次圖可以很顯然地看出來(lái),低層次的網(wǎng)址就是高層次的網(wǎng)絡(luò )種子。也就是說(shuō)只要有一個(gè)或者幾個(gè)網(wǎng)絡(luò )種子,我們就可以通過(guò)他們的鏈接找到更多的網(wǎng)絡(luò )種子。只要這樣我們的蜘蛛才能永遠地運行下去!
層次2是通過(guò)層次1(即網(wǎng)絡(luò )種子)抓取到的鏈接;
層次3是通過(guò)層次2抓取到的鏈接;
依次類(lèi)推,構成一棵大樹(shù)!
蜘蛛程序關(guān)鍵代碼
由于我對VB比較熟悉,所以在此我用VB實(shí)現核心部分的代碼,當然您也可以很簡(jiǎn)單地轉換成其他語(yǔ)言代碼。在這里了為了簡(jiǎn)單起見(jiàn),我們這里不對數據庫操作,我們建立一個(gè)二維數組存放我們的網(wǎng)址??!
Dim Web(4,10000) ‘//建立數組
Dim Pointer ‘//建立指針,記錄當前種子
Dim Id ‘//建立序號,記錄當前抓區網(wǎng)站的序號
Dim Layer ‘//建立層次,記錄當前正在運行種子的層次
Dim Running ‘//建立是否運行的標志,
Private Function NewworkSeed_Set() As Boolean ‘//用來(lái)設置網(wǎng)絡(luò )種子,為演示方便我們把種子放在數組,
'//當然您也可以根據需要把他們直接放到數據庫中
Web(0,0) = 1 ‘//序號
Web(1,0) = “http://www.netfox.cn/” ‘//網(wǎng)站
Web(2,0) = 1 ‘//層次
Web(3,0) = 0 ‘//父序號,0表示為網(wǎng)絡(luò )原始種子
Web(4,0) = “奈福網(wǎng)絡(luò )”
‘//當然這里可以設置多個(gè)網(wǎng)絡(luò )原始種子
Web(0,1) = 1
Web(1,1) = “http://www.aspfaq.cn/”
Web(2,1) = 1
Web(3,1) = 0
Web(4,1) = “asp技術(shù)站”
‘//設置網(wǎng)絡(luò )種子后,記錄種子序號開(kāi)始后的序號,這里設置了2個(gè)種子,所以Id=2開(kāi)始
Id = 2
End Function
Private Sub Spider_Work() ‘//蜘蛛工作程序,抓取網(wǎng)站并記錄到數組
‘//根據需要可以把他們放到數據庫中
Dim A
For Each A In WebBrowser.Document.All
If UCase(A.tagName) = "A" Then
If IsValidWeb(A.href) Then
Id = Id + 1
Web(0, Id) = Id ‘//記錄當前網(wǎng)站的序號
Web(1, Id) = A.href ‘//記錄當前網(wǎng)站
Web(2, Id) = Layer ‘//記錄當前網(wǎng)站的層次
If Web(2,Pointer)<> Layer Then Layer = Layer + 1 ‘//當指針層次與當前層次不同的話(huà)
‘//則說(shuō)明層次已經(jīng)發(fā)生了增加
Web(3, Id) = Pointer ‘//記錄當前網(wǎng)站的父序號
Web(4,Id) = A.innerText ‘//記錄當前網(wǎng)站的名稱(chēng)
End If
End If
Next
Pointer = Pointer + 1
WebBrowser.Navigate Web(1, Pointer-1) ‘//抓取當前種子完畢后,自動(dòng)跳轉到下一個(gè)種子
If Running = False Then ‘//運行為否,退出運行
Exit Sub
End If
End Sub
Private Function Spider_Init() As Boolean ‘//蜘蛛程序初始化函數
Pointer = 1 ‘//指針設置為1,表示從第一個(gè)序號開(kāi)始運行
Id = 2 ‘//序號設置為2,以后可以讀取記錄
Layer = 0 ‘//層次設置為0,表示蜘蛛第一次運行
‘//以上指針,序號,層次都可以記錄并且方便以后讀取
If IsValidWeb(Web(1, Pointer-1)) Then ‘//判斷種子是否正確,如果正確初始化成功,否則失敗
Running = True
Spider_Init = True
WebBrowser.Navigate Web(1, Pointer-1)
Else
Running = False
Spider_Init = False
Exit Function
End If
End Function
Private Sub WebBrowser_DocumentComplete(ByVal pDisp As Object, URL As Variant) ‘//WebBrowser控件
Call Spider_Work()
End Sub
Private Function IsValidWeb(_href) As Boolean ‘//判斷是否是cn域名函數
‘//通過(guò)該函數可以實(shí)現抓取指定網(wǎng)站或數據
If InStr(_href, "http://www.") > 0 And InStr(_href, ".cn/") > 0 And Len(_href) < 60 Then
IsValidWeb = True
Else
IsValidWeb = False
End If
End Function
Private Sub InitCommand_Click() ‘//Init初始化 命令控件
If Spider_Init() Then
Msgbox “蜘蛛初始化成功并開(kāi)始運行了”
Else
Msgbox “蜘蛛初始化失敗”
End If
End Private
Private Sub StopCommand_Click() ‘//Stop停止 命令控件
Running = False ‘//停止運行
End Private
Private Sub RunCommand_Click() ‘//Run運行 命令控件
Running = True ‘//繼續運行
Call Spider_Work() ‘//蜘蛛運行主程序
End Private
聯(lián)系客服
微信登錄中...
請勿關(guān)閉此頁(yè)面


