[Spring] Jsoup를 사용한 html 파싱
👩💻 Jsoup
📌Jsoup
✏️ Jsoup란?
: Jsoup에 대해 알아보자
Jsoup란 html 문서의 String을 넘겨주면 Java Dom 객체 형식으로 변환시켜 Html에 저장된 데이터를 추출할 수 있는 Java 오픈소스 라이브러리이다.
✏️ Jsoup의 주요 요소
: Jsoup의 주요 요소는 크게 다섯가지로 볼 수 있다
| 클래스 명 | 설명 |
| Document | Jsoup 얻어온 결과 HTML 전체 문서 |
| Element | Document의 HTML 요소 |
| Elements | Element가 모인 자료형. for & while 등 반복문 사용이 가능 |
| Connection | Jsoup의 connect 혹은 설정 메소드들을 이용해 만들어지는 객체. 연결을 하기 위한 정보를 담고 있음 |
| Response | Jsoup가 URL에 접속해 얻어온 결과. Document와 다르게 status 코드, status Message, charset같은 헤더 메시지와 쿠키등을 가지고 있음 |
Jsoup로 하는 작업은 크게 보았을 때, Connection 객체를 통해 URL에 접속하고(혹은 로컬 파일/ 문자열), Response 객체에서 세션 ID같은 쿠키와 HTML Document를 얻어낸 후, Document의 Element들을 파싱하는 과정으로 나누어진다.
✏️ Jsoup 사용방법
: Jsoup를 사용해보자!
1️⃣ jsoup 다운로드 받은 뒤, 라이브러리 추가
Download and install jsoup
Download and install jsoup jsoup is available as a downloadable .jar java library. The current release version is 1.17.2. What's new See the 1.17.2 release announcement for the latest changes, or the changelog for the full history. Previous releases of jso
jsoup.org


:다운받은 Jsoup 라이브러리를 intelliJ의 Project Structure(commend + ;)를 통해 추가해주자
Project Structure(단축키: commend + ;)
-> Modules
-> main
-> Dependencies
-> + 클릭
-> JARs or Directories... 클릭
-> 다운로드 받은 jsoup-1.15.3.jar 추가
2️⃣ 파싱 할 대상 페이지 찾기
라이브러리 추가 이후 파싱할 대상 페이지를 찾아주었다.
나는 진행중인 프로젝트에서 사용하기 위해 프로젝트 주제와 유사한 "네이버 뉴스" 페이지를 파싱하기로 하였다.
https://news.naver.com/section/100
정치 : 네이버 뉴스
국회, 행정, 국방, 외교 등 정치 분야 뉴스 제공
news.naver.com

위의 웹 사이트에서 "헤드라인 뉴스"의 뉴스들을 파싱하고 싶었다 !
3️⃣ 웹 크롤링

페이지 소스를 열어 요소를 확인해보니 헤드 라인 뉴스의 class명이 "sa_list"인 것을 확인할 수 있었다.
네이버 뉴스의 헤드라인 뉴스의 제목들을 가져오는 코드를 작성해보자 ~!!

final String url = "https://news.naver.com/section/100";
-> url이라는 변수를 선언하고 네이버 뉴스 정치 섹션의 URL로 초기화
Connection conn = Jsoup.connect(url);
-> Jsoup 라이브러리를 사용하여 해당 url에 연결을 설정하는 conn 객체를 생성
Document document = conn.get();
-> conn 객체를 사용해서 url의 HTML 문서를 가져와 'document' 객체에 저장
Elements news = document.getElementsByClass("sa_list");
-> document 객체에서 Class 이름이 "sa_list"인 모든 HTML 요소들을 찾아 news라는 Elements 객체에 저장
Elements title = document.select("a.sa_text_title > strong.sa_text_strong");
-> document 객체에서 CSS 선택자 "a.sa_text_title > strong.sa_text_strong"에 해당하는 모든 요소를 선택하여
title 객체에 저장. 이 선택자는 <a> 태그 내부의 <strong> 태그를 가리킴
이어서 네이버 헤드라인 뉴스에 뜨는 뉴스들의 언론사들을 가져오는 코드를 작성해보자~!


근데 헤드라인 뉴스제목과 같이 코드를 작성하니, 언론사 데이터만 추출하고싶은데 다른 코드까지 같이 뜨는 것을 확인할 수 있었다.


trim()을 사용해서 앞 뒤 공백을 제거한 뒤, 출력해보니 아까와같이 다른 태그가 같이 나오지않고 언론사 명만 추출된 것을 확인할 수 있었다 !

위의 코드들을 합쳐서 출력해보면 위와같이 출력되는 것을 볼 수 있었다 ~!~!~! 이제 위의 코드를 사용해서 JPA를 통해 db에 파싱한 데이터들을 저장해보자 !
📌웹 크롤링을 통해 수집한 데이터를 DB에 저장해보자
✏️ Entity 생성
: 네이버 뉴스에서 가져올데이터를 담을 Entity를 생성하자

- String title: 뉴스기사 제목
- String company: 뉴스기사 언론사
- String newsURL: 상세 뉴스 기사 주소
✏️ Repository 생성

✏️ Service 생성


title에 news 제목, news에 언론사, newsUrl에 뉴스 상세 페이지 url을 각각 파싱해서 집어넣고 , 세개의 요소 갯수가 하나라도 다를 시, 에러를 발생하도록 작성했다.
이후 for문을 돌려서 Headline 객체를 생성하고 title,company,newsURL의 값을 각각 set으로 값을 넣어준뒤 headLineRepository.save()를 통해서 db에 저장되도록 하였다!
이후 saveNews()를 호출하면 모든 headLine을 반환!!!
✏️ Controller 생성

✏️ Thymeleaf 생성

📌 결과
✏️ 결과를 확인해보자

서버를 시작한 뒤 비어있는 jsoupEx DB를 확인 !

Controller에 지정한 url로 요청을 보내면 위처럼 네이버 헤드라인 뉴스기사와 언론사, 상세 페이지 url이 화면에 출력되는 것을 볼 수 있다.
이후 DB를 다시 새로고침 해보면

DB에 크롤링 했던 네이버 헤드 라인 뉴스가 저장된 것을 볼 수 있다.

DB와 네이버 헤드라인 뉴스 기사를 비교해보니 DB에 모든 내용이 있는 것을 확인할 수 있었다 !!!!!!