日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > HTML >内容正文

HTML

HTMLParser(一个比较流行的html代码解析、处理开源项目)学习,总结

發布時間:2023/12/18 HTML 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 HTMLParser(一个比较流行的html代码解析、处理开源项目)学习,总结 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
主頁:
http://htmlparser.sourceforge.net/

?HtmlParser初步研究 by lostfire

這兩天準備做一些網站編程的工作,于是對HtmlParse小研究了一下,目的是快速入手,而不是深入研究,做了一下整理,和大家共同討論一下。 一,數據組織分析:

HtmlParser主要靠Node、AbstractNode和Tag來表達Html,因為Remark和Text相對簡單,此處就將其忽略了。

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

Node分成三類:

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


實際上NodeVisitor里邊這四種visit方法都是空的,因為在不同的Visitor中對于這三類節點的處理是不同的;對于需要處理的節點,只要重載對應的visit方法就行了,如果不處理那就不理會就可以了;另外,如果用戶用自己的Visitor,那么還可以靈活的處理不同類型的節點了。

系統為我們實現了下面我要介紹的8種Visitor,實際上可以看作是系統給我們演示了如何做各種各樣的Visitor來訪問Html,因為實際上我們要真正來用HtmlParser的話,還需要特定的Visitor,而通過簡單的這些系統提供的Visitor組合是難以做成什么事情的。 三,系統Visitor功能簡介:
  • ObjectFindingVisitor:用來找出所有指定類型的節點,采用getTags()來獲取結果。
  • StringBean:用來從一個指定的URL獲取移除了<SCRIPT></SCRIPT>和<PRE></PRE>之間代碼的Html代碼,也可以用做Visitor,用來移除這兩種標簽內部的代碼,采用StringBean.getStrings()來獲取結果。
  • HtmlPage:提取Title,body中的節點和頁面中的TableTag節點。
  • LinkFindingVisitor:找出節點中包含某個鏈接的總個數。
  • StringFindingVisitor:找出遍歷的TextNode中含有指定字符串的個數。
  • TagFindingVisitor:找出指定Tag的所有節點,可以指定多種類型。
  • TextExtractingVisitor:從網頁中把所有標簽去掉來提取文本,這個提取文本的Visitor有時是很實用的,只是注意在提取文本時將標簽的屬性也去掉了,也就是說只剩下標簽之間的文本,例如<a>中的鏈接也去掉了。
  • UrlModifyingVisitor:用來修改網頁中的鏈接。
四,Filter 如果說visitor是遍歷提取信息,當然這個信息可以包括某些節點或者從節點分析出來的更有效的信息,這都取決于我們的Visitor做成什么樣子,那么Filter則目標很明確,就是用來提取節點的。所以說要想用HtmlParser,首先要熟悉上面講到的數據組織。 系統定義了17種具體的Filter,包括依據節點父子關系的Filter,連接Filter組合的Filter,依據網頁內容匹配情況的filter,等等。我們也可以implement Filter來做自己的Filter來提取節點。 Filter的調用是同Visitor獨立的,因為也無需先filter出一些NodeList,再用Visitor來訪問。調用Filter的方法是: NodeList nodeList = myParser.parse(someFilter); 解析之后,我們可以采用: Node[] nodes = nodeList.toNodeArray(); 來獲取節點數組,也可以直接訪問: Node node = nodeList.elementAt(i)來獲取Node。 另 外,在Filter后得到NodeList以后,我們仍然可以使用NodeList的extractAllNodesThatMatch (someFilter)來進一步過濾,同時又可以用NodeList的isitAllNodesWith(someVisitor)來做進一步的訪問。 這 樣,我們可以看到HtmlParser為我們提供了非常方便的Html解析方式,針對不同的應用可以采用visitor來遍歷Html節點提取數據,也可 以用Filter來過濾節點,提取出我們所關注的節點,再對節點進行處理。通過這樣的組合,一定能夠找出我們所需要的信息。 參考: http://htmlparser.sourceforge.net/ http://www.blogjava.net/rocky/archive/2005/12/21/24997.aspx http://www.westing.cn/xblog/?p=90


獲取幫助:
?郵件列表:

http://sourceforge.net/mail/?group_id=24399
主頁上的sample:
http://htmlparser.sourceforge.net/samples.html
在發布的包里沒有demo或example文件夾,但是在有些類,比如org.htmlparser.Parser
有public static void main(String[] args)這個方法,其中有一些該類的使用方法。
org.htmlparser.Parser.main(String[] args)中就有Parse a web page and print the tags in a simple loop的方法。這在http://htmlparser.sourceforge.net/samples.html上有說明。
特別的:一個java web start
http://htmlparser.sourceforge.net/samples/filterbuilder.jnlp
幫助認識和使用filter。


一些常見處理:

應用HtmlParser處理含HTML標簽的字符串或網頁

String Extraction

To get all the text content from a web page, use the TextExtractingVisitor, like so:

import org.htmlparser.Parser;
import org.htmlparser.util.ParserException;
import org.htmlparser.visitors.TextExtractingVisitor;
public class StringDemo
{
public static void main (String[] args) throws ParserException
{
Parser parser = new Parser ("http://pageIwantToParse.com");
TextExtractingVisitor visitor = new TextExtractingVisitor ();
parser.visitAllNodesWith (visitor);
System.out.println (visitor.getExtractedText());
}
}

If you want a more browser like behaviour, use the StringBean like so:

import org.htmlparser.beans.StringBean;
public class StringDemo
{
public static void main (String[] args)
{
StringBean sb = new StringBean ();
sb.setLinks (false);
sb.setReplaceNonBreakingSpaces (true);
sb.setCollapse (true);
sb.setURL ("http://pageIwantToParse.com");
System.out.println (sb.getStrings ());
}
}

To get all the text content from a web page you already have in a string:

import org.htmlparser.Parser;
import org.htmlparser.Node;
import org.htmlparser.nodes.TextNode;
import org.htmlparser.util.ParserException;
public class StringDemo
{
public static void main (String[] args) throws ParserException
{
Parser myParser;
Node[] nodes = null;
String content = "";
myParser = Parser.createParser(content, null);

nodes = myParser.extractAllNodesThatAre(TextNode.class); //exception could be thrown here

for (int i = 0; i < nodes.length; i++)
{
TextNode textnode = (TextNode) nodes[i];
String line = textnode.toPlainTextString().trim();
if (line.equals("")) continue;
System.out.println(line);
}
}


http://blog.csdn.net/redez/archive/2005/11/21/534277.aspx
?HTMLParser 使用

最近在研究lucene,主要做ftp搜索和網頁的站內搜索。
ftp搜索比較好做,主流的FTP有兩種一種是IIS的一種是Server-U的.
真對這兩種FTP分別進行分析就可以得到FTP資源的文件名和路徑及大小和日期
然后對其進行索引就可以了,比較簡單。
網頁檢索可不像ftp那樣了,我試著用lucene自帶的htmlparser,解析純英文的網頁
沒有問題,可解析中文的網頁時有時會遇到編碼問題。郁悶。。。
SourceForge搜到了一個開源的HTMLParser。網址是
http://htmlparser.sourceforge.net
目前的版本為1.6。

測試代碼為:

import java.io.*;
import org.htmlparser.filters.*;
import org.htmlparser.*;
import org.htmlparser.nodes.*;
import org.htmlparser.tags.*;
import org.htmlparser.util.*;
import org.htmlparser.visitors.*;


public class HTMLParserTest
{
?public static void main(String args[]) throws Exception
?{
? String path = "D://Webdup//MyWebsites//biti//download//latest//cisco.biti.edu.cn//index.html";
? StringBuffer sbStr = new StringBuffer();
? BufferedReader reader? = new BufferedReader(new FileReader(new File(path)));
? String temp = "";
? while((temp=reader.readLine())!=null)
? {
?? sbStr.append(temp);
?? sbStr.append("/r/n");
? }
? reader.close();
?
?
? String result = sbStr.toString();
?? readAll(result);
??????? readTextAndLink(result);
??????? readByHtml(result);
???? readTextAndTitle(result);
?}
?

?//按頁面方式處理.解析標準的html頁面
?public static void readByHtml(String content) throws Exception
??? {
??????? Parser myParser;
??????? myParser = Parser.createParser(content, "GB2312");

??????? HtmlPage visitor = new HtmlPage(myParser);

??????? myParser.visitAllNodesWith(visitor);

??????? String textInPage = visitor.getTitle();
??????? System.out.println(textInPage);
??????? NodeList nodelist ;
??????? nodelist = visitor.getBody();
??????? System.out.print(nodelist.asString().trim());
?
?
??? }
???
??? //讀取文本內容和標題
?public static void readTextAndTitle(String result) throws Exception
?{
? Parser parser ;
? NodeList nodelist ;
? parser = Parser.createParser(result,"GB2312");
? NodeFilter textFilter = new NodeClassFilter(TextNode.class);
? NodeFilter titleFilter = new NodeClassFilter(TitleTag.class);
? OrFilter lastFilter = new OrFilter();
? lastFilter.setPredicates(new NodeFilter[]{textFilter,titleFilter});
? nodelist = parser.parse(lastFilter);
? Node[] nodes = nodelist.toNodeArray();
? String line ="";
? for(int i=0;i<nodes.length;i++)
? {
?? Node node = nodes[i];
?? if(node instanceof TextNode)
?? {
??? TextNode textnode = (TextNode) node;
??? line = textnode.getText();
?? }
?? else
?? if(node instanceof TitleTag)
?? {
??? TitleTag titlenode = (TitleTag) node;
??? line = titlenode.getTitle();
?? }
?? if (isTrimEmpty(line))
??????????????? continue;
??????????? System.out.println(line);
? }
?}
?
?//分別讀純文本和鏈接
?
?public static void readTextAndLink(String result) throws Exception
?{
? Parser parser;
? NodeList nodelist;
? parser = Parser.createParser(result,"GB2312");
? NodeFilter textFilter = new NodeClassFilter(TextNode.class);
??NodeFilter linkFilter = new NodeClassFilter(LinkTag.class);
? OrFilter lastFilter = new OrFilter();
? lastFilter.setPredicates(new NodeFilter[] { textFilter, linkFilter });
? nodelist = parser.parse(lastFilter);
? Node[] nodes = nodelist.toNodeArray();
? String line ="";
? for(int i=0;i<nodes.length;i++)
? {
?? Node node = nodes[i];
?? if(node instanceof TextNode)
?? {
??? TextNode textnode = (TextNode) node;
??? line = textnode.getText();
?? }
?? else
?? if(node instanceof LinkTag)
?? {
??? LinkTag link = (LinkTag)node;
??? line = link.getLink();
?? }
?? if (isTrimEmpty(line))
??????????????? continue;
??????????? System.out.println(line);
? }
?}
?
?
?
?
?
?public static void readAll(String result) throws Exception
?{
? Parser parser;
? Node[] nodes ;
? parser = Parser.createParser(result,"GB2312");
? nodes = parser.extractAllNodesThatAre(TextNode.class);
?
? //讀取所有的內容節點
? for (int i = 0; i < nodes.length; i++)
??????? {
??????????? TextNode textnode = (TextNode) nodes[i];
??????????? String line = textnode.toPlainTextString().trim();
??????????? if (line.equals(""))
??????????????? continue;
??????????? System.out.println(line);
??????? }
?}
?
?
?/**
???? * 去掉左右空格后字符串是否為空
???? */
??? public static boolean isTrimEmpty(String astr)
??? {
??????? if ((null == astr) || (astr.length() == 0))
??????? {
??????????? return true;
??????? }
??????? if (isBlank(astr.trim()))
??????? {
??????????? return true;
??????? }
??????? return false;
??? }

??? /**
???? * 字符串是否為空:null或者長度為0.
???? */
??? public static boolean isBlank(String astr)
??? {
??????? if ((null == astr) || (astr.length() == 0))
??????? {
??????????? return true;
??????? }
??????? else
??????? {
??????????? return false;
??????? }
??? }

?
}

?


} ? 來源:http://htmlparser.sourceforge.net/wiki/index.php/StringExtraction 參考:http://htmlparser.sourceforge.net/


處理特定tag:
參考:http://sourceforge.net/mailarchive/message.php?msg_id=25aac9fc0704200423h78893925y72cb75136be7330%40mail.gmail.com
package cn.yethyeth.forTest;
思路:建立一個新的NodeVisitor,在其中處理visitTag這個函數(具體原理見上面第一篇文章)

import?org.htmlparser.Parser;
import?org.htmlparser.Tag;
import?org.htmlparser.util.ParserException;
import?org.htmlparser.visitors.NodeVisitor;


public?class?HTMLParserHandleTag?extends?NodeVisitor{
????
public?void?visitTag?(Tag?tag)
????
{
????
if(?tag.getAttribute("class")!=null?){
????System.out.println?(
" "?+?tag.getTagName?()?+?tag.getAttribute("class"));
????}

????}

???
????
public?static?void?main?(String[]?args)?throws?ParserException
????
{
????Parser?parser?
=?new?Parser?("http://bbs.qihoo.com/ttgz/index.html");
????NodeVisitor?visitor?
=?new?HTMLParserHandleTag?();
????parser.visitAllNodesWith?(visitor);
????}

}

更簡單的方法:使用 TagNameFilter , HasAttributeFilter,AndFilter。
TagNameFilter過濾特定名字的tag,
HasAttributeFilter過濾特定名字和值的tag,
AndFilter將多個filter組合起來。
/*
?* TestFilter.java, 2007-5-13 1:22:45.
?*
?* CopyRight (c) 2007-2007, yethyeth ,All rights reserved.
?*
?* This file is licenced under the Apache License.
?*/

package com.bighai.forTest;

import org.apache.commons.lang.StringUtils;
import org.htmlparser.Parser;
import org.htmlparser.Tag;
import org.htmlparser.filters.AndFilter;
import org.htmlparser.filters.HasAttributeFilter;
import org.htmlparser.filters.TagNameFilter;
import org.htmlparser.util.NodeList;
import org.htmlparser.util.ParserException;

public class TestFilter {

??? /**
??? ?* @param args
??? ?* @throws ParserException
??? ?*/
??? public static void main(String[] args) throws ParserException {
??? ??? // TODO Auto-generated method stub
??? ??? Parser parser = new Parser("http://bbs.qihoo.com/ttgz/index.html");
??? ??? AndFilter filter =
??? ??? ??? new AndFilter(
??? ??? ??? ??? ??? new TagNameFilter("div"),
??? ??? ??? ??? ??? ??? new HasAttributeFilter("class","rLCon") );

??? ??? NodeList nodes = parser.parse(filter);

??? ??? for( int i = 0; i < nodes.size(); i++ ){

??? ??? ??? System.out.println(
??? ??? ??? ??? ??? ((Tag)nodes.elementAt(i)).getTagName()+" class="+
??? ??? ??? ??? ??? ((Tag)nodes.elementAt(i)).getAttribute("class") );
??? ??? }
??? }

}

結果:
DIV?class=rLCon


總結

以上是生活随笔為你收集整理的HTMLParser(一个比较流行的html代码解析、处理开源项目)学习,总结的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。