[JAVA] Jsoup으로 HTML 파싱하기

프로필

2017. 3. 22. 0:49

이웃추가

안녕하세요!


이번 포스팅에서는
Jsoup 라이브러리를 이용하여

HTML을 파싱해보도록 하겠습니다.


파싱이란?
내가 원하는대로 데이터를 가공/변환하는 것입니다.



HTML 파싱은
HTML 소스를 얻어온 후 내가 원하는 부분만 추출하는 목적으로
널리 쓰입니다.



자바에서는 여러 라이브러리가 있지만
이번 포스트에서는 jsoup 이라는 라이브러리를 사용할겁니다.
"이클립스" 환경에서 작업합니다.

사용법이 간단하고 인기가 많은 파서(Parser) 이죠
라이브러리를 먼저 다운받읍시다.

위 사이트에 접속하신 후 jar 파일을 다운받습니다.


Download ths jsoup jar에서 원하는 경로에 다운받습니다.
라이브러리가 준비되었으니 프로젝트에 추가해봅시다





자바 프로젝트를 하나 만듭시다.
또는 기존의 자바 프로젝트에서 진행하셔도 됩니다.
프로젝트를 생성했으면, 프로젝트 폴더에 우클릭

프로젝트 폴더 우클릭 - Build Path - Configure Build Path.. 선택

Add External JARs 버튼을 누른 후, 방금 다운받은 jar파일을 추가해주고
확인버튼을 눌러서 설정을 마칩니다.


이제 추가되었으니 사용만 하면 됩니다!


예제를 통해 간단히 알아볼건데요!
로또 번호 파싱을 해보도록 하겠습니다.


http://www.nlotto.co.kr/common.do?method=main

위 링크가 나눔로또 홈페이지입니다.
본격적으로 시작하기전에 메모를 조금 해봅시다.


사이트에 접속한후 F12 키를 누릅니다.
(크롬 기준)

그럼 우측에 페이지의 HTML 소스코드가 보입니다.

여기서 원하는 부분을 먼저 찾아봅시다.

좌측에 로또번호 영역이 파랗게 변한거 보이시나요?
HTML 코드를 펼치고 훑어보면서 찾아나갑니다.

로또 번호부분 영역을 찾았습니다!

이제 펜이나 스마트폰에 메모합시다.


위에서 찾아낸 영역의 소스입니다.
Body태그안에 곂치고 쌓여서 만들어져있죠.

우리가 필요한부분은 img태그의 alt속성값입니다.
3, 12, 33, 36, 43, 45, 25
로또 번호들인데요

img태그는 p태그 안에 감싸져있습니다.
p태그의 id는 nuwView 이고 클래스이름은 lotto_num 입니다.

메모해둡시다.



이제 이클립스로 돌아와서 코딩을하면 됩니다.
시작하기전에 앞서 Jsoup의 간단한 사용법을 알려드리겠습니다.

Document 형태의 객체에 해당 웹사이트 주소를 connect하여 소스파일을get 합니다. 

예를들어 Document doc;

doc라는 Document가 생겼습니다.
doc.connect("www.naver.com").get();
이렇게 작성하면 네이버의 HTML 코드가 doc에 저장이 됩니다.

이제 이 doc에서 원하는 부분만 추출하면 됩니다.
원하는 부분만 걸러내면 Elements 형태의 객체에 저장해야합니다.

걸러낸것을 저장할공간을 만들어줍니다.

Elements contents;
contents에 doc에서 추출한데이터를 집어넣을겁니다.

먼저 추출하는 방법은 select(); 를 사용합니다.

doc에 저장된 HTML파일에서 클래스이름, id이름, 태그위치등.. 을
지정하여 그부분만 빼올수 있습니다.

<div class="test_class"> 라고 HTML 코드상에
있다고 가정합시다.

div태그이면서 class이름이 test_class 인 데이터를 뽑아오려면
select(".test_class");

이렇게 작성하면 해당 부분을 반환합니다.
클래스 이름으로 추출하려면
.클래스이름

이렇게 하시면 되구요


id이름으로 하고싶다! 그렇다면
#id이름
이렇게 하시면 됩니다.


그리고 해당 태그의 속성값을 가져오고싶다! 하시는분은
위 그림의 두번째 상황을 보시면 됩니다.

먼저 그 부분을 추출할 후 contents에 저장하고
contents.attr("태그이름");
이렇게 작성하면
해당 태그의 값이 반환됩니다.

alt속성, src속성 등등.. 다 됩니다.



말로 설명하니 무슨소린지 못알아들으실텐데요
코드를 작성하면서 알아봅시다.

저는 메인메소드가 있는 클래스와 파싱을 하는 클래스를 나누었습니다.

LottoNum이라는 클래스가 바로 파싱을 하는 부분입니다.
아래에서 자세히 진행합니다.



저는 먼저 LottoNum 이라는 클래스를 만들었습니다.

클래스 안에는 생성자와 GetNumber라는 메소드가 있죠.
GetNumber 메소드 안에 로또 번호를 수집하고  출력하도록 할겁니다.


실행 순서는
생성자 호출(public LottoNum) - GetNumber 호출 - 결과출력 - 
만약 예외발생시 Error! 출력


try / catch 를 알고싶으시면 검색해보도록 하세요
try부분을 시도하고 시도했을 때 예외가 던져지면 catch 부분에서 잡고
catch 부분의 코드를 실행합니다. (예외 미발생시 그냥 지나감)

GetNumber 메소드의 첫번째 줄에
Document doc가 생성되어있습니다.

doc에는 Jsoup.connect("url").get(); 의 데이터가
대입되고있죠

url은 나눔로또 홈페이지가 적혀있습니다.
나눔로또 홈페이지에 접속하여 HTML 코드를 가져와라!
이뜻입니다.

가져온 HTML 코드가 doc 안에 들어있는거죠
그 아랫줄에는 doc를 출력하고있습니다.


결과

HTML 소스가 잘 저장되어있네요.
이제 doc에서 필요한 부분만 파싱합시다.

contents 를 만든 후 doc.select(); 로

p태그이면서 클래스이름이 lotto_num인 데이터를 뽑아오고 있습니다.
그 아래는 뽑아온 데이터를 출력하는 모습이구요.

아까 위에서 메모했던 부분중에 클래스 이름이 lotto_num인
부분이 있었죠? 그 안의 데이터만 저장됩니다.

 
<p class="lotto_num"...>
으로 싸여있는 부분만 추출된 모습입니다.


테스트를 위해 진행해보았고
우리가 필요한 부분은 img태그의 alt 속성값입니다.

alt 속성값에 로또 번호가 적혀있거든요

위 HTML 코드에서 img태그 안의 alt값을 파싱하려면,
img태그의 id값을 통해 접근하면 됩니다.
drwtNo1 ~ drwtNo6 까지의 id의 alt값에 6개의 번호가 있고,
보너스 번호는 id가 bnusNo 입니다.

이제 소스를 수정합니다.

source_id는 클래스에 String sourcr_id; 로 선언되어있습니다.
for문을 1부터 6까지 반복하여

"#drwtNo"+i
를 진행합니다.

i값이 #drwtNo 뒤에 붙어서 새 문자열을 만듭니다.

contents = doc.select(source_id);
위에서 만들어진 id값 문자열을 select에 전달합니다.

select는 해당 id를 탐색하여 찾은 후 그부분을 반환합니다.
contents에는 해당 id 부분이 들어가있습니다.

출력부분에서
contents.attr("alt");
는 속성이 alt인 값을 반환하라는 뜻입니다.

HTML코드에서 로또번호는 alt속성값에 들어가 있으므로 alt 속성값을
구하면 끝!

위 과정을 6번 반복합니다.
id가
#dwrtNo1
#dwrtNo2
#dwrtNo3
#dwrtNo4
#dwrtNo5
#dwrtNo6

인 부분의 alt속성값을 출력합니다.

그리고 보너스번호는 id값이 조금 다르므로
따로 출력합니다.

contents = doc.select("#bnusNo");
contents.attr("alt");

id가 bnusNo인 부분을 가져온 후 해당 부분의 alt속성값을 출력합니다.


여기까지 마치면 1~6번의 로또 번호와 보너스 번호까지 출력이
완료되었습니다.




비교해봅시다.

잘 작동하죠?



파싱에 대해 꼭 알아둡시다!! 



소스코드

//TestMain.class public class TestMain { public static void main(String[] args){ new LottoNum(); } }



//LottoNum.class import org.jsoup.Jsoup; import org.jsoup.nodes.Document; import org.jsoup.select.Elements; public class LottoNum { private String source_id; public LottoNum(){ try { GetNumber(); } catch (Exception e) { System.out.println("Error!"); } } public void GetNumber() throws Exception{ Document doc = Jsoup.connect("http://www.nlotto.co.kr/common.do?method=main").get(); Elements contents; for(int i=1; i<=6; i++){ source_id = "#drwtNo"+i; contents = doc.select(source_id); System.out.println("["+i+"] : "+contents.attr("alt")); } contents = doc.select("#bnusNo"); System.out.println("[B] : "+contents.attr("alt")); } }





여기까지가 Jsoup으로 HTML 파싱하는 방법이었습니다..!!!

안드로이드에서도 적용이 가능하구요
급식정보 불러오기, 실시간검색어 불러오기 등등.. 웹페이지의 데이터를 언제든지 원하는 부분만 파싱하여 보여줄 수 있게되었습니다~!



자주 사용한다고 하니 꼭 알아두세요..!

근둥
근둥 IT·컴퓨터

블로그 이전했습니다. 공지사항을 확인해주세요~ 메일: dev.ghlee@gmail.com (블로그 판매, 임대, 포스팅 대행 등 모든 연락 차단합니다.)