springboot

[springboot] java로 크롤링 하기 - Jsoup , 네이버 주식 가격 조회 -01

vmpo 2021. 9. 16. 19:56

Java로 크롤링 쉽게 하기

 

Java에서도 Python 처럼 쉽게 크롤링이 가능합니다.

Jsoup 라이브러리를 활용해서 네이버 주식 가격을 조회 해보도록 하겠습니다. 

 

전체 소스는 제일 하단에 공유해드렸습니다.

 

개발환경 : springboot

라이브러리 : Jsoup

 

Jsoup 라이브러리 다운로드

- > java project일 경우 jar 파일을 다운로드 받아서 import 한 후 진행하면 된다.

jsoup: Java HTML parser, built for HTML editing, cleaning, scraping, and XSS safety

 

jsoup: Java HTML parser, built for HTML editing, cleaning, scraping, and XSS safety

jsoup: Java HTML Parser jsoup is a Java library for working with real-world HTML. It provides a very convenient API for fetching URLs and extracting and manipulating data, using the best of HTML5 DOM methods and CSS selectors. jsoup implements the WHATWG H

jsoup.org

 

본 포스팅은 스프링부트 환경이므로 maven or gradle 설정을 해주도록 하겠습니다.

(저는 gradle로 진행하겠습니다.)

 

MAVEN 

<dependency>
  
<groupId>org.jsoup</groupId>
  
<artifactId>jsoup</artifactId>
  
<version>1.14.2</version>
</dependency>

Gradle

implementation 'org.jsoup:jsoup:1.14.2'

 

아래와 같이 gradle 설정을 해주었습니다.

 

아래 네이버 시가총액 순위 가격조회 화면을 크롤링 해보도록 하겠습니다. 빨간색 영역을 조회하도록 하겠습니다.

URL : https://finance.naver.com/sise/sise_market_sum.nhn?&page=1

 

F12 를 눌러서 개발자 도구를 활용해서 html이 어떻게 구성되어있는지 확인해보겠습니다.

조회하고자 하는 영역은 <table>영역으로 <thead> 가 제일 상단 칼럼정보(N,종목명,전일비,,,) <tbody>가 데이터를 담는 row들인 것을 알 수 있습니다. 그럼 해당 영역을 나눠서 조회 해보도록 하겠습니다. 

 

로컬 서버를 띄우지 않고 콘솔창에 크롤링 결과를 출력 해보도록 하겠습니다. 

 

* 전체소스

public class JsoupComponentLocalMain {

  public static void getStockPriceList() {

    final String stockList = "https://finance.naver.com/sise/sise_market_sum.nhn?&page=1";
    Connection conn = Jsoup.connect(stockList);

    try {
      Document document = conn.get();
      String thead = getStockHeader(document); // 칼럼명
      String tbody = getStockList(document);   // 데이터 리스트
      System.out.println(thead);
      System.out.println(tbody);

    } catch (IOException ignored) {
    }
  }

  public static String getStockHeader(Document document) {
    Elements stockTableBody = document.select("table.type_2 thead tr");
    StringBuilder sb = new StringBuilder();
    for (Element element : stockTableBody) {
      for (Element td : element.select("th")) {
        sb.append(td.text());
        sb.append("   ");
      }
      break;
    }
    return sb.toString();
  }

  public static String getStockList(Document document) {
    Elements stockTableBody = document.select("table.type_2 tbody tr");
    StringBuilder sb = new StringBuilder();
    for (Element element : stockTableBody) {
      if (element.attr("onmouseover").isEmpty()) {
        continue;
      }

      for (Element td : element.select("td")) {
        String text;
        if(td.select(".center a").attr("href").isEmpty()){
          text = td.text();
        }else{
          text = "https://finance.naver.com"+td.select(".center a").attr("href");
        }
        sb.append(text);
        sb.append("   ");
      }
      sb.append(System.getProperty("line.separator")); //줄바꿈
    }
    return sb.toString();
  }

  public static void main(String[] args) {
    getStockPriceList();
  }
}

 

상세설명 

 

1.조회할 URL 셋팅 및 Document 객체로드하기

-getStockHeader() -> 칼럼명 정보 조회

-getStockList()   -> 리스트 데이터 조회

  public static void getStockPriceList() {

    final String stockList = "https://finance.naver.com/sise/sise_market_sum.nhn?&page=1";
    Connection conn = Jsoup.connect(stockList);

    try {
      Document document = conn.get();
      String thead = getStockHeader(document); // 칼럼명
      String tbody = getStockList(document);   // 데이터 리스트
      System.out.println(thead);
      System.out.println(tbody);

    } catch (IOException ignored) {
    }
  }

 

2. 칼럼명 정보 파싱

- document.select() 로 html 태그 접근 

-> table.type_2 thead tr

 -tr 태그로 접근했으니, th를 for문으로 각각 조회

  public static String getStockHeader(Document document) {
    Elements stockTableBody = document.select("table.type_2 thead tr");
    StringBuilder sb = new StringBuilder();
    for (Element element : stockTableBody) {
      for (Element td : element.select("th")) {
        sb.append(td.text());
        sb.append("   ");
      }
      break;
    }
    return sb.toString();
  }

 

3. 데이터 정보 파싱

- document.select() 로 html 태그 접근 

-> table.type_2 tbody tr

- tr 태그로 접근했으니, td를 for으로 조회,

- 마지막 td는 토론방 url로 a tag를 통해 접근해야되니깐 별도 분기처리를 해준다.

 

  public static String getStockList(Document document) {
    Elements stockTableBody = document.select("table.type_2 tbody tr");
    StringBuilder sb = new StringBuilder();
    for (Element element : stockTableBody) {
      if (element.attr("onmouseover").isEmpty()) {
        continue;
      }

      for (Element td : element.select("td")) {
        String text;
        if(td.select(".center a").attr("href").isEmpty()){
          text = td.text();
        }else{
          text = "https://finance.naver.com"+td.select(".center a").attr("href");
        }
        sb.append(text);
        sb.append("   ");
      }
      sb.append(System.getProperty("line.separator")); //줄바꿈
    }
    return sb.toString();
  }

 

main 메소드로 출력해보도록 하겠습니다. 

아래와 같이 정상적으로 출력되는 것을 확인 할 수 있습니다.

 

로컬 서버를 띄워 브라우저 호출은 다음 포스팅에서 진행하도록 하겠습니다.

 

전체 소스 코드는 아래 깃허브에 올려두었습니다.

build99k/spring-boot-buildup (github.com)

 

GitHub - build99k/spring-boot-buildup

Contribute to build99k/spring-boot-buildup development by creating an account on GitHub.

github.com

 

LIST