Notice
Recent Posts
Recent Comments
Link
«   2024/04   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
Archives
Today
Total
04-19 10:21
관리 메뉴

zyint's blog

Java Swing HTML Parser 본문

예전글들

Java Swing HTML Parser

진트­ 2008. 10. 3. 22:40

Java Swing HTML Parser#

http://java.sun.com/products/jfc/tsc/articles/bookmarks/

 

기본 HTML 파싱 버전#

자바 스윙에서 제공하는 파서는 HTML 3.2 DTD를 기본으로 파싱한다.

다른 버전의 HTML 파싱 방법 [1] #

스윙의 기본 파싱 DTD인 HTML 3.2로는 제대로 파싱이 되지 않는 경우가 발생할 수 있다. 이를 해결하고자, 다른 버전의 DTD를 지정함으로써 파싱을 할 수 있다.

  1.  public static class ParserHTML extends ParserDelegator
     {
      /**
         *
         */
      private static final long serialVersionUID = -4814411384900651146L;
      private static DTD dtd = null;
  2.   public ParserHTML()
      {
       setDefaultDTD();
      }
  3.   protected static synchronized void setDefaultDTD()
      {
       if (dtd == null)
       {
        DTD _dtd = null;
        String nm = "html32";
  4.     try
        {
         _dtd = DTD.getDTD(nm);
        } catch (IOException e)
        {
         System.out.println("Throw an exception: could not get default dtd: "
           + nm);
        }
  5.     dtd = createDTD(_dtd, nm);
       }
      }
  6.   public void parse(Reader r, HTMLEditorKit.ParserCallback cb, boolean ignoreCharSet)
        throws IOException
      {
       new DocumentParser(dtd).parse(r, cb, ignoreCharSet);
      }
     };

 를 만들어, DTD(bdtd 확장자)를 업데이트 하여 사용할수 있다. 그러면 원하는 결과를 얻을수 있다.
그런데, 문제는 해당 DTD를 구하기가 쉽지 않다는 것이다.

아래 html401.bdtd 파일을 첨부한다. 이 파일을 사용하기 위해서는 classpath가  
     javax/swing/text/html/parser/dtds
에 저장되어 있어야 DTD.getDTD()를 통해 얻을수 있다.

그러나, HTML 4.01를 사용할경우, HTML 3.2 사용시 문제가 되지 않았던 부분에 문제가 발생되는
경우가 있다.   첨부한 html401.bdtd는 Sun에서 배포한 버젼이 아니라, 인터넷을 돌아 다니다 우연히
발견한 것으로 기본으로 포함된 html32.bdtd에 비해 좋은 분석 결과를 얻어 내지는 못하였다.
(기본 Java패키지에는 포함 안되어 있음)

 html401.bdtd

 

웹페이지 파싱 예제#

HTML 코드를 읽어 파싱한 결과대로 화면에 출력해주는 코드

 


  1. import javax.swing.text.html.HTMLEditorKit;
    import javax.swing.text.html.HTML;
    import java.io.InputStreamReader;
    import java.net.URL;
    import java.net.HttpURLConnection;
    import java.util.Enumeration;
  2. import javax.swing.text.BadLocationException;
    import javax.swing.text.MutableAttributeSet;
    import javax.swing.text.html.HTML.Tag;
    import javax.swing.text.html.parser.ParserDelegator;
  3. public class HTMLParsing
    {
  4.  //파서는 콜백 형식으로 되어 있다. 각 태그가 들어 올때 적절한 메소드가 호출됨
     private class CallbackHandler extends HTMLEditorKit.ParserCallback
     {
      @Override
      public void flush() throws BadLocationException
      {
       System.out.println("flush");
      }
  5.   @Override
      public void handleComment(char[] data, int pos)
      {
       System.out.println("Cmt " + new String(data));
      }
  6.   @Override
      public void handleEndOfLineString(String eol)
      {
       System.out.println("EOL ");
      }
  7.   @Override
      public void handleEndTag(Tag t, int pos)
      {
       System.out.println("End </" + t + ">");
      }
  8.   @Override
      public void handleError(String errorMsg, int pos)
      {
    //   System.out.println("ERROR\t" + new String(errorMsg));
      }
  9.   @Override
      public void handleSimpleTag(Tag t, MutableAttributeSet a, int pos)
      {
       System.out.print("Sim <" + t.toString() + ">\n");
       for (Enumeration e = a.getAttributeNames(); e.hasMoreElements();)
       {
        Object attributeName = e.nextElement();
        System.out.print("\t" + attributeName + "=");
        System.out.println(a.getAttribute(attributeName));
       }
      }
  10.   @Override
      public void handleStartTag(Tag t, MutableAttributeSet a, int pos)
      {
       System.out.println("Str <" + t + ">");
       for (Enumeration e = a.getAttributeNames(); e.hasMoreElements();)
       {
        Object attributeName = e.nextElement();
        System.out.print("\t" + attributeName + "=");
        System.out.println(a.getAttribute(attributeName));
       }
      }
  11.   public void handleText(char[] data, int pos)
      {
       System.out.println("\t\t" + new String(data));
      }
     }
  12.  public void parse(String str)
     {
  13.   try
      {
       //입력받은 URL에 연결하여 InputStream을 통해 읽은 후 파싱 한다.
       URL url = new URL(str);
  14.    HttpURLConnection con = (HttpURLConnection) url.openConnection();
  15.    InputStreamReader reader =
         new InputStreamReader(con.getInputStream(), "euc-kr");
  16.    new ParserDelegator().parse(reader, new CallbackHandler(), true);
  17.    con.disconnect();
      } catch (Exception e)
      {
       e.printStackTrace();
      }
     }
  18.  public static void main(String[] args)
     {
      HTMLParsing parser = new HTMLParsing();
      parser.parse("http://www.daum.net");
     }
    }

 

미리 선언된 태그로 확인 방법#

HTML.TAG에 미리 선언된 태그목록을 통해 콜백 함수로 받은 태그를 확인할 수 있다.

  1. //DIV 태그를 확인하는 경우
  2. public void handleStartTag(Tag t, MutableAttributeSet a, int pos)
  3. {
  4. if(t == HTML.Tag.DIV)
  5. {
  6. ...
  7. }
  8. }

 

 

 

참고자료#

(1) a http://symlink.tistory.com/19

 

 

 

이 글은 스프링노트에서 작성되었습니다.

Comments