프로젝트를 시작하면서 주식 정보를 얻어와야 할 필요가 있어서 크롤링을 통해 주식 정보 데이터를 얻어와야했다.
스프링에서의 크롤링에 대해 구글링 해본 결과 Jsoup라이브러리를 많이 사용하고 내가 원하는 데이터를 가지고 있는 웹사이트에서도 사용이 가능할것 같아 Jsoup라이브러리를 사용하여 크롤링을 시도해 보았다.
Jsoup이란 HTML문서에 저장된 데이터를 구문 분석, 추출 밑 조작하도록 설계된 오픈 소스 Java 라이브러리이다.
build.gradle 의존성 추가
implementation 'org.jsoup:jsoup:1.15.3'
내가 크롤링한 웹사이트
https://finance.naver.com/sise/sise_market_sum.nhn?&page=1
우리가 필요한 데이터는 테이블의 바디에 있는 주식 데이터이다. 그 중에서도 우선 종목명, 현재가, 종목 코드만 크롤링 해보려 한다.
크롤링 코드
package com.project.stocker.util;
import org.jsoup.Connection;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import java.io.IOException;
public class JsoupCrawling {
public static void getStockPriceList() {
final String STOCK_URL = "https://finance.naver.com/sise/sise_market_sum.nhn?&page=1";
Connection conn = Jsoup.connect(STOCK_URL);
try {
Document document = conn.get();
String stockList = getStockList(document);
System.out.println(stockList);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
// table body 에 있는 주식 데이터 가져오기
private 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;
}
String company = element.select("td").get(1).text();
String price = element.select("td").get(2).text();
String id = element.select("td").get(12).select(".center a").attr("href").split("code=")[1];
sb.append(company + " ");
sb.append(price + " ");
sb.append(id);
sb.append(System.getProperty("line.separator")); //줄바꿈
}
return sb.toString();
}
}
1. getStockPriceList
우선 크롤링 하고자 하는 URL으로 STOCK_URL을 초기화 해준 후 해당 URL으로 연결하는 Jsoup.connect()메소드를 호출하여 연결한다. 그리고 연결로 부터 해당 URL의 HTML 문서를 얻어온다.
문서를 얻어온 후에 getStockList()메소드를 통해 해당 문서에서 원하는 데이터를 크롤링 한다.
2. getStockList()
document의 select메소드를 통해 필요한 데이터가 있는 table의 하위 tbody태그의 하위 tr을 Elements로 가져온다.
우선 크롤링이 잘되는지 확인해보기 위해 따로 데이터를 저장하진 않고 출력으로 테스트하기 위해 StringBuilder로 크롤링한 데이터를 만들어 출력해보겠다.
앞서 가져온 Elements를 for-each로 돌면서 데이터를 뽑아낼것이다. Elements는 테이블 바디의 tr태그들인데 해당 html파일에는 tr태그여도 5종목 마다 구분선을 위한 tr태그들이 존재한다. 때문에 onmouseover속성이 없는 태그들은 무시하겠다.
원하는 데이터가 있는 tr태그안에 td태그로 N, 종목명, 현재가 등등이 나열되어 있는데 tr태그인 element를 .select("td")를 통해 td태그들로 접근할 수 있고 .get(index)로 해당 index의 td태그로 접근하여 .text()를 통해 종목명, 현재가를 가져올 수 있다.
종목코드의 경우 td태그들 중 13번째 td태그의 center클래스의 a태그의 href속성값에 있다.
다음과 같이 href 속성의 값으로 /item/board.naver?code={종목코드} 형식으로 되어있는데 이를 .split()메소드를 활용하여 "code="을 기준으로 나누어 1번째 인덱스에 있는 문자열을 가져왔다.
실행 결과
'백엔드(Back End) > Spring' 카테고리의 다른 글
[TIL]20230818 - Redis 캐싱 전략 (0) | 2023.08.21 |
---|---|
[TIL]20230809 - JPA save()와 saveAll()의 차이 (0) | 2023.08.11 |
[TIL]20230728 - 팔로우 기능 구현 (1) | 2023.07.31 |
[TIL]20230727 - Mockito (0) | 2023.07.28 |
[TIL]20230726 - 테스트 코드 작성 (0) | 2023.07.28 |