亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來(lái)到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關(guān)于我們
? 蟲蟲下載站

?? 如何用c#語(yǔ)言構(gòu)造網(wǎng)絡(luò)蜘蛛程序1.htm

?? 如何用C#語(yǔ)言構(gòu)造網(wǎng)絡(luò)蜘蛛程序1.htm
?? HTM
?? 第 1 頁(yè) / 共 4 頁(yè)
字號(hào):

<html>
<head>
<title>如何用C#語(yǔ)言構(gòu)造網(wǎng)絡(luò)蜘蛛程序|搜索引擎,網(wǎng)絡(luò)蜘蛛,程序,算法,C#-中國(guó)源碼網(wǎng)</title>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<meta http-equiv="Refresh" content=600>
<meta name="keywords" content="搜索引擎,網(wǎng)絡(luò)蜘蛛,程序,算法,C#">
<meta name="description" content="如何用C#語(yǔ)言構(gòu)造網(wǎng)絡(luò)蜘蛛程序">
<link rel="stylesheet" href="/templates/yobo/style/default/style.css" type="text/css" media="all" />
</head><body oncontextmenu='return false' ondragstart='return false' onselectstart ='return false' onselect='document.selection.empty()' oncopy='document.selection.empty()' onbeforecopy='return false'>
<a name="top"></a>
<!--頁(yè)面頭部信息-->
<div id="header">
  <div id="topmenu">
    <div class="left">
      <div id="topdate"><a href="http://www.yuanma.org/rss.php" target="_blank" title="中國(guó)源碼 RSS 訂閱 "><img src="/images/rss.gif" border="0"></a>=>中國(guó)源碼:全球著名開源項(xiàng)目大本營(yíng)</div>
    </div>
    <div class="right">
      <div id="topnavlist">
        <ul>
                    <li><a href="/member.php?action=reg" title="注冊(cè)會(huì)員">注冊(cè)會(huì)員</a></li>
          <li><a href="/member.php?action=login" title="會(huì)員登錄">會(huì)員登錄</a></li>
          <li><a href="/member.php?action=manage" title="控制面板">控制面板</a></li>
          <li><a href="#" onClick="this.style.behavior= 'url(#default#homepage)';this.setHomePage ('http://www.yuanma.org');">設(shè)為首頁(yè)</a></li>
          <li><a href="#" onClick="window.external.addFavorite('http://www.yuanma.org','中國(guó)源碼-全球著名開放源代碼大本營(yíng)')">加入收藏</a></li>
          <li><a href="http://cgi.alexa.com/client/mail_this_site/cgi-bin/mail_this_site.cgi?url=yuanma.org" title="推薦本站" target=_blank>推薦本站</a></li>
                  </ul>
      </div>
    </div>
  </div>
  <div id="maintop">
<div id="LogoSide1">
<a href="/blog/"><img src="/images/blog.gif" alt="博客" /></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<a href="/download/"><img src="/images/download.gif" alt="下載" /></a><br />
博客&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;下載
</div>
    <div id="Logo"><a href="/"><img src="/images/logo.gif" alt="中國(guó)源碼 首頁(yè)" /></a></div>
<div id="LogoSide2">
<a href="/bbs/"><img src="/images/forum.gif" alt="論壇" /></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<a href="/lilina/" target=_blank><img src="/images/rss_reader.gif" alt="最新開源項(xiàng)目" /></a><br />
&nbsp;&nbsp;論壇&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;開源項(xiàng)目
</div>
  </div>
  <div class="navline">&nbsp;</div>
  <div class="navup">
    <div id="nav-up-left"><a href="/" class="mainmenu">首頁(yè)</a>  &#183;<a href='/data/osupdate/' target='_self' title='開源社區(qū)最新動(dòng)態(tài)、新聞' class="mainmenu">開源動(dòng)態(tài)</a>
 &#183;<a href='/data/osprojects/' target='_self' title='世界知名開源社區(qū)著名開源項(xiàng)目、軟件介紹和使用文章' class="mainmenu">應(yīng)用軟件</a>
 &#183;<a href='/data/osprojectsos/' target='_self' title='開放源代碼操作系統(tǒng) Linux FreeBSD OpenBSD..' class="mainmenu">開源操作系統(tǒng)</a>
 &#183;<a href='/data/osprojectssd/' target='_self' title='介紹程序設(shè)計(jì)方法、事例、教程
software development' class="mainmenu">程序設(shè)計(jì)</a>
 &#183;<a href='/data/osarticles/' target='_self' title='開放源代碼社區(qū)文章、評(píng)論' class="mainmenu">開源文章</a>
 &#183;<a href='/data/yuanmaprotocol/' target='_self' title='介紹網(wǎng)絡(luò)協(xié)議、RFC及安全' class="mainmenu">網(wǎng)絡(luò)協(xié)議與安全</a>
·<a href="/data/special/" class="mainmenu">專題</a>·<a href="/mypage.php?action=picture" class="mainmenu">圖片文章</a>·<a href="/search.php" title="搜索" class="mainmenu">搜索</a>· <a href="/contribute.php" title="投稿" class="mainmenu">投稿</a> </div>
  </div>
  <div class="navline">&nbsp;</div>
</div>

<SCRIPT language=javascript type=text/javascript>
var currentpos,timer;

function initialize()
{
timer=setInterval("scrollwindow()",2);
}
function sc(){
clearInterval(timer);
}
function scrollwindow()
{
currentpos=document.body.scrollTop;
window.scroll(0,++currentpos);
if (currentpos != document.body.scrollTop)
sc();
}
document.onmousedown=sc
document.ondblclick=initialize
</SCRIPT>
<script language="JavaScript">
function fontZoom(size)
{
 document.getElementById('fontzoom').style.fontSize=size+'px'
}

function doCheck(){

// 檢測(cè)表單的有效性
// 如:標(biāo)題不能為空,內(nèi)容不能為空,等等....
if (myform.username.value=="") {
alert("請(qǐng)輸入姓名!");
myform.username.focus();
return false;
}

if (myform.content.value=="") {
alert("請(qǐng)輸入評(píng)論內(nèi)容!");
myform.content.focus();
return false;
}
if (myform.checkcode.value=="") {
alert("請(qǐng)輸入驗(yàn)證碼!");
myform.checkcode.focus();
return false;
}
return true;
}
</script>
<div class="mainline">&nbsp;</div>
<div class="maincolumn">
<div class="navadimg">
<script type="text/javascript"><!--
google_ad_client = "pub-4357927283882197";
google_ad_width = 728;
google_ad_height = 90;
google_ad_format = "728x90_as";
google_ad_type = "image";
google_ad_channel = "";
//--></script>
<script type="text/javascript"
  src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</div>
</div>
<div class="mainline">&nbsp;</div>
<div class="maincolumn">
  <div id="flist">
    <div class="ftitleico">&nbsp;</div>
    <div class="ftitlebg">
      <div class="ftitlename">當(dāng)前位置: <a href='/' class='position'>首頁(yè)</a> >> <a href='/data/osprojectssd/' class='position'>程序設(shè)計(jì)</a>  &gt;&gt; 如何用C#語(yǔ)言構(gòu)造網(wǎng)絡(luò)蜘蛛程序</div>
    </div>
    <div class="clear">&nbsp;</div>
    <div id="newsview">
        <div class="title">
          <h1>如何用C#語(yǔ)言構(gòu)造網(wǎng)絡(luò)蜘蛛程序</h1>
                    <h2><strong>作者:</strong><a href="/member.php?action=show&username=webmaster" target="_blank"></a>            &nbsp;&nbsp;&nbsp;&nbsp; <strong>來(lái)源:</strong><a href="http://blog.csdn.net/smildlzj/archive/2006/09/21/1260758.aspx" target="_blank">zz</a>&nbsp;&nbsp;&nbsp;&nbsp; <strong>發(fā)表時(shí)間:</strong>2006-09-21&nbsp;&nbsp;&nbsp;&nbsp;
            <strong>瀏覽次數(shù):</strong>
            <script language=Javascript src="/view.php?articleid=1570"></script>
            &nbsp;&nbsp;&nbsp;&nbsp; <strong>字號(hào):</strong><a href="javascript:fontZoom(16)" class=black>大</a>&nbsp;&nbsp;<a href="javascript:fontZoom(14)" class=black>中</a>&nbsp;&nbsp;<a href="javascript:fontZoom(12)" class=black>小</a></h2>
        </div>
                <div id="fontzoom" class="content">
          <p>如何用C#語(yǔ)言構(gòu)造蜘蛛程序 <BR> "蜘蛛"(Spider)是Internet上一種很有用的程序,搜索引擎利用蜘蛛程序?qū)eb頁(yè)面收集到數(shù)據(jù)庫(kù),企業(yè)利用蜘蛛程序監(jiān)視競(jìng)爭(zhēng)對(duì)手的網(wǎng)站并跟蹤變動(dòng),個(gè)人用戶用蜘蛛程序下載Web頁(yè)面以便脫機(jī)使用,開發(fā)者利用蜘蛛程序掃描自己的Web檢查無(wú)效的鏈接……對(duì)于不同的用戶,蜘蛛程序有不同的用途。那么,蜘蛛程序到底是怎樣工作的呢? <BR><BR>  蜘蛛是一種半自動(dòng)的程序,就象現(xiàn)實(shí)當(dāng)中的蜘蛛在它的Web(蜘蛛網(wǎng))上旅行一樣,蜘蛛程序也按照類似的方式在Web鏈接織成的網(wǎng)上旅行。蜘蛛程序之所以是半自動(dòng)的,是因?yàn)樗偸切枰粋€(gè)初始鏈接(出發(fā)點(diǎn)),但此后的運(yùn)行情況就要由它自己決定了,蜘蛛程序會(huì)掃描起始頁(yè)面包含的鏈接,然后訪問這些鏈接指向的頁(yè)面,再分析和追蹤那些頁(yè)面包含的鏈接。從理論上看,最終蜘蛛程序會(huì)訪問到Internet上的每一個(gè)頁(yè)面,因?yàn)镮nternet上幾乎每一個(gè)頁(yè)面總是被其他或多或少的頁(yè)面引用。 <BR><BR>  本文介紹如何用C#語(yǔ)言構(gòu)造一個(gè)蜘蛛程序,它能夠把整個(gè)網(wǎng)站的內(nèi)容下載到某個(gè)指定的目錄,程序的運(yùn)行界面如圖一。你可以方便地利用本文提供的幾個(gè)核心類構(gòu)造出自己的蜘蛛程序。 <BR>  C#特別適合于構(gòu)造蜘蛛程序,這是因?yàn)樗呀?jīng)內(nèi)置了HTTP訪問和多線程的能力,而這兩種能力對(duì)于蜘蛛程序來(lái)說(shuō)都是非常關(guān)鍵的。下面是構(gòu)造一個(gè)蜘蛛程序要解決的關(guān)鍵問題: <BR><BR>  ⑴ HTML分析:需要某種HTML解析器來(lái)分析蜘蛛程序遇到的每一個(gè)頁(yè)面。 <BR><BR>  ⑵ 頁(yè)面處理:需要處理每一個(gè)下載得到的頁(yè)面。下載得到的內(nèi)容可能要保存到磁盤,或者進(jìn)一步分析處理。 <BR><BR>  ⑶ 多線程:只有擁有多線程能力,蜘蛛程序才能真正做到高效。 <BR><BR>  ⑷ 確定何時(shí)完成:不要小看這個(gè)問題,確定任務(wù)是否已經(jīng)完成并不簡(jiǎn)單,尤其是在多線程環(huán)境下。 <BR><BR>  一、HTML解析 <BR><BR>  C#語(yǔ)言本身不包含解析HTML的能力,但支持XML解析;不過,XML有著嚴(yán)格的語(yǔ)法,為XML設(shè)計(jì)的解析器對(duì)HTML來(lái)說(shuō)根本沒用,因?yàn)镠TML的語(yǔ)法要寬松得多。為此,我們需要自己設(shè)計(jì)一個(gè)HTML解析器。本文提供的解析器是高度獨(dú)立的,你可以方便地將它用于其它用C#處理HTML的場(chǎng)合。 <BR><BR>  本文提供的HTML解析器由ParseHTML類實(shí)現(xiàn),使用非常方便:首先創(chuàng)建該類的一個(gè)實(shí)例,然后將它的Source屬性設(shè)置為要解析的HTML文檔: <BR><BR>ParseHTML parse = new ParseHTML();parse.Source = " 
<P>Hello World</P>";<BR><BR><BR><BR>  接下來(lái)就可以利用循環(huán)來(lái)檢查HTML文檔包含的所有文本和標(biāo)記。通常,檢查過程可以從一個(gè)測(cè)試Eof方法的while循環(huán)開始: <BR><BR>while(!parse.Eof()){char ch = parse.Parse();<BR><BR><BR><BR>  Parse方法將返回HTML文檔包含的字符--它返回的內(nèi)容只包含那些非HTML標(biāo)記的字符,如果遇到了HTML標(biāo)記,Parse方法將返回0值,表示現(xiàn)在遇到了一個(gè)HTML標(biāo)記。遇到一個(gè)標(biāo)記之后,我們可以用GetTag()方法來(lái)處理它。 <BR><BR>if(ch==0){HTMLTag tag = parse.GetTag();}<BR><BR><BR><BR>  一般地,蜘蛛程序最重要的任務(wù)之一就是找出各個(gè)HREF屬性,這可以借助C#的索引功能完成。例如,下面的代碼將提取出HREF屬性的值(如果存在的話)。 <BR><BR>Attribute href = tag["HREF"];string link = href.Value;<BR><BR><BR><BR>  獲得Attribute對(duì)象之后,通過Attribute.Value可以得到該屬性的值。 <BR><BR>二、處理HTML頁(yè)面 <BR><BR>  下面來(lái)看看如何處理HTML頁(yè)面。首先要做的當(dāng)然是下載HTML頁(yè)面,這可以通過C#提供的HttpWebRequest類實(shí)現(xiàn): <BR><BR>HttpWebRequest request = (HttpWebRequest)WebRequest.Create(m_uri);response = request.GetResponse();stream = response.GetResponseStream();<BR><BR><BR><BR>  接下來(lái)我們就從request創(chuàng)建一個(gè)stream流。在執(zhí)行其他處理之前,我們要先確定該文件是二進(jìn)制文件還是文本文件,不同的文件類型處理方式也不同。下面的代碼確定該文件是否為二進(jìn)制文件。 <BR><BR>if( !response.ContentType.ToLower().StartsWith("text/") ){SaveBinaryFile(response);return null;}string buffer = "",line;<BR><BR><BR><BR>  如果該文件不是文本文件,我們將它作為二進(jìn)制文件讀入。如果是文本文件,首先從stream創(chuàng)建一個(gè)StreamReader,然后將文本文件的內(nèi)容一行一行加入緩沖區(qū)。 <BR><BR>reader = new StreamReader(stream);while( (line = reader.ReadLine())!=null ){buffer+=line+"\r\n";}<BR><BR><BR><BR>  裝入整個(gè)文件之后,接著就要把它保存為文本文件。 <BR><BR>SaveTextFile(buffer);<BR><BR><BR><BR>  下面來(lái)看看這兩類不同文件的存儲(chǔ)方式。 <BR><BR>  二進(jìn)制文件的內(nèi)容類型聲明不以"text/"開頭,蜘蛛程序直接把二進(jìn)制文件保存到磁盤,不必進(jìn)行額外的處理,這是因?yàn)槎M(jìn)制文件不包含HTML,因此也不會(huì)再有需要蜘蛛程序處理的HTML鏈接。下面是寫入二進(jìn)制文件的步驟。 <BR><BR>  首先準(zhǔn)備一個(gè)緩沖區(qū)臨時(shí)地保存二進(jìn)制文件的內(nèi)容。 byte []buffer = new byte[1024];<BR><BR><BR><BR>  接下來(lái)要確定文件保存到本地的路徑和名稱。如果要把一個(gè)myhost.com網(wǎng)站的內(nèi)容下載到本地的c:\test文件夾,二進(jìn)制文件的網(wǎng)上路徑和名稱是http://myhost.com/images/logo.gif,則本地路徑和名稱應(yīng)當(dāng)是c:\test\images\logo.gif。與此同時(shí),我們還要確保c:\test目錄下已經(jīng)創(chuàng)建了images子目錄。這部分任務(wù)由convertFilename方法完成。 <BR><BR>string filename = convertFilename( response.ResponseUri );<BR><BR><BR><BR>  convertFilename方法分離HTTP地址,創(chuàng)建相應(yīng)的目錄結(jié)構(gòu)。確定了輸出文件的名字和路徑之后就可以打開讀取Web頁(yè)面的輸入流、寫入本地文件的輸出流。 <BR><BR>Stream outStream = File.Create( filename );Stream inStream = response.GetResponseStream();<BR><BR><BR><BR>  接下來(lái)就可以讀取Web文件的內(nèi)容并寫入到本地文件,這可以通過一個(gè)循環(huán)方便地完成。 <BR><BR>int l;do{l = inStream.Read(buffer,0,buffer.Length);if(l&gt;0)outStream.Write(buffer,0,l);} while(l&gt;0);<BR><BR><BR><BR>  寫入整個(gè)文件之后,關(guān)閉輸入流、輸出流。 <BR><BR>outStream.Close();inStream.Close();<BR><BR><BR><BR>  比較而言,下載文本文件更容易一些。文本文件的內(nèi)容類型總是以"text/"開頭。假設(shè)文件已被下載并保存到了一個(gè)字符串,這個(gè)字符串可以用來(lái)分析網(wǎng)頁(yè)包含的鏈接,當(dāng)然也可以保存為磁盤上的文件。下面代碼的任務(wù)就是保存文本文件。 <BR><BR>string filename = convertFilename( m_uri );StreamWriter outStream = new StreamWriter( filename );outStream.Write(buffer);outStream.Close();<BR><BR><BR><BR>  在這里,我們首先打開一個(gè)文件輸出流,然后將緩沖區(qū)的內(nèi)容寫入流,最后關(guān)閉文件。 <BR><BR>  三、多線程 <BR><BR>  多線程使得計(jì)算機(jī)看起來(lái)就象能夠同時(shí)執(zhí)行一個(gè)以上的操作,不過,除非計(jì)算機(jī)包含多個(gè)處理器,否則,所謂的同時(shí)執(zhí)行多個(gè)操作僅僅是一種模擬出來(lái)的效果--靠計(jì)算機(jī)在多個(gè)線程之間快速切換達(dá)到"同時(shí)"執(zhí)行多個(gè)操作的效果。一般而言,只有在兩種情況下多線程才能事實(shí)上提高程序運(yùn)行的速度。第一種情況是計(jì)算機(jī)擁有多個(gè)處理器,第二種情況是程序經(jīng)常要等待某個(gè)外部事件。 <BR><BR>  對(duì)于蜘蛛程序來(lái)說(shuō),第二種情況正是它的典型特征之一,它每發(fā)出一個(gè)URL請(qǐng)求,總是要等待文件下載完畢,然后再請(qǐng)求下一個(gè)URL。如果蜘蛛程序能夠同時(shí)請(qǐng)求多個(gè)URL,顯然能夠有效地減少總下載時(shí)間。 <BR><BR>  為此,我們用DocumentWorker類封裝所有下載一個(gè)URL的操作。每當(dāng)一個(gè)DocumentWorker的實(shí)例被創(chuàng)建,它就進(jìn)入循環(huán),等待下一個(gè)要處理的URL。下面是DocumentWorker的主循環(huán): <BR><BR>while(!m_spider.Quit ){m_uri = m_spider.ObtainWork();m_spider.SpiderDone.WorkerBegin();string page = GetPage();if(page!=null)ProcessPage(page);m_spider.SpiderDone.WorkerEnd();}<BR><BR><BR><BR>  這個(gè)循環(huán)將一直運(yùn)行,直至Quit標(biāo)記被設(shè)置成了true(當(dāng)用戶點(diǎn)擊"Cancel"按鈕時(shí),Quit標(biāo)記就被設(shè)置成true)。在循環(huán)之內(nèi),我們調(diào)用ObtainWork獲取一個(gè)URL。ObtainWork將一直等待,直到有一個(gè)URL可用--這要由其他線程解析文檔并尋找鏈接才能獲得。Done類利用WorkerBegin和WorkerEnd方法來(lái)確定何時(shí)整個(gè)下載操作已經(jīng)完成。 <BR><BR>  從圖一可以看出,蜘蛛程序允許用戶自己確定要使用的線程數(shù)量。在實(shí)踐中,線程的最佳數(shù)量受許多因素影響。如果你的機(jī)器性能較高,或者有兩個(gè)處理器,可以設(shè)置較多的線程數(shù)量;反之,如果網(wǎng)絡(luò)帶寬、機(jī)器性能有限,設(shè)置太多的線程數(shù)量其實(shí)不一定能夠提高性能。 <BR><BR>  四、任務(wù)完成了嗎? <BR><BR>  利用多個(gè)線程同時(shí)下載文件有效地提高了性能,但也帶來(lái)了線程管理方面的問題。其中最復(fù)雜的一個(gè)問題是:蜘蛛程序何時(shí)才算完成了工作?在這里我們要借助一個(gè)專用的類Done來(lái)判斷。 <BR><BR>  首先有必要說(shuō)明一下"完成工作"的具體含義。只有當(dāng)系統(tǒng)中不存在等待下載的URL,而且所有工作線程都已經(jīng)結(jié)束其處理工作時(shí),蜘蛛程序的工作才算完成。也就是說(shuō),完成工作意味著已經(jīng)沒有等待下載和正在下載的URL。 <BR><BR>  Done類提供了一個(gè)WaitDone方法,它的功能是一直等待,直到Done對(duì)象檢測(cè)到蜘蛛程序已完成工作。下面是WaitDone方法的代碼。 <BR><BR>public void WaitDone(){Monitor.Enter(this);while ( m_activeThreads&gt;0 ){Monitor.Wait(this);}Monitor.Exit(this);}<BR><BR><BR><BR>  WaitDone方法將一直等待,直到不再有活動(dòng)的線程。但必須注意的是,下載開始的最初階段也沒有任何活動(dòng)的線程,所以很容易造成蜘蛛程序一開始就立即停止的現(xiàn)象。為解決這個(gè)問題,我們還需要另一個(gè)方法WaitBegin來(lái)等待蜘蛛程序進(jìn)入"正式的"工作階段。一般的調(diào)用次序是:先調(diào)用WaitBegin,再接著調(diào)用WaitDone,WaitDone將等待蜘蛛程序完成工作。下面是WaitBegin的代碼: <BR><BR>public void WaitBegin(){Monitor.Enter(this);while ( !m_started ){Monitor.Wait(this);}Monitor.Exit(this);}<BR><BR><BR><BR>  WaitBegin方法將一直等待,直到m_started標(biāo)記被設(shè)置。m_started標(biāo)記是由WorkerBegin方法設(shè)置的。工作線程在開始處理各個(gè)URL之時(shí),會(huì)調(diào)用WorkerBegin;處理結(jié)束時(shí)調(diào)用WorkerEnd。WorkerBegin和WorkerEnd這兩個(gè)方法幫助Done對(duì)象確定當(dāng)前的工作狀態(tài)。下面是WorkerBegin方法的代碼: <BR><BR>public void WorkerBegin(){Monitor.Enter(this);m_activeThreads++;m_started = true;Monitor.Pulse(this);Monitor.Exit(this);}<BR><BR><BR><BR>  WorkerBegin方法首先增加當(dāng)前活動(dòng)線程的數(shù)量,接著設(shè)置m_started標(biāo)記,最后調(diào)用Pulse方法以通知(可能存在的)等待工作線程啟動(dòng)的線程。如前所述,可能等待Done對(duì)象的方法是WaitBegin方法。每處理完一個(gè)URL,WorkerEnd方法會(huì)被調(diào)用: <BR><BR>public void WorkerEnd(){Monitor.Enter(this);m_activeThreads--;Monitor.Pulse(this);Monitor.Exit(this);}<BR><BR><BR><BR><BR><BR>  WorkerEnd方法減小m_activeThreads活動(dòng)線程計(jì)數(shù)器,調(diào)用Pulse釋放可能在等待Done對(duì)象的線程--如前所述,可能在等待Done對(duì)象的方法是WaitDone方法。 <BR><BR>  結(jié)束語(yǔ):本文介紹了開發(fā)Internet蜘蛛程序的基礎(chǔ)知識(shí),下面提供的源代碼將幫助你進(jìn)一步深入理解本文的主題。這里提供的代碼非常靈活,你可以方便地將它用于自己的程序。<BR><BR>創(chuàng)建智能網(wǎng)絡(luò)蜘蛛——如何使用Java網(wǎng)絡(luò)對(duì)象和HTML對(duì)象(翻譯)<BR>作者:Mark O. Pendergast<BR><BR>原文:http://www.javaworld.com/javaworld/jw-11-2004/jw-1101-spider.html<BR><BR>摘要<BR>你是否想過創(chuàng)建自己的符合特定標(biāo)準(zhǔn)的網(wǎng)站數(shù)據(jù)庫(kù)呢?網(wǎng)絡(luò)蜘蛛,有時(shí)也稱為網(wǎng)絡(luò)爬蟲,是一些根據(jù)網(wǎng)絡(luò)鏈接從一個(gè)網(wǎng)站到另外一個(gè)網(wǎng)站,檢查內(nèi)容和記錄位置的程序。商業(yè)搜索站點(diǎn)使用網(wǎng)絡(luò)蜘蛛豐富它們的數(shù)據(jù)庫(kù),研究人員可以使用蜘蛛獲得相關(guān)的信息。創(chuàng)建自己的蜘蛛搜索的內(nèi)容、主機(jī)和網(wǎng)頁(yè)特征,比如文字密度和內(nèi)置的多媒體內(nèi)容。這篇文章將告訴你如何使用Java的HTML和網(wǎng)絡(luò)類來(lái)創(chuàng)建你自己的功能強(qiáng)大的網(wǎng)絡(luò)蜘蛛。<BR><BR>這篇文章將介紹如何在標(biāo)準(zhǔn)Java網(wǎng)絡(luò)對(duì)象的基礎(chǔ)上創(chuàng)建一個(gè)智能的網(wǎng)絡(luò)蜘蛛。蜘蛛的核心是一個(gè)基于關(guān)鍵字/短語(yǔ)標(biāo)準(zhǔn)和網(wǎng)頁(yè)特征進(jìn)行深入網(wǎng)絡(luò)搜索的遞歸程序。搜索過程在圖形上類似于JTree結(jié)構(gòu)。我主要介紹的問題,例如處理相關(guān)的URL,防止循環(huán)引用和監(jiān)視內(nèi)存/堆棧使用。另外,我將介紹再訪問和分解遠(yuǎn)程網(wǎng)頁(yè)中如何正確是用Java網(wǎng)絡(luò)對(duì)象。<BR><BR>● 蜘蛛示例程序<BR><BR>示例程序包括用戶界面類SpiderControl、網(wǎng)絡(luò)搜索類Spider,兩個(gè)用作創(chuàng)建JTree顯示結(jié)果的類UrlTreeNode和UrlNodeRenderer,和兩個(gè)幫助驗(yàn)證用戶界面中數(shù)字輸入的類IntegerVerifier和VerifierListener。文章末尾的資源中有完整代碼和文檔的璉接。<BR><BR>SpiderControl界面由三個(gè)屬性頁(yè)組成,一個(gè)用來(lái)設(shè)置搜索參數(shù),另一個(gè)顯示結(jié)果搜索樹(JTree),第三個(gè)顯示錯(cuò)誤和狀態(tài)信息,如圖1<BR><BR><BR><BR><BR>圖1 搜索參數(shù)屬性頁(yè)<BR><BR><BR>搜索參數(shù)包括訪問網(wǎng)站的最大數(shù)量,搜索的最大深度(鏈接到鏈接到鏈接),關(guān)鍵字/短語(yǔ)列表,搜索的頂級(jí)主機(jī),起始網(wǎng)站或者門戶。一旦用戶輸入了搜索參數(shù),并按下開始按鈕,網(wǎng)絡(luò)搜索將開始,第二個(gè)屬性頁(yè)將顯示搜索的進(jìn)度。<BR><BR><BR>圖2 搜索樹<BR><BR>一個(gè)Spider類的實(shí)例以獨(dú)立進(jìn)程的方式執(zhí)行網(wǎng)絡(luò)搜索。獨(dú)立進(jìn)程的使用是為了SpiderControl模塊可以不斷更新搜索樹顯示和處理停止搜索按鈕。當(dāng)Spider運(yùn)行時(shí),它不斷在第二個(gè)屬性頁(yè)中為JTree增加節(jié)點(diǎn)(UrlTreeNode)。包含關(guān)鍵字和短語(yǔ)的搜索樹節(jié)點(diǎn)以藍(lán)色顯示(UrlNodeRenderer)。<BR><BR>當(dāng)搜索完成以后,用戶可以查看站點(diǎn)的統(tǒng)計(jì),還可以用外部瀏覽器(默認(rèn)是位于Program Files目錄的Internet Explorer)查看站點(diǎn)。統(tǒng)計(jì)包括關(guān)鍵字出現(xiàn)次數(shù),總字符數(shù),總圖片數(shù)和總鏈接數(shù)。<BR><BR>● Spider類<BR><BR>Spider類負(fù)責(zé)搜索給出起點(diǎn)(入口)的網(wǎng)絡(luò),一系列的關(guān)鍵字和主機(jī),和搜索深度和大小的限制。Spider繼承了Thread,所以可以以獨(dú)立線程運(yùn)行。這允許SpiderControl模塊不斷更新搜索樹顯示和處理停止搜索按鈕。<BR><BR>構(gòu)造方法接受包含對(duì)一個(gè)空的JTree和一個(gè)空的JtextArea引用的搜索參數(shù)。JTree被用作創(chuàng)建一個(gè)搜索過程中的分類站點(diǎn)記錄。這樣為用戶提供了可見的反饋,幫助跟蹤Spdier循環(huán)搜索的位置。JtextArea顯示錯(cuò)誤和過程信息。<BR><BR>構(gòu)造器將參數(shù)存放在類變量中,使用UrlNodeRenderer類初始化顯示節(jié)點(diǎn)的JTree。直到SpiderControl調(diào)用run()方法搜索才開始。<BR><BR>run()方法以獨(dú)立的線程開始執(zhí)行。它首先判斷入口站點(diǎn)是否是一個(gè)Web引用(以http,ftp或者www開始)或是一個(gè)本地文件引用。它接著確認(rèn)入口站點(diǎn)是否具有正確的符號(hào),重置運(yùn)行統(tǒng)計(jì),接著調(diào)用searchWeb()開始搜索:<BR><BR>public void run()<BR>{<BR>DefaultTreeModel treeModel = (DefaultTreeModel)searchTree.getModel(); // get our model<BR>DefaultMutableTreeNode root = (DefaultMutableTreeNode)treeModel.getRoot();<BR>String urllc = startSite.toLowerCase();<BR>if(!urllc.startsWith("http://") &amp;&amp; !urllc.startsWith("ftp://") &amp;&amp;<BR>!urllc.startsWith("www."))<BR><BR>{<BR>startSite = "file:///"+startSite; // Note you must have 3 slashes !<BR><BR>}<BR>else // Http missing ?<BR>if(urllc.startsWith("www."))<BR>{<BR>startSite = "http://"+startSite; // Tack on http:// <BR>}<BR><BR>startSite = startSite.replace('\\', '/'); // Fix bad slashes<BR>sitesFound = 0;<BR>sitesSearched = 0;<BR>updateStats();<BR>searchWeb(root,startSite); // Search the Web<BR>messageArea.append("Done!\n\n");<BR>}<BR><BR>searchWeb()是一個(gè)接受搜索樹父節(jié)點(diǎn)和搜索Web地址參數(shù)的遞歸方法。searchWeb()首先檢查給出的站點(diǎn)是否已被訪問和未被執(zhí)行的搜索深度和站點(diǎn)。SearchWeb()接著允許SpiderControl運(yùn)行(更新界面和檢查停止搜索按鈕是否按下)。如果所有正常,searchWeb()繼續(xù),否則返回。<BR><BR>在searchWeb()開始讀和解析站點(diǎn)以前,它首先檢驗(yàn)基于站點(diǎn)創(chuàng)建的URL對(duì)象是否具有正確的類型和主機(jī)。URL協(xié)議被檢查來(lái)確認(rèn)它是一個(gè)HTML地址或者一個(gè)文件地址(不必搜索mailt和其他協(xié)議)。接著檢查文件擴(kuò)展名(如果當(dāng)前有)來(lái)確認(rèn)它是一個(gè)HTML文件(不必解析pdf或者gif文件)。一旦這些工作完成,通過isDomainOk()方法檢查根據(jù)用戶指定的列表檢查主機(jī):<BR><BR>...URL url = new URL(urlstr); // Create the URL object from a string.<BR>String protocol = url.getProtocol(); // Ask the URL for its protocol<BR>if(!protocol.equalsIgnoreCase("http") &amp;&amp; !protocol.equalsIgnoreCase("file"))<BR>{<BR>messageArea.append(" Skipping : "+urlstr+" not a http site\n\n");<BR>return;<BR>}<BR><BR>String path = url.getPath(); // Ask the URL for its path<BR>int lastdot = path.lastIndexOf("."); // Check for file extension<BR>if(lastdot &gt; 0)<BR>{<BR>String extension = path.substring(lastdot); // Just the file extension<BR>if(!extension.equalsIgnoreCase(".html") &amp;&amp; !extension.equalsIgnoreCase(".htm"))<BR>return; // Skip everything but html files<BR>}<BR><BR>if(!isDomainOk(url))<BR><BR>{<BR><BR>messageArea.append(" Skipping : "+urlstr+" not in domain list\n\n");<BR>return;<BR>}<BR></p>
        </div>
                <div class="content">
          <p align="center"><b>[1]</b> [<a href=/data/2006/0921/article_1570_1.htm>2</a>] </p>
        </div>
                <div class="content">
          <p align="right">責(zé)任編輯 webmaster</p>
        </div>

<div class="mainline">&nbsp;</div>
<div class="maincolumn">
<div class="navadimg">
<script type="text/javascript"><!--
google_ad_client = "pub-4357927283882197";
google_ad_width = 728;
google_ad_height = 90;
google_ad_format = "728x90_as";
google_ad_type = "image";
google_ad_channel = "";
//--></script>
<script type="text/javascript"
  src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</div>
</div>


                <div class="content">
          <p align="left"><b>相關(guān)鏈接</b><br>

?? 快捷鍵說(shuō)明

復(fù)制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號(hào) Ctrl + =
減小字號(hào) Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
国产一区免费电影| 色综合久久久久久久久| 精品国产乱码久久久久久浪潮| 国产福利一区在线| 国产一区二区三区在线观看免费视频 | 色婷婷av一区| 成人精品视频网站| 丝袜美腿成人在线| 一区精品在线播放| 日本韩国一区二区| 欧美在线观看视频一区二区| 久久99蜜桃精品| 一区二区三区在线免费观看| 欧美大片日本大片免费观看| 91成人免费在线| 欧洲视频一区二区| 欧美精品1区2区3区| 色综合色综合色综合| 91免费版pro下载短视频| 国产一区二区不卡在线 | 国产曰批免费观看久久久| 国产资源精品在线观看| 视频一区欧美精品| 全国精品久久少妇| 丝袜诱惑亚洲看片 | 欧美精品v国产精品v日韩精品 | 91精品国产色综合久久ai换脸| 91老师国产黑色丝袜在线| 在线观看日韩av先锋影音电影院| 欧美日韩色一区| 欧美性videosxxxxx| 日韩免费成人网| 国产欧美一区二区精品婷婷| 日韩一区二区在线观看| 欧美蜜桃一区二区三区| 欧美三日本三级三级在线播放| 555夜色666亚洲国产免| 欧美福利一区二区| 久久香蕉国产线看观看99| 亚洲精品一区二区在线观看| 中文无字幕一区二区三区| 欧美一区二区三区性视频| 久久久久久久免费视频了| 久久久久久夜精品精品免费| 亚洲视频电影在线| 夜夜嗨av一区二区三区网页| 蜜臀a∨国产成人精品| 免费观看日韩av| 成人手机电影网| 欧美人妖巨大在线| 国产欧美一区二区精品性色超碰| 伊人性伊人情综合网| 夜夜嗨av一区二区三区四季av| 日本女人一区二区三区| 久久国产精品一区二区| 色综合婷婷久久| 欧美日韩夫妻久久| 日本一区二区久久| 欧美96一区二区免费视频| 成人福利视频在线| 99国产精品久久久久| 在线一区二区视频| 久久青草欧美一区二区三区| 亚洲香蕉伊在人在线观| 日本在线不卡视频| 9i在线看片成人免费| 精品视频1区2区| 中文无字幕一区二区三区 | 亚洲成人你懂的| 日本一区中文字幕| 99精品欧美一区| 久久无码av三级| 日韩精品1区2区3区| 色老汉一区二区三区| 国产日韩欧美一区二区三区乱码 | 成人黄色片在线观看| 欧美一二三区在线| 一区二区三区久久久| 成人黄色软件下载| 久久久夜色精品亚洲| 婷婷亚洲久悠悠色悠在线播放| 精品一区二区在线视频| 成人手机在线视频| 久久视频一区二区| 蜜臀av一区二区三区| 欧美视频完全免费看| 亚洲同性gay激情无套| 欧美成人激情免费网| 欧美激情一区二区三区在线| 麻豆国产精品777777在线| 欧美日韩国产片| 亚洲自拍都市欧美小说| 国产一区二区三区观看| 日韩一区二区免费视频| 婷婷六月综合亚洲| 欧美三级日韩三级| 亚洲一区二区精品久久av| 色婷婷综合激情| 亚洲成人av一区二区三区| 国产精品一区一区三区| 91电影在线观看| 亚洲欧美另类综合偷拍| 国内精品久久久久影院薰衣草| 欧美精品一二三| 午夜精品一区二区三区电影天堂| 欧美在线综合视频| 亚洲午夜在线电影| 欧美日韩中文字幕一区| 亚洲成人一区二区| 欧美三级日本三级少妇99| 日韩精品午夜视频| 欧美一区二区三区免费| 奇米影视在线99精品| 欧美成人免费网站| 国内精品国产三级国产a久久| 精品成人一区二区三区四区| 久久69国产一区二区蜜臀| 久久综合色之久久综合| 粉嫩av一区二区三区| 日韩丝袜美女视频| 久久超碰97中文字幕| 国产午夜精品久久久久久免费视 | 秋霞午夜鲁丝一区二区老狼| 91精品国产免费久久综合| 美国精品在线观看| 26uuu亚洲婷婷狠狠天堂| 岛国一区二区三区| 国产精品久久久久久久久免费丝袜 | 2023国产精品| 粉嫩av亚洲一区二区图片| 1000精品久久久久久久久| 欧美无砖砖区免费| 免费观看日韩av| 国产日韩欧美精品一区| 99久久久久久99| 亚洲va欧美va人人爽| 欧美精品一区二| 91在线精品秘密一区二区| 亚洲一二三四区| 日韩欧美成人一区二区| 成人网页在线观看| 亚洲成a人在线观看| 欧美v亚洲v综合ⅴ国产v| 懂色av一区二区三区免费观看 | 亚洲一区二区三区国产| 欧美一级一级性生活免费录像| 国产一区二区三区蝌蚪| 亚洲视频香蕉人妖| 欧美一区日韩一区| 成人免费va视频| 亚洲第四色夜色| 中文字幕国产一区| 欧美日韩精品一二三区| 粉嫩一区二区三区性色av| 亚洲成人免费在线| 日本一区二区视频在线| 欧美日本一区二区三区四区| 丁香六月久久综合狠狠色| 视频一区视频二区中文字幕| 国产亚洲一区二区三区四区| 欧美日韩国产三级| 成人黄色小视频在线观看| 人人爽香蕉精品| 一区二区三区在线免费视频| 久久亚洲综合色一区二区三区| 91福利在线免费观看| 国产精品资源网| 日产国产高清一区二区三区| 国产精品久久久久三级| 日韩精品资源二区在线| 欧亚一区二区三区| 国产ts人妖一区二区| 美国av一区二区| 亚洲丶国产丶欧美一区二区三区| 中文字幕精品一区| 精品久久久三级丝袜| 欧美色倩网站大全免费| 成人国产精品免费观看视频| 精品一区二区在线免费观看| 亚洲成va人在线观看| 亚洲色图在线播放| 日本一区二区在线不卡| 精品国产精品一区二区夜夜嗨| 欧美午夜影院一区| 99视频超级精品| 风间由美一区二区av101| 九一久久久久久| 舔着乳尖日韩一区| 一区二区三区高清| 亚洲私人影院在线观看| 国产日韩欧美麻豆| 久久众筹精品私拍模特| 欧美va在线播放| 91精品国产综合久久蜜臀| 精品视频一区 二区 三区| 一本一本大道香蕉久在线精品| 成人开心网精品视频| 国产成人免费xxxxxxxx| 国产九九视频一区二区三区| 经典一区二区三区|