반응형

JSOUP 으로만 웹 크롤링하기는 아래 링크를 참조하세요!

http://derveljunit.tistory.com/280



# 안읽어도 좋은 서론(넋두리)


파이썬으로 웹 크롤러를 만들어보려 예제까지 만들어 보았건만

중대한 문제에 봉착한다.


파이썬의 뷰티풀솝으로 가져온 HTML은 그 html에서 참조하는 또 다른 html을 가져오지 못한다는 것.


왜인지도 모르겠고, 찾기에는 시간이 아까워서 그냥 자바로 만들자고 생각했다 ^^;;;


파이썬이 좋은 점은 C를 활용해서 속도가 빠르다는 것과 간단한 소스 코드, 그리고 범용적인 라이브러리 사용인데, 사실 다른 언어에도 다 라이브러리가 있다. 


소스코드가 복잡하다? 자바도 점점 간략화 되어가고 있다.


오히려 편한 언어가 생산성이 더 좋은 법(이렇게 말하면서 파이썬 툴과 파이썬을 삭제한다. 사실 문법이 마음에 안들어 배우기도 귀찮아...)


그래서 간단한게 만들어보았다.






# 본론(feat. 빈약한 예제)


아파치는 사랑이다.

아파치에서 제공하는 HTTP 라이브러리로 쉽게 HTML을 가져올 수 있다.



사용할 라이브러리는 아파치가 제공하는 http 관련 라이브러리와

DOM을 파싱할 Jsoup 라이브러리


1.  다운로드

 Download 는 https://hc.apache.org/downloads.cgi 에서

최신 버전의 binary형태의 http-core나 http-client 둘중 아무거나 받으면 된다.

받은 압축내에 lib 폴더를 보면 아파치가 친절하게 다 때려 넣어주었다.


 사용할 라이브러리는 

 - commons-logging-1.2.jar

 - httpclient-4.5.2.jar

 - httpcore-4.4.4.jar


 Jsoup은 https://jsoup.org/download 여기서 다운받기




2. 라이브러리 추가

 간략히 소개만. 모르겠으면 구글링

  1) 자바 프로젝트(생짜 프로젝트)는 소스에 라이브러리 추가하고 Build-path 추가

  2) 웹 프로젝트는 WEB-INF / LIB / 밑에 추가 및 Build-path 추가

  3) 스프링 프레임워크는 dependency 추가 -> 자세한 건 구글링 ㄱㄱ




3. 소스 코드 및 예제

 기본적으로 Jsoup 의 Connect 함수를 통해서 데이터를 가져올 수 있지만, 파이썬에서 값을 가져올때와 마찬가지로 진짜 생짜 스크립트와 HTML만 가져온다. 그래서 보조로 httpclient를 통해 가져온 데이터를 Jsoup에 담아서 크롤링을 한다.


package batch;


import java.io.BufferedReader;

import java.io.IOException;

import java.io.InputStreamReader;

import java.nio.charset.Charset;

import java.text.SimpleDateFormat;

import java.util.Date;


import org.apache.http.HttpEntity;

import org.apache.http.HttpResponse;

import org.apache.http.client.ClientProtocolException;

import org.apache.http.client.HttpClient;

import org.apache.http.client.methods.HttpPost;

import org.apache.http.entity.ContentType;

import org.apache.http.impl.client.HttpClientBuilder;

import org.jsoup.Jsoup;

import org.jsoup.nodes.Document;



public class JavaWebCrawler {

public static String getCurrentData(){

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss");

        return sdf.format(new Date());

}

public static void main(String[] args) throws ClientProtocolException, IOException {

// 1. 가져오기전 시간 찍기

System.out.println(" Start Date : " + getCurrentData());

// 2. 가져올 HTTP 주소 세팅

   HttpPost http = new HttpPost("http://finance.naver.com/item/coinfo.nhn?code=045510&target=finsum_more");


   // 3. 가져오기를 실행할 클라이언트 객체 생성

   HttpClient httpClient = HttpClientBuilder.create().build();

   

   // 4. 실행 및 실행 데이터를 Response 객체에 담음

   HttpResponse response = httpClient.execute(http);

   

   // 5. Response 받은 데이터 중, DOM 데이터를 가져와 Entity에 담음

   HttpEntity entity = response.getEntity();

   

   // 6. Charset을 알아내기 위해 DOM의 컨텐트 타입을 가져와 담고 Charset을 가져옴 

   ContentType contentType = ContentType.getOrDefault(entity);

        Charset charset = contentType.getCharset();

        

        // 7. DOM 데이터를 한 줄씩 읽기 위해 Reader에 담음 (InputStream / Buffered 중 선택은 개인취향) 

   BufferedReader br = new BufferedReader(new InputStreamReader(entity.getContent(), charset));

   

   // 8. 가져온 DOM 데이터를 담기위한 그릇

   StringBuffer sb = new StringBuffer();

   

   // 9. DOM 데이터 가져오기

   String line = "";

   while((line=br.readLine()) != null){

    sb.append(line+"\n");

   }

   

   // 10. 가져온 아름다운 DOM을 보자

   System.out.println(sb.toString());

   

   // 11. Jsoup으로 파싱해보자.

   Document doc = Jsoup.parse(sb.toString());

   

   // 참고 - Jsoup에서 제공하는 Connect 처리

   Document doc2 = Jsoup.connect("http://finance.naver.com/item/coinfo.nhn?code=045510&target=finsum_more").get();

//    System.out.println(doc2.data());

   

   

   // 12. 얼마나 걸렸나 찍어보자

   System.out.println(" End Date : " + getCurrentData());

}

}



아래는 실행 결과

Start Date : 2016.07.23 14:36:06





<!--  global include -->



"... dom 구조 및 스크립트 이므로 중략 ..."



</body>

</html>


 End Date : 2016.07.23 14:36:08



대략 2초정도 걸린다.


여기에 크롤링할 데이터에 대한 로직까지 심으면 대략 3~4초 걸리지 않을까 예상해본다.






# 결론

사실 난 Jsoup안 쓰고 문법이 편하고 익숙한 Jquery로 크롤링할거 였는데

Jsoup은 자바로만 처리할 사람이 있을 거 같아 넣어봤다...

자세한 Jsoup을 활용하는 예제는 jsoup 본 사이트를 참조.


httpclient로 jquery까지 html을 가져올 인터페이스 역할만 한다.

dom 파싱하는데에는 jquery 만한게 없다고 본다.


왜냐 내가 익숙하니까...




# 후기

 1. 이글을 쓰고 몇 분뒤에 깨달은 건데 가져오려는 데이터가 안나왔던 이유는 

 iframe 값이었기 때문에 그랬다... 자나깨나 iframe 조심...


 2. python 보다 느리다


반응형

WRITTEN BY
데르벨준

,