分析/解析Html頁面:HTML Parser的試用

          作者:scud(飛云小俠)  http://www.jscud.com  轉載請注明作者來源.否則請勿轉載,謝謝.

          最近在研究lucene的全文檢索,在很多地方需要解析或者說分析Html內容或者Html頁面,Lucene本身的演示程序中也提供了一個Html Parser,但是不是純Java的解決方案.于是到處搜索,在網上找到了一個"HTMLParser".

          網址是: http://htmlparser.sourceforge.net ,當前版本為1.5.

          下載下來,試用一番,感覺不錯,完全能滿足lucene解析Html的需求.

          過幾天貼出lucene進行全文檢索的代碼.(檢索本站的文章等).

          試用代碼如下,供大家參考:

          package com.jscud.test;

          import java.io.BufferedReader;
          import java.io.File;
          import java.io.FileInputStream;
          import java.io.InputStreamReader;

          import org.htmlparser.Node;
          import org.htmlparser.NodeFilter;
          import org.htmlparser.Parser;
          import org.htmlparser.filters.NodeClassFilter;
          import org.htmlparser.filters.OrFilter;
          import org.htmlparser.nodes.TextNode;
          import org.htmlparser.tags.LinkTag;
          import org.htmlparser.util.NodeList;
          import org.htmlparser.util.ParserException;
          import org.htmlparser.visitors.HtmlPage;
          import org.htmlparser.visitors.TextExtractingVisitor;

          import com.jscud.util.LogMan; //一個日志記錄類

          /**
           * 演示了Html Parse的應用.
           *
           * @author scud http://www.jscud.com
           */

          public class ParseHtmlTest
          {

              public static void main(String[] args) throws Exception
              {
                  String aFile = "e:/jscud/temp/test.htm";

                  String content = readTextFile(aFile, "GBK");

                  test1(content);
                  System.out.println("====================================");

                  test2(content);
                  System.out.println("====================================");

                  test3(content);
                  System.out.println("====================================");

                  test4(content);
                  System.out.println("====================================");

                  test5(aFile);
                  System.out.println("====================================");

                  //訪問外部資源,相對慢
                  test5("        System.out.println("====================================");

              }

              /**
               * 讀取文件的方式來分析內容.
               * filePath也可以是一個Url.
               *
               * @param resource 文件/Url
               */
              public static void test5(String resource) throws Exception
              {
                  Parser myParser = new Parser(resource);

                  //設置編碼
                  myParser.setEncoding("GBK");

                  HtmlPage visitor = new HtmlPage(myParser);

                  myParser.visitAllNodesWith(visitor);

                  String textInPage = visitor.getTitle();

                  System.out.println(textInPage);
              }

              /**
               * 按頁面方式處理.對一個標準的Html頁面,推薦使用此種方式.
               */
              public static void test4(String content) throws Exception
              {
                  Parser myParser;
                  myParser = Parser.createParser(content, "GBK");

                  HtmlPage visitor = new HtmlPage(myParser);

                  myParser.visitAllNodesWith(visitor);

                  String textInPage = visitor.getTitle();

                  System.out.println(textInPage);
              }

              /**
               * 利用Visitor模式解析html頁面.
               *
               * 小優點:翻譯了<>等符號
               * 缺點:好多空格,無法提取link
               *  
               */
              public static void test3(String content) throws Exception
              {
                  Parser myParser;
                  myParser = Parser.createParser(content, "GBK");

                  TextExtractingVisitor visitor = new TextExtractingVisitor();

                  myParser.visitAllNodesWith(visitor);

                  String textInPage = visitor.getExtractedText();

                  System.out.println(textInPage);
              }

              /**
               * 得到普通文本和鏈接的內容.
               *
               * 使用了過濾條件.
               */
              public static void test2(String content) throws ParserException
              {
                  Parser myParser;
                  NodeList nodeList = null;

                  myParser = Parser.createParser(content, "GBK");

                  NodeFilter textFilter = new NodeClassFilter(TextNode.class);
                  NodeFilter linkFilter = new NodeClassFilter(LinkTag.class);

                  //暫時不處理 meta
                  //NodeFilter metaFilter = new NodeClassFilter(MetaTag.class);

                  OrFilter lastFilter = new OrFilter();
                  lastFilter.setPredicates(new NodeFilter[] { textFilter, linkFilter });

                  nodeList = myParser.parse(lastFilter);

                  Node[] nodes = nodeList.toNodeArray();

                  for (int i = 0; i < nodes.length; i++)
                  {
                      Node anode = (Node) nodes[i];

                      String line = "";
                      if (anode instanceof TextNode)
                      {
                          TextNode textnode = (TextNode) anode;
                          //line = textnode.toPlainTextString().trim();
                          line = textnode.getText();
                      }
                      else if (anode instanceof LinkTag)
                      {
                          LinkTag linknode = (LinkTag) anode;

                          line = linknode.getLink();
                         
          //@todo 過濾jsp標簽:可以自己實現這個函數
                          //line = StringFunc.replace(line, "<%.*%>", "");
                      }

                      if (isTrimEmpty(line))
                          continue;

                      System.out.println(line);
                  }
              }

              /**
               * 解析普通文本節點.
               *
               * @param content
               * @throws ParserException
               */
              public static void test1(String content) throws ParserException
              {
                  Parser myParser;
                  Node[] nodes = null;

                  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);
                  }

              }

              /**
               * 讀取一個文件到字符串里.
               *
               * @param sFileName  文件名
               * @param sEncode   String
               * @return 文件內容
               */
              public static String readTextFile(String sFileName, String sEncode)
              {
                  StringBuffer sbStr = new StringBuffer();

                  try
                  {
                      File ff = new File(sFileName);
                      InputStreamReader read = new InputStreamReader(new FileInputStream(ff),
                              sEncode);
                      BufferedReader ins = new BufferedReader(read);

                      String dataLine = "";
                      while (null != (dataLine = ins.readLine()))
                      {
                          sbStr.append(dataLine);
                          sbStr.append("\r\n");
                      }

                      ins.close();
                  }
                  catch (Exception e)
                  {
                      LogMan.error("read Text File Error", e);
                  }

                  return sbStr.toString();
              }

              /**
               * 去掉左右空格后字符串是否為空
               * @param astr String
               * @return boolean
               */
              public static boolean isTrimEmpty(String astr)
              {
                  if ((null == astr) || (astr.length() == 0))
                  {
                      return true;
                  }
                  if (isBlank(astr.trim()))
                  {
                      return true;
                  }
                  return false;
              }

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

          }

           


          posted on 2005-08-11 22:31 Scud(飛云小俠) 閱讀(7525) 評論(5)  編輯  收藏 所屬分類: Java

          評論

          # re: 分析/解析Html頁面:HTML Parser的試用 2005-12-25 15:12 t608

          非常好,謝謝發發表  回復  更多評論   

          # re: 分析/解析Html頁面:HTML Parser的試用 2007-04-10 21:59 杜輝

          呵呵
          導師叫我做個網站結構分析
          哈哈
          用上了~
          真心謝謝哦~
            回復  更多評論   

          # re: 分析/解析Html頁面:HTML Parser的試用 2009-05-06 13:44 nn

          good  回復  更多評論   

          # re: 分析/解析Html頁面:HTML Parser的試用 2009-06-09 02:48 杜輝

          你好 我怎么運行不了啊 怎么獲得com.jscud.test這個包啊  回復  更多評論   

          # re: 分析/解析Html頁面:HTML Parser的試用 2011-05-15 15:29 Lingyi

          thanks, i have read it carefully, it really helps!  回復  更多評論   

          <2005年8月>
          31123456
          78910111213
          14151617181920
          21222324252627
          28293031123
          45678910

          導航

          統計

          公告

          文章發布許可
          創造共用協議:署名,非商業,保持一致

          我的郵件
          cnscud # gmail


          常用鏈接

          留言簿(15)

          隨筆分類(113)

          隨筆檔案(103)

          相冊

          友情鏈接

          技術網站

          搜索

          積分與排名

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 贺兰县| 讷河市| 龙岩市| 东丽区| 利川市| 沧州市| 会理县| 奇台县| 平乡县| 石景山区| 乐陵市| 太康县| 安徽省| 全南县| 修武县| 扶余县| 紫云| 清水县| 夏邑县| 丹阳市| 久治县| 南丹县| 永安市| 基隆市| 文登市| 游戏| 漳平市| 名山县| 石景山区| 福州市| 习水县| 精河县| 乌拉特中旗| 凤翔县| 房产| 应用必备| 东乌珠穆沁旗| 饶阳县| 新河县| 旬阳县| 察隅县|