2017년 1월 8일 일요일

jericho htmlparser 사용하기


jericho란

java를 이용해서 html을 파싱할때 사용하는 라이브러리를 말합니다.
아래 링크를 이용해서 jar파일을 받을 수 있습니다.
http://jericho.htmlparser.net/docs/index.html
몇가지 구성 요소들을 이해하면 원하는 부분을 파싱하는데 도움이 됩니다.

Source

가장 기본이 되는 class입니다. 기본이 되는 data를 넣어서 파싱 준비를 하거나 web주소를 입력하여 source instance를 만들어야 합니다. 아래 예 처럼하면 파싱 준비가 된 것입니다.
예)
  String htmlString="<A id=123 href=kk>abc<td id=789>lala</td></a> <a id=456 href=zz>def</a>";
  Source source = new Source(htmlString);
Source source=new Source(new URL("http://www.abc.def.com/"));

Element

html에서 tag들을 Element라고 표현합니다.
예를 들자면 <H1>TITLE</H1> 이때 H1이 element라고 합니다.
심도있는 예제를 만들어 보겠습니다.
htmlString="<a id=123 href=kk>abc<td id=789>lala</td></a> <a id=456 href=zz>def</a>"; 일때
Element 목록들을 담든 메소드는 getAllElemnets(tag name)라는 메소드를 사용합니다. 태그 이름 없이 호출하면 모든 tag들이 목록에 들어옵니다.
리턴값은 element 들이 여러개가 돌아오기 때문에 List형태로 리턴이 됩니다.
List<Element> data=source.getAllElement();
data에는 a, td, a 3개의 tag목록들이 들어오게 됩니다.

package test;

import java.util.List;

import net.htmlparser.jericho.Element;
import net.htmlparser.jericho.Source;

public class Test {
 public static void main(String[] args) {
  test1();
 }
 private static void test1() {
  String htmlString="<A id=123 href=kk>abc<td id=789>lala</td></a> <a id=456 href=zz>def</a>";
  Source source = new Source(htmlString);
  List<Element> els = source.getAllElements();
  System.out.println("Elements size:"+els.size());
  for(int i=0;i<els.size();i++){
   Element el = els.get(i);
   System.out.println(el.getName());
  }
 }
}
결과
Elements size:3
a
td
a

위 예제에서 알 수 있듯이 tag를 대문자와 소문자가 되어 있어도 모두 소문자로 인식됩니다.
List<Element> els로 돌아온 List는 els.get()을 이용해서 각각의 element들을 접근 할 수 있습니다.

원하는 tag만 인식하기


package test;

import java.util.List;

import net.htmlparser.jericho.Element;
import net.htmlparser.jericho.Source;

public class Test {
 public static void main(String[] args) {
  test2();
 }
 private static void test2() {
  String htmlString="<A id=123 href=kk>abc<td id=789>lala</td></a> <a id=456 href=zz>def</a>";
  Source source = new Source(htmlString);
  List<Element> els = source.getAllElements("a");
  System.out.println("Elements size:"+els.size());
  for(int i=0;i<els.size();i++){
   Element el = els.get(i);
   System.out.println(el.getName());
  }
 }
}
결과
Elements size:2
a
a


Attribute

만약 tag의 내용이 <a id=456 href=zz>def</a>이라면 id, href는 attribute가 됩니다.

Attribute value

만약 tag의 내용이 <a id=456 href=zz>def</a>이라면 attribute id의 value는 456이 되며, attribute href의 value는 zz가 됩니다.

package test;

import java.util.List;

import net.htmlparser.jericho.Element;
import net.htmlparser.jericho.Source;

public class Test {
 public static void main(String[] args) {
  test2();
 }
 private static void test2() {
  String htmlString="<A id=123 href=kk>abc<td id=789>lala</td></a> <a id=456 href=zz>def</a>";
  Source source = new Source(htmlString);
  List<Element> els = source.getAllElements("a");
  System.out.println("Elements size:"+els.size());
  for(int i=0;i<els.size();i++){
   Element el = els.get(i);
   System.out.println(el.getName()+" id:"+el.getAttributeValue("id")
    +" href:"+el.getAttributeValue("href"));
  }
 }
}


결과
Elements size:2
a id:123 href:kk
a id:456 href:zz


Content

tag안의 내용을 content라고 합니다.
예를 들어서 <a id=456 href=zz>def</a>라고 한다면 def가 content가 됩니다.
다른 예를 들어보자면 <A id=123 href=kk>abc<td id=789>lala</td></a> A tag의 content는 abc<td id=789>lala</td> 가 됩니다. 즉 내부에 새로운 tag가 중첩될 수도 있습니다.                                  

package test;

import java.util.List;

import net.htmlparser.jericho.Element;
import net.htmlparser.jericho.Source;

public class Test {
 public static void main(String[] args) {
  test2();
 }
 private static void test2() {
  String htmlString="<A id=123 href=kk>abc<td id=789>lala</td></a> <a id=456 href=zz>def</a>";
  Source source = new Source(htmlString);
  List<Element> els = source.getAllElements("a");
  System.out.println("Elements size:"+els.size());
  for(int i=0;i<els.size();i++){
   Element el = els.get(i);
   System.out.println(el.getName()+" id:"+el.getAttributeValue("id")
    +" href:"+el.getAttributeValue("href")+" content:"+el.getContent());
  }
 }
}

결과
Elements size:2
a id:123 href:kk content:abc<td id=789>lala</td>
a id:456 href:zz content:def


Segment


content의 내용에 tag가 있다면 또다시 파싱할 필요가 있게 됩니다. 그래서 파싱을 처음부터 하게 되는데요. getContent 의 리턴값은 Segment라고 불리웁니다. 제일 앞에서 설명한 Source또한 Segment로 부터 상속 받아서 만들어졌기 때문에 Source에서 사용했던 getAllElemnets가 이용이 가능합니다.

package test;

import java.util.List;

import net.htmlparser.jericho.Element;
import net.htmlparser.jericho.Segment;
import net.htmlparser.jericho.Source;

public class Test {
 public static void main(String[] args) {
  test2();
 }
 private static void test2() {
  String htmlString="<A id=123 href=kk>abc<td id=789>lala</td></a> <a id=456 href=zz>def</a>";
  Source source = new Source(htmlString);
  List<Element> els = source.getAllElements("a");
  System.out.println("Elements size:"+els.size());
  for(int i=0;i<els.size();i++){
   Element el = els.get(i);
   System.out.println("tagName:"+el.getName()+" id:"+el.getAttributeValue("id")
    +" href:"+el.getAttributeValue("href")+" content:"+el.getContent());
   Segment seg = el.getContent();
   List<Element> subels = seg.getAllElements();
   for(int j=0;j<subels.size();j++){
    Element subel = subels.get(i);
    System.out.println(" SUB tagName:"+subel.getName()+" id:"+subel.getAttributeValue("id")
    +" href:"+subel.getAttributeValue("href")+" content:"+subel.getContent());
   }
  }
 }
}

결과
Elements size:2
tagName:a id:123 href:kk content:abc<td id=789>lala</td>
SUB tagName:td id:789 href:null content:lala
tagName:a id:456 href:zz content:def















댓글 없음:

댓글 쓰기