posts - 23,comments - 66,trackbacks - 0
          by lostfire

          這兩天準(zhǔn)備做一些網(wǎng)站編程的工作,于是對(duì)HtmlParse小研究了一下,目的是快速入手,而不是深入研究,做了一下整理,和大家共同討論一下。
          ?
          一,數(shù)據(jù)組織分析:

          HtmlParser主要靠Node、AbstractNode和Tag來(lái)表達(dá)Html,因?yàn)镽emark和Text相對(duì)簡(jiǎn)單,此處就將其忽略了。

          • Node是形成樹(shù)結(jié)構(gòu)表示HTML的基礎(chǔ),所有的數(shù)據(jù)表示都是接口Node的實(shí)現(xiàn),Node定義了與頁(yè)面樹(shù)結(jié)構(gòu)所表達(dá)的頁(yè)面Page對(duì)象,定義了獲取父、子、兄弟節(jié)點(diǎn)的方法,定義了節(jié)點(diǎn)到對(duì)應(yīng)html文本的方法,定義了該節(jié)點(diǎn)對(duì)應(yīng)的起止位置,定義了過(guò)濾方法,定義了Visitor訪問(wèn)機(jī)制。
          • AbstractNode是Node的一種具體的類(lèi)實(shí)現(xiàn),起到構(gòu)成樹(shù)形結(jié)構(gòu)的作用,除了同具體Node相關(guān)的accetp方法,toString,toHtml,toPlainTextString方法以外,AbstractNode實(shí)現(xiàn)了大多基本的方法,使得它的子類(lèi),不用理會(huì)具體的樹(shù)操作。
          • Tag是具體分析的主要內(nèi)容。Tag分成composite的Tag和不能包含其他Tag的簡(jiǎn)單Tag兩類(lèi),其中前者的基類(lèi)是CompositeTag,其子類(lèi)包含BodyTag,Div,FrameSetTag,OptionTag,等27個(gè)子類(lèi);而簡(jiǎn)單Tag有BaseHrefTag、DoctypeTag,FrameTag,ImageTag,InputTag,JspTag,MetaTag,ProcessingInstructionTag這八類(lèi)。

          Node分成三類(lèi):

          • RemarkNode:代表Html中的注釋
          • TagNode:標(biāo)簽節(jié)點(diǎn),是種類(lèi)最多的節(jié)點(diǎn)類(lèi)型,上述Tag的具體節(jié)點(diǎn)類(lèi)都是TagNode的實(shí)現(xiàn)。
          • TextNode:文本節(jié)點(diǎn)
          ?
          二,Visitor方式訪問(wèn)Html:
          ?
          1,整體解析過(guò)程
          • 用一個(gè)URL或頁(yè)面String做一個(gè)Parser
          • 用這個(gè)Parser做一個(gè)Visitor
          • 使用Parser.visitAllNodeWith(Visitor)來(lái)遍歷節(jié)點(diǎn)
          • 獲取Visitor遍歷后得到的數(shù)據(jù)
          2,Visit過(guò)程
          • 做解析之前做的事情:visitor.beginParsing();
          • 每次取到一個(gè)節(jié)點(diǎn)Node,讓該Node接受accept該Visitor
          • 做解析后做的事情:visitor.finishedParsing();
          3,獲取節(jié)點(diǎn)的過(guò)程:逐步遍歷Html,分析出Node。此部分較為復(fù)雜,且對(duì)于我們應(yīng)用來(lái)說(shuō)無(wú)需很多了解,暫跳過(guò)。
          ?
          4,節(jié)點(diǎn)訪問(wèn)
          節(jié)點(diǎn)訪問(wèn)采用Visitor模式,Node的accept方法和具體Visitor的visit方法是關(guān)鍵。
          首先三類(lèi)Node來(lái)accept的方式各不相同:
          • 對(duì)于所有TagNode都使用一個(gè)accept方法,即TagNode的accept方法。首先判斷是否是標(biāo)簽結(jié)尾,如果是就visitor.visitEndTag (this);否則visitor.visitTag (this);
          • 如果是TextNode,那就visitor.visitStringNode (this);就可以了。
          • 如果是RemarkNode,那就visitor.visitRemarkNode (this);就可以了。


          實(shí)際上NodeVisitor里邊這四種visit方法都是空的,因?yàn)樵诓煌腣isitor中對(duì)于這三類(lèi)節(jié)點(diǎn)的處理是不同的;對(duì)于需要處理的節(jié)點(diǎn),只要重載對(duì)應(yīng)的visit方法就行了,如果不處理那就不理會(huì)就可以了;另外,如果用戶(hù)用自己的Visitor,那么還可以靈活的處理不同類(lèi)型的節(jié)點(diǎn)了。

          系統(tǒng)為我們實(shí)現(xiàn)了下面我要介紹的8種Visitor,實(shí)際上可以看作是系統(tǒng)給我們演示了如何做各種各樣的Visitor來(lái)訪問(wèn)Html,因?yàn)閷?shí)際上我們要真正來(lái)用HtmlParser的話(huà),還需要特定的Visitor,而通過(guò)簡(jiǎn)單的這些系統(tǒng)提供的Visitor組合是難以做成什么事情的。
          ?
          三,系統(tǒng)Visitor功能簡(jiǎn)介:
          • ObjectFindingVisitor:用來(lái)找出所有指定類(lèi)型的節(jié)點(diǎn),采用getTags()來(lái)獲取結(jié)果。
          • StringBean:用來(lái)從一個(gè)指定的URL獲取移除了<SCRIPT></SCRIPT>和<PRE></PRE>之間代碼的Html代碼,也可以用做Visitor,用來(lái)移除這兩種標(biāo)簽內(nèi)部的代碼,采用StringBean.getStrings()來(lái)獲取結(jié)果。
          • HtmlPage:提取Title,body中的節(jié)點(diǎn)和頁(yè)面中的TableTag節(jié)點(diǎn)。
          • LinkFindingVisitor:找出節(jié)點(diǎn)中包含某個(gè)鏈接的總個(gè)數(shù)。
          • StringFindingVisitor:找出遍歷的TextNode中含有指定字符串的個(gè)數(shù)。
          • TagFindingVisitor:找出指定Tag的所有節(jié)點(diǎn),可以指定多種類(lèi)型。
          • TextExtractingVisitor:從網(wǎng)頁(yè)中把所有標(biāo)簽去掉來(lái)提取文本,這個(gè)提取文本的Visitor有時(shí)是很實(shí)用的,只是注意在提取文本時(shí)將標(biāo)簽的屬性也去掉了,也就是說(shuō)只剩下標(biāo)簽之間的文本,例如<a>中的鏈接也去掉了。
          • UrlModifyingVisitor:用來(lái)修改網(wǎng)頁(yè)中的鏈接。
          四,F(xiàn)ilter
          ?
          如果說(shuō)visitor是遍歷提取信息,當(dāng)然這個(gè)信息可以包括某些節(jié)點(diǎn)或者從節(jié)點(diǎn)分析出來(lái)的更有效的信息,這都取決于我們的Visitor做成什么樣子,那么Filter則目標(biāo)很明確,就是用來(lái)提取節(jié)點(diǎn)的。所以說(shuō)要想用HtmlParser,首先要熟悉上面講到的數(shù)據(jù)組織。
          ?
          系統(tǒng)定義了17種具體的Filter,包括依據(jù)節(jié)點(diǎn)父子關(guān)系的Filter,連接Filter組合的Filter,依據(jù)網(wǎng)頁(yè)內(nèi)容匹配情況的filter,等等。我們也可以implement Filter來(lái)做自己的Filter來(lái)提取節(jié)點(diǎn)。
          ?
          Filter的調(diào)用是同Visitor獨(dú)立的,因?yàn)橐矡o(wú)需先f(wàn)ilter出一些NodeList,再用Visitor來(lái)訪問(wèn)。調(diào)用Filter的方法是:
          NodeList nodeList = myParser.parse(someFilter);
          解析之后,我們可以采用:
          Node[] nodes = nodeList.toNodeArray();
          來(lái)獲取節(jié)點(diǎn)數(shù)組,也可以直接訪問(wèn):
          Node node = nodeList.elementAt(i)來(lái)獲取Node。
          ?
          另外,在Filter后得到NodeList以后,我們?nèi)匀豢梢允褂肗odeList的extractAllNodesThatMatch(someFilter)來(lái)進(jìn)一步過(guò)濾,同時(shí)又可以用NodeList的isitAllNodesWith(someVisitor)來(lái)做進(jìn)一步的訪問(wèn)。
          這樣,我們可以看到HtmlParser為我們提供了非常方便的Html解析方式,針對(duì)不同的應(yīng)用可以采用visitor來(lái)遍歷Html節(jié)點(diǎn)提取數(shù)據(jù),也可以用Filter來(lái)過(guò)濾節(jié)點(diǎn),提取出我們所關(guān)注的節(jié)點(diǎn),再對(duì)節(jié)點(diǎn)進(jìn)行處理。通過(guò)這樣的組合,一定能夠找出我們所需要的信息。
          ?
          參考:
          http://htmlparser.sourceforge.net/
          http://www.aygfsteel.com/rocky/archive/2005/12/21/24997.aspx
          http://www.westing.cn/xblog/?p=90
          posted on 2006-07-02 22:47 rd2pm 閱讀(34215) 評(píng)論(23)  編輯  收藏 所屬分類(lèi): http tool

          FeedBack:
          # re: HtmlParser初步研究
          2006-07-03 10:26 | 艾塵
          這東西不錯(cuò)。一年前用來(lái)做過(guò)項(xiàng)目。可以自定義Tag,還是比較方便。郵件列表也天天更新。  回復(fù)  更多評(píng)論
            
          # re: HtmlParser初步研究
          2006-07-03 13:12 | rox
          暈倒,我正好用過(guò)了,你才寫(xiě)。
          不過(guò),還是感謝你為大家的勞動(dòng)。
          呵呵。  回復(fù)  更多評(píng)論
            
          # re: HtmlParser初步研究
          2006-07-03 14:15 | lostfire
          @rox
          看來(lái)還是有很多人用的,大家都用來(lái)做什么方面的工作啊?  回復(fù)  更多評(píng)論
            
          # re: HtmlParser初步研究
          2006-07-03 15:15 | 老妖
          汗,這個(gè)東西還真的有人用啊!當(dāng)時(shí)只是初步寫(xiě)了一個(gè)應(yīng)急的小demo哦,好久沒(méi)有上blog了,沒(méi)有想到有這么多人捧場(chǎng),頂一下  回復(fù)  更多評(píng)論
            
          # re: HtmlParser初步研究
          2006-07-09 15:56 | pysh@163.com
          htmlParser有好多。我用的是叫什么jericho提供的api。如果你也是歡迎交流一下qq 54171690  回復(fù)  更多評(píng)論
            
          # re: HtmlParser初步研究
          2006-08-18 14:18 | common
          一個(gè)例子就行了。  回復(fù)  更多評(píng)論
            
          # re: HtmlParser初步研究
          2006-10-14 13:18 | czp
          太他媽的志同道和了
          正需要這方面的資料啊




          狂頂!狂頂!狂頂!狂頂!狂頂!狂頂!狂頂!狂頂!狂頂!狂頂!狂頂!狂頂!狂頂!狂頂!狂頂!狂頂!狂頂!狂頂!狂頂!狂頂!狂頂!狂頂!狂頂!狂頂!狂頂!狂頂!狂頂!狂頂!狂頂!狂頂!狂頂!狂頂!狂頂!狂頂!狂頂!狂頂!狂頂!狂頂!狂頂!狂頂!狂頂!狂頂!狂頂!狂頂!狂頂!狂頂!狂頂!狂頂!狂頂!  回復(fù)  更多評(píng)論
            
          # re: HtmlParser初步研究
          2007-01-05 17:38 | ruozhi
          剛接手一個(gè)項(xiàng)目要解析html,先拿它試驗(yàn)一次.QQ:52386348  回復(fù)  更多評(píng)論
            
          # re: HtmlParser初步研究
          2007-02-05 00:50 | 涂萬(wàn)剛
          輝哥!

          我頂  回復(fù)  更多評(píng)論
            
          # re: HtmlParser初步研究
          2007-04-30 14:10 | 雨夜
          剛學(xué)........................  回復(fù)  更多評(píng)論
            
          # re: HtmlParser初步研究
          2007-05-27 09:47 | liu_UFO
          頂哈,我也剛剛開(kāi)始學(xué)習(xí)java ,我的畢業(yè)論文是用java 作,需要解析html,提取論壇里面的文字,正在學(xué)習(xí)htmlparse  回復(fù)  更多評(píng)論
            
          # re: HtmlParser初步研究
          2007-08-26 15:40 | 鄒江
          @liu_UFO


          你好,我想了解下你以前做提取論壇里面的內(nèi)容是怎么提取的,源代碼還有嗎  回復(fù)  更多評(píng)論
            
          # re: HtmlParser初步研究
          2007-10-05 17:55 |
          不錯(cuò),不過(guò)還是有些不全,對(duì)于初學(xué)者來(lái)講還是不太明白,像node里有很多東西都要用到,但沒(méi)有寫(xiě)。
          謝謝,已經(jīng)了解了不少!  回復(fù)  更多評(píng)論
            
          # re: HtmlParser初步研究
          2007-10-28 19:58 | 中華信鴿
          找到了:)  回復(fù)  更多評(píng)論
            
          # re: HtmlParser初步研究
          2007-11-28 11:56 | 北京seo
          不錯(cuò).  回復(fù)  更多評(píng)論
            
          # re: HtmlParser初步研究
          2009-05-03 13:46 | 11
          相當(dāng)不錯(cuò),對(duì)于我這樣的初學(xué)者還是非常有用的。  回復(fù)  更多評(píng)論
            
          # re: HtmlParser初步研究[未登錄](méi)
          2009-11-28 00:43 | dongdong
          你好,我現(xiàn)在在自學(xué)HTMLPARSER和爬蟲(chóng)這里,謝謝你的文章,給我提供了幫助。希望能夠和你成為朋友,向你多多請(qǐng)教。所以。。可以留下一個(gè)聯(lián)系方式么?QQ或郵箱,不勝榮幸。
          我的郵箱是Spirit.dongdong@gmail.com  回復(fù)  更多評(píng)論
            
          # re: HtmlParser初步研究
          2009-12-13 15:32 | hahabk
          來(lái)學(xué)習(xí)了.  回復(fù)  更多評(píng)論
            
          # re: HtmlParser初步研究
          2009-12-25 16:46 | cqyuu
          學(xué)習(xí)了~!謝謝~!  回復(fù)  更多評(píng)論
            
          # re: HtmlParser初步研究
          2010-12-03 10:20 | 火地晉
          樓主知道有css parser嗎  回復(fù)  更多評(píng)論
            
          # re: HtmlParser初步研究
          2011-03-05 18:05 | guolongxin
          你好,我也在做一個(gè)這樣的東西,但是不會(huì),你能把你以前做的發(fā)我看下嗎?謝謝
          我的郵箱490403992@qq.com  回復(fù)  更多評(píng)論
            
          # re: HtmlParser初步研究
          2011-11-21 20:24 | 憂(yōu)傷恛憶
          謝謝樓主,最近正好用到。。。。。。不過(guò)還是有些看不明白。。。。  回復(fù)  更多評(píng)論
            
          # re: HtmlParser初步研究
          2012-04-29 07:40 | newgod
          解析完 http://www.sina.com.cn 要多少毫秒?  回復(fù)  更多評(píng)論
            

          只有注冊(cè)用戶(hù)登錄后才能發(fā)表評(píng)論。


          網(wǎng)站導(dǎo)航:
           

          主站蜘蛛池模板: 宁化县| 安龙县| 新余市| 武汉市| 鄢陵县| 平江县| 吉木萨尔县| 平果县| 嘉义县| 加查县| 绥江县| 泾川县| 雷州市| 阿拉善左旗| 秦皇岛市| 陇川县| 阜南县| 临西县| 宜州市| 喀什市| 获嘉县| 安塞县| 康保县| 青阳县| 乐都县| 枣强县| 枞阳县| 襄樊市| 乐至县| 九龙坡区| 阳泉市| 库伦旗| 沽源县| 和政县| 同仁县| 沈丘县| 阿拉善右旗| 桃园县| 嘉黎县| 南平市| 邻水|