[ Android ] HTML Parser (jericho / jsoup)

2018. 1. 17. 21:34 안드로이드/라이브러리

이번에 HTML 파싱을 할 기회가 있어서 가장 유명한 두 가지 라이브러리를 사용해 보았다.

jar파일은 첨부해 놓은 버전을 사용했다.


jericho 사용법 >

1. HTML이 존재하는 사이트의 주소를 입력하면 source에 담기는데 fullSequentialParse()를 통해 위에서부터 순차적으로 검색을 한다.

Source source = new Source(new URL("사이트주소"));

 

source.fullSequentialParse();


2. 클래스명으로 List에 엘리먼트가 담긴 형태로 데이터를 리턴 받는다.

 

List<Element> divList = source.getAllElementsByClass("클래스");

 

* 아이디도 가능

source.getElementById("id명")


3. 클래스명으로 받아온 리스트에서 div > a > img 순서의 태그가 있다고 가정할때 데이터를 가져오는법

// Element 내에서 필요한 img 태그 경로를 풀어서 src에 있는 이미지 경로를 가져온다.

for(int i = 0; i < divList.size(); i ++)

{

Element tagA = divList.get(i).getAllElements(HTMLElementName.A).get(0);

Element tagImg = tagA.getAllElements(HTMLElementName.IMG).get(0);


Log.d("tagImg""tagImg name : " + tagImg.getAttributeValue("src").toString());

 

}



*OpenSource 분석

Source source = new Source(URL)


  • Source

new EncodingDetector(URL.openconnection())



  • EncodingDetector

new StreamEncodingDetector(URLConnection)


  • StreamEncodingDetector (스트림 인코딩 세팅 클래스)
    • InputStream, contentType, encoding 등을 세팅
    • inputStream=urlInputStream.markSupported() ? urlInputStream : new BufferedInputStream(urlInputStream);(mark() and reset() 지원하는지 여부에 따라InputStream 담을지 BufferedInputStream 담을지 결정)




source.fullSequentialParse();

Tag 단위로 HTML 전체 파싱  list 담음




class 해당하는 Element List 받기

  • List<Element> divList = source.getAllElementsByClass("gallery-item-group");
    • Pattern.compile(".*(\\s|^)"+className+"(\\s|$).*",Pattern.DOTALL);
    • Pattern.compile 사용해서 className  시작하는 태그를 검색해서 해당하는 Element 리스트에 담는다.



Element에서 tag 해당하는 Element 가져오기

Element tagA = divList.get(i).getAllElements(HTMLElementName.A).get(0);

Element tagImg = tagA.getAllElements(HTMLElementName.IMG).get(0);


Element 에서 attribute  가져오기

 

resultList.add(tagImg.getAttributeValue("src").toString());



< jsoup 사용법 >

1. HTML이 존재하는 사이트의 주소를 입력하면 document에 담긴다.

Document document = Jsoup.connect("사이트주소").get();


2. jQuery 와 비슷한 형태로 '.', '>' 등으로 한번에 원하는 데이터들만 뽑을수 있다.

Elements elements = document.select("div.클래스명 > a > img");

System.out.println("elements.size()"elements.size());


3. 클래스명으로 받아온 리스트에서 div > a > img 순서의 태그가 있다고 가정할때 데이터를 가져오는법

// 위에서 뽑은 elements를 이용해 src에 있는 이미지 경로를 가져온다.

for (int i = 0; i < elements.size(); i++) 

{

Log.d("tagImg""tagImg name : " + elements.get(i).attr("src"));

 

}


< 나만의 정리 >

* jsoup 평균 실행시간 테스트 (평균 : 3.641초) 3.161 / 3.450 / 3.298 / 5.296 / 3.219 / 3.617 / 3.449 

 

* jericho 평균 실행시간 테스트 (평균 : 3.482초) 3.832 / 3.591 / 3.268 / 3.440 / 3.025 / 3.614 / 3.581



웹을 잘모르는 나에게는 파싱하기에 jericho가 더 편했다. 늘 익숙한 자바에서 사용하는 형태와 비슷했기 때문이다.

그러나 jsoup에서 element를 가져오는 법이 익숙해지면 jsoup이 조금이나마 더 간단하게 데이터를 가져올수 있을것 같다.

결론은 두 가지 모두 사용성이 편리했고 속도 면에서도 비슷한 모습을 보였다.

어떤 라이브러리가 더 좋다. 라는 평가는 못할것 같다. 본인에게 맞는 라이브러리를 쓰면 될듯 하다.



#라이브러리 사이트

https://jsoup.org/


http://jericho.htmlparser.net/docs/index.html