免费视频淫片aa毛片_日韩高清在线亚洲专区vr_日韩大片免费观看视频播放_亚洲欧美国产精品完整版

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費(fèi)電子書(shū)等14項(xiàng)超值服

開(kāi)通VIP
解析HTML文件
解析HTML文件

這里有兩個(gè)為了查找A HREF來(lái)解析HTML文件方法——一個(gè)麻煩的方法和一個(gè)簡(jiǎn)單的方法。

如果你選擇麻煩的方法,你將使用Java的StreamTokenizer類創(chuàng)建你自己的解析規(guī)則。使用這些技術(shù),你必須為StreamTokenizer對(duì)象指定單詞和空格,接著去掉<和>符號(hào)來(lái)查找標(biāo)簽,屬性,在標(biāo)簽之間分割文字。太多的工作要做。

簡(jiǎn)單的方法是使用內(nèi)置的ParserDelegator類,一個(gè)HTMLEditorKit.Parser抽象類的子類。這些類在Java文檔中沒(méi)有完善的文檔。使用ParserDelegator有三個(gè)步驟:首先為你的URL創(chuàng)建一個(gè)InputStreamReader對(duì)象,接著創(chuàng)建一個(gè)ParserCallback對(duì)象的實(shí)例,最后創(chuàng)建一個(gè)ParserDelegator對(duì)象的實(shí)例并調(diào)用它的public方法parse():


UrlTreeNode newnode = new UrlTreeNode(url); // Create the data node
InputStream in = url.openStream(); // Ask the URL object to create an input stream
InputStreamReader isr = new InputStreamReader(in); // Convert the stream to a reader
DefaultMutableTreeNode treenode = addNode(parentnode, newnode);
SpiderParserCallback cb = new SpiderParserCallback(treenode); // Create a callback object
ParserDelegator pd = new ParserDelegator(); // Create the delegator
pd.parse(isr,cb,true); // Parse the stream
isr.close(); // Close the stream
parse()接受一個(gè)InputStreamReader,一個(gè)ParseCallback對(duì)象實(shí)例和一個(gè)指定CharSet標(biāo)簽是否忽略的標(biāo)志。parse()方法接著讀和解碼HTML文件,每次完成解碼一個(gè)標(biāo)簽或者HTML元素后調(diào)用ParserCallback對(duì)象的方法。

在示例代碼中,我實(shí)現(xiàn)了ParserCallback作為Spider的一個(gè)內(nèi)部類,這樣就允許ParseCallback訪問(wèn)Spider的方法和屬性。基于ParserCallback的類可以覆蓋下面的方法:

■ handleStartTag():當(dāng)遇到起始HTML標(biāo)簽時(shí)調(diào)用,比如>A <

■ handleEndTag():當(dāng)遇到結(jié)束HTML標(biāo)簽時(shí)調(diào)用,比如>/A<

■ handleSimpleTag():當(dāng)遇到?jīng)]有匹配結(jié)束標(biāo)簽時(shí)調(diào)用

■ handleText():當(dāng)遇到標(biāo)簽之間的文字時(shí)調(diào)用


在示例代碼中,我覆蓋了handleSimpleTag()以便我的代碼可以處理HTML的BASE和IMG標(biāo)簽。BASE標(biāo)簽告訴當(dāng)處理相關(guān)的URL引用時(shí)使用什么URL。如果沒(méi)有BASE標(biāo)簽出現(xiàn),那么當(dāng)前URL就用來(lái)處理相關(guān)的引用。HandleSimpleTag()接受三個(gè)參數(shù),一個(gè)HTML.Tag對(duì)象,一個(gè)包含所有標(biāo)簽屬性的MutableAttributeSet,和在文件中的相應(yīng)位置。我的代碼檢查標(biāo)簽來(lái)判斷它是否是一個(gè)BASE對(duì)象實(shí)例,如果是則HREF屬性被提取出來(lái)并保存在頁(yè)面的數(shù)據(jù)節(jié)點(diǎn)中。這個(gè)屬性以后在處理鏈接站點(diǎn)的URL地址中被用到。每次遇到IMG標(biāo)簽,頁(yè)面圖片數(shù)就被更新。

我覆蓋了handleStartTag以便程序可以處理HTML的A和TITLE標(biāo)簽。方法檢查t參數(shù)是否是一個(gè)事實(shí)上的A標(biāo)簽,如果是則HREF屬性將被提取出來(lái)。

fixHref()被用作清理大量的引用(改變反斜線為斜線,添加缺少的結(jié)束斜線),鏈接的URL通過(guò)使用基礎(chǔ)URL和引用創(chuàng)建URL對(duì)象來(lái)處理。接著遞歸調(diào)用searchWeb()來(lái)處理鏈接。如果方法遇到TITLE標(biāo)簽,它就清除存儲(chǔ)最后遇到文字的變量以便標(biāo)題的結(jié)束標(biāo)記具有正確的值(有時(shí)網(wǎng)頁(yè)的title標(biāo)簽之間沒(méi)有標(biāo)題)。

我覆蓋了handleEndTag()以便HTML的TITLE結(jié)束標(biāo)記可以被處理。這個(gè)結(jié)束標(biāo)記指出前面的文字(存在lastText中)是頁(yè)面的標(biāo)題文字。這個(gè)文字接著存在頁(yè)面的數(shù)據(jù)節(jié)點(diǎn)中。因?yàn)樘砑訕?biāo)題信息到數(shù)據(jù)節(jié)點(diǎn)中將改變樹(shù)中數(shù)據(jù)節(jié)點(diǎn)的顯示,nodeChanged()方法必須被調(diào)用以便樹(shù)可以更新。

我覆蓋了handleText()方法以便HTML頁(yè)面的文字可以根據(jù)被搜索的任意關(guān)鍵字或者短語(yǔ)來(lái)檢查。HandleText()接受一個(gè)包含一個(gè)子符數(shù)組和該字符在文件中位置作為參數(shù)。HandleText()首先將字符數(shù)組轉(zhuǎn)換成一個(gè)String對(duì)象,在這個(gè)過(guò)程中全部轉(zhuǎn)換為大寫(xiě)。接著在搜索列表中的每個(gè)關(guān)鍵字/短語(yǔ)根據(jù)String對(duì)象的indexof()方法來(lái)檢查。如果indexof()返回一個(gè)非負(fù)結(jié)果,則關(guān)鍵字/短語(yǔ)在頁(yè)面的文字中顯示。如果關(guān)鍵字/短語(yǔ)被顯示,匹配被記錄在匹配列表的節(jié)點(diǎn)中,統(tǒng)計(jì)數(shù)據(jù)被更新:

public class SpiderParserCallback extends HTMLEditorKit.ParserCallback {

/**

* Inner class used to html handle parser callbacks

*/


public class SpiderParserCallback extends HTMLEditorKit.ParserCallback {

/** URL node being parsed */

private UrlTreeNode node;

/** Tree node */

private DefaultMutableTreeNode treenode;

/** Contents of last text element */

private String lastText = "";

/**

* Creates a new instance of SpiderParserCallback

* @param atreenode search tree node that is being parsed
*/

public SpiderParserCallback(DefaultMutableTreeNode atreenode) {

treenode = atreenode;
node = (UrlTreeNode)treenode.getUserObject();

}

/**
* Handle HTML tags that don‘t have a start and end tag
* @param t HTML tag
* @param a HTML attributes
* @param pos Position within file
*/
public void handleSimpleTag(HTML.Tag t,

MutableAttributeSet a,
int pos)

{
if(t.equals(HTML.Tag.IMG))

{
node.addImages(1);
return;
}

if(t.equals(HTML.Tag.BASE))
{
Object value = a.getAttribute(HTML.Attribute.HREF);

if(value != null)
node.setBase(fixHref(value.toString()));
}
}

/**

* Take care of start tags

* @param t HTML tag

* @param a HTML attributes

* @param pos Position within file
*/
public void handleStartTag(HTML.Tag t,

MutableAttributeSet a,

int pos)
{
if(t.equals(HTML.Tag.TITLE))
{

lastText="";
return;

}

if(t.equals(HTML.Tag.A))

{

Object value = a.getAttribute(HTML.Attribute.HREF);
if(value != null)
{
node.addLinks(1);
String href = value.toString();
href = fixHref(href);
try{
URL referencedURL = new URL(node.getBase(),href);
searchWeb(treenode, referencedURL.getProtocol()+"://"+referencedURL.getHost()+referencedURL.getPath());
}
catch (MalformedURLException e)

{
messageArea.append(" Bad URL encountered : "+href+"\n\n"); return;
}
}
}
}
/**
* Take care of start tags
* @param t HTML tag
* @param pos Position within file

*/
public void handleEndTag(HTML.Tag t,
int pos)

{
if(t.equals(HTML.Tag.TITLE) && lastText != null)
{
node.setTitle(lastText.trim());
DefaultTreeModel tm = (DefaultTreeModel)searchTree.getModel();

tm.nodeChanged(treenode);

}

}

/**

* Take care of text between tags, check against keyword list for matches, if
* match found, set the node match status to true
* @param data Text between tags
* @param pos position of text within Webpage
*/
public void handleText(char[] data, int pos)
{

lastText = new String(data);
node.addChars(lastText.length());
String text = lastText.toUpperCase();
for(int i = 0; i < keywordList.length; i++)
{
if(text.indexOf(keywordList) >= 0)
{
if(!node.isMatch())
{
sitesFound++;
updateStats();
}
node.setMatch(keywordList);
return;
}
}
}

}

 引用  報(bào)告 回復(fù)
admin
管理員




UID 1
精華 0
積分 0
帖子 418
閱讀權(quán)限 200
注冊(cè) 2007-5-8
狀態(tài) 離線
發(fā)表于 2007-5-14 12:18  資料  個(gè)人空間  短消息  加為好友 
2、處理和補(bǔ)全URL

當(dāng)遇到相關(guān)頁(yè)面的鏈接,你必須在它們基礎(chǔ)URL上創(chuàng)建完整的鏈接?;A(chǔ)URL可能通過(guò)BASE標(biāo)簽在頁(yè)面中明確的定義,或者暗含在當(dāng)前頁(yè)面的鏈接中。Java的URL對(duì)象為你解決這個(gè)問(wèn)題提供了構(gòu)造器,提供了根據(jù)它的鏈接結(jié)構(gòu)創(chuàng)建相似的。
URL(URL context, String spec)接受spec參數(shù)的鏈接和context參數(shù)的基礎(chǔ)鏈接。如果spec是一個(gè)相關(guān)鏈接,構(gòu)建器將使用context來(lái)創(chuàng)建一個(gè)完整引用的URL對(duì)象。URL它推薦URL遵循嚴(yán)格的(Unix)格式。使用反斜線,在Microsoft Windows中,而不是斜線,將是錯(cuò)誤的引用。如果spec或者context指向一個(gè)目錄(包含index.html或default.html),而不是一個(gè)HTML文件,它必須有一個(gè)結(jié)束斜線。fixHref()方法檢查這些引用并且修正它們:


public static String fixHref(String href)
{

String newhref = href.replace(‘\\‘, ‘/‘); // Fix sloppy Web references

int lastdot = newhref.lastIndexOf(‘.‘);

int lastslash = newhref.lastIndexOf(‘/‘);
if(lastslash > lastdot)
{
if(newhref.charAt(newhref.length()-1) != ‘/‘)
newhref = newhref+"/"; // Add missing /

}
return newhref;

}


3、 控制遞歸

searchWeb()開(kāi)始是為了搜索用戶指定的起始Web地址而被調(diào)用的。它接著在遇到HTML鏈接時(shí)調(diào)用自身。這形成了深度優(yōu)先搜索的基礎(chǔ),也帶來(lái)了兩種問(wèn)題。首先非常危險(xiǎn)的內(nèi)存/堆棧溢出問(wèn)題將因?yàn)樘嗟倪f歸調(diào)用而產(chǎn)生。如果出現(xiàn)環(huán)形的引用,這個(gè)問(wèn)題就將發(fā)生,也就是說(shuō),一個(gè)頁(yè)面鏈接另外一個(gè)鏈接回來(lái)的連接,這是WWW中常見(jiàn)的事情。為了預(yù)防這種現(xiàn)象,searchWeb()檢查搜索樹(shù)(通過(guò)urlHasBeenVisited()方法)來(lái)確定是否引用的頁(yè)面已經(jīng)存在。如果已經(jīng)存在,這個(gè)鏈接將被忽略。如果你選擇實(shí)現(xiàn)一個(gè)沒(méi)有搜索樹(shù)的蜘蛛,你仍然必須維護(hù)一個(gè)以訪問(wèn)站點(diǎn)的列表(在Vector或數(shù)組中)以便你可以判斷是否你正在重復(fù)訪問(wèn)站點(diǎn)。

遞歸的第二個(gè)問(wèn)題來(lái)自深度優(yōu)先的搜索和WWW的結(jié)構(gòu)。根據(jù)選擇的入口,深度優(yōu)先的搜索在初始頁(yè)面的初始鏈接在完成處理以前造成大量的遞歸調(diào)用。這就造成了兩種不需要的結(jié)果:首先內(nèi)存/堆棧溢出可能發(fā)生,第二被搜索過(guò)的頁(yè)面可能很久才被從初始入口眾多的結(jié)果中刪除。為了控制這些,我為蜘蛛添加了最大搜索深度設(shè)置。用戶可以選擇可以達(dá)到的深度等級(jí)(鏈接到鏈接到鏈接),當(dāng)遇到每個(gè)鏈接時(shí),當(dāng)前深度通過(guò)調(diào)用depthLimitExceeded()方法進(jìn)行檢查。如果達(dá)到限制,鏈接就被忽略。測(cè)試僅僅檢查JTree中節(jié)點(diǎn)的級(jí)別。

示例程序也增加了站點(diǎn)限制,用戶來(lái)指定,可以在特定數(shù)目的URL被檢查以后停止搜索,這樣確保程序可以最后停止!站點(diǎn)限制通過(guò)一個(gè)簡(jiǎn)單的數(shù)字計(jì)數(shù)器sitesSearched來(lái)控制,這個(gè)數(shù)字每次調(diào)用searchWeb()后都被更新和檢查。

4、UrlTreeNode和UrlNodeRenderer

UrlTreeNode和UrlNodeRenderer是用來(lái)在SpiderControl用戶界面中創(chuàng)建JTree中個(gè)性化的樹(shù)節(jié)點(diǎn)的類。UrlTreeNode包含每個(gè)搜索過(guò)的站點(diǎn)鐘的URL信息和統(tǒng)計(jì)數(shù)據(jù)。UrlTreeNode以作為用戶對(duì)象屬性的標(biāo)準(zhǔn)DefaultMutableTreeNode對(duì)象形式存儲(chǔ)在JTree中。數(shù)據(jù)包括節(jié)點(diǎn)中跟蹤關(guān)鍵字出現(xiàn)的能力,節(jié)點(diǎn)的URL,節(jié)點(diǎn)的基礎(chǔ)URL,鏈接的數(shù)量,圖片的數(shù)量和字符的個(gè)數(shù),以及節(jié)點(diǎn)是否符合搜索規(guī)則。

UrlTreeNodeRenderer是DefaultTreeCellRenderer界面的實(shí)現(xiàn)。UrlTreeNodeRenderer使節(jié)點(diǎn)包含匹配關(guān)鍵字顯示為藍(lán)色。UrlTreeNodeRenderer也為JtreeNodes加入了個(gè)性化的圖標(biāo)。個(gè)性化的顯示通過(guò)覆蓋getTreeCellRendererComponent()方法(如下)實(shí)現(xiàn)。這個(gè)方法在樹(shù)中創(chuàng)建了一個(gè)Component對(duì)象。大部分的Component屬性通過(guò)子類來(lái)進(jìn)行設(shè)置,UrlTreeNodeRenderer改變了文字的顏色(前景色)和圖標(biāo):


public Component getTreeCellRendererComponent(
JTree tree,
Object value,
boolean sel,
boolean expanded,
boolean leaf,
int row,
boolean hasFocus) {

super.getTreeCellRendererComponent(

tree, value, sel,
expanded, leaf, row,
hasFocus);
UrlTreeNode node = (UrlTreeNode)(((DefaultMutableTreeNode)value).getUserObject());
if (node.isMatch()) // Set color
setForeground(Color.blue);
else
setForeground(Color.black);

if(icon != null) // Set a custom icon
{
setOpenIcon(icon);
setClosedIcon(icon);
setLeafIcon(icon);
}
return this;
}

5、 總結(jié)

這篇文章向你展示了如何創(chuàng)建網(wǎng)絡(luò)蜘蛛和控制它的用戶界面。用戶界面使用JTree來(lái)跟蹤蜘蛛的進(jìn)展和記錄訪問(wèn)過(guò)的站點(diǎn)。當(dāng)然,你也可以使用Vector來(lái)記錄訪問(wèn)過(guò)的站點(diǎn)和使用一個(gè)簡(jiǎn)單的計(jì)數(shù)器來(lái)顯示進(jìn)展。其他增強(qiáng)可以包含通過(guò)數(shù)據(jù)庫(kù)記錄關(guān)鍵字和站點(diǎn)的接口,增加通過(guò)多個(gè)入口搜索的能力,用大量或者很少的文字內(nèi)容來(lái)顯現(xiàn)站點(diǎn),以及為搜索引擎提供同義搜索的能力。

這篇文章中展示的Spider類使用遞歸調(diào)用搜索程序,當(dāng)然,一個(gè)新蜘蛛的獨(dú)立線程可以在遇到每個(gè)鏈接時(shí)開(kāi)始。這樣的好處是允許鏈接遠(yuǎn)程URL并發(fā)執(zhí)行,提高速度。然而記住那些叫做DefaultMutableTreeNode的JTree對(duì)象,不是線程安全的,所以程序員必須自己實(shí)現(xiàn)同步。
本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)。
打開(kāi)APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
html post請(qǐng)求之a(chǎn)標(biāo)簽的兩種用法舉例
影響搜索引擎排名的77個(gè)因素(第1-16,關(guān)鍵字因素)
英文seo專有名詞,中英對(duì)照
HTML <a> 標(biāo)簽
zblog模板修改,模板標(biāo)簽解釋大全
JSTL詳解
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長(zhǎng)圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服