지난 글에서는 웹 크롤링의 개념과 작동원리, 크롤링할 웹 페이지를 정했다면 가장 먼저 확인해야하는 사항에 대해서 설명했습니다. 이번에는 간단한 예시들을 중심으로 Jsoup을 활용하여 크롤링하는 방식에 대해서 가볍게 다뤄보도록 하겠습니다.
Velog, 요즘 IT 크롤링 하기(1) - crawlin, Robots.txt, Jsoup, SSR, CSR
🤗간단한 프로젝트 소개현재 하고 있는 프로젝트는 매일 IT 관련 블로그나 뉴스를 3개씩 이메일(or 문자) 발송해주는 서비스입니다. 이를 위해서 매일 정해진 시간마다 관련 블로그나 뉴스 사이
cinining.tistory.com
Jsoup이란
Jsoup에 대해서 한번 더 정리해보자면, Jsoup은 Java로 작성된 HTML 파싱 및 웹 크롤링을 위한 라이브러리입니다. 이 라이브러리를 통해 크롤링 및 스크래핑을 할 수 있습니다.
아래는 Jsoup 공식 문서입니다. 다양한 코드 사용 예제를 통해 사용법을 소개하고 있으니 참고해보세요.
jsoup: Java HTML parser, built for HTML editing, cleaning, scraping, and XSS safety
jsoup: Java HTML Parser jsoup is a Java library that simplifies working with real-world HTML and XML. It offers an easy-to-use API for URL fetching, data parsing, extraction, and manipulation using DOM API methods, CSS, and xpath selectors. jsoup implement
jsoup.org
Jsoup 의존성 추가하기
프로젝트 환경은 `Spring Boot`, `gradle`입니다.
현재 기준 가장 최신 버전이었던 1.18.3 버전을 의존성 추가했고, 위의 공식 문서에서 릴리즈된 버전을 추가하시면 됩니다.
implementation 'org.jsoup:jsoup:1.18.3'
Jsoup 사용 시 알아야 할 핵심 클래스
Jsoup을 사용하기 전에 Jsoup이 가지고 있는 클래스 중에 총 3가지의 중요 클래스들을 미리 알아보겠습니다.
import org.jsoup.nodes.Document; // 연결해서 얻어온 HTML 전체 문서
import org.jsoup.nodes.Element; // Document(HTML 전체)의 HTML 요소
import org.jsoup.select.Elements; // Element가 모인 자료형
1. Document 클래스: 연결해서 얻어온 HTML 전체 문서
// 이러한 HTML이 있을 때
String html = "<html><head><title>First parse</title></head>"
+ "<body><p>Parsed HTML into a doc.</p></body></html>";
// HTML 통째로 가져온다.
Document doc = Jsoup.parse(html);
`Document`타입의 `doc`을 출력해보면 아래처럼 `HTML` 전체가 그대로 출력됩니다.
참고로 `Jsoup.parse()`는 `HTML`문자열을 파싱하여 Jsoup의 `Document` 객체로 변환하는 역할입니다.
2. Element 클래스: Document의 HTML 요소
3. Elements 클래스: Element가 모인 자료형
Element, Elements 클래스는 아래 예제 코드를 통해 살펴보겠습니다.
// 해당 링크의 HTML 가져오기
Document doc = Jsoup.connect("https://en.wikipedia.org/").get();
// css 선택자에 해당되는 모든 데이터 추출(추출된 Element들이 모인 Elements)
Elements newsHeadlines = doc.select("#mp-itn b a");
// for문으로 각 Element의 title과 href 링크 출력
for (Element headline : newsHeadlines) {
System.out.println(headline.attr("title") + "\n" + headline.absUrl("href"));
}
내가 원하는 페이지의 HTML 전체 문서를 가져오고 HTML에서 `mp-itn`이라는 id선택자에 `b`태그 안, 그리고 `a`태그 안에 있는 요소를 가져옵니다. for문을 돌려서 각각의 Element의 title과 href를 출력합니다.
`https://en.wikipedia.org/` 링크를 타고 들어가 개발자 도구를 열어 HTML을 살펴보면 아래와 같이 HTML 형식을 가지고 있는데 위처럼 잘 출력된 것을 한번 더 확인할 수 있습니다.
Jsoup 사용법
Jsoup으로 문서의 파싱, 해당 문서의 내부 돌아다니기, CSS 스타일로 요소 선택하기 등이 가능합니다.
1. 문서의 파싱
문서는 URL, 파일, 문자열을 파싱할 수 있습니다.
1.1. 문서 전체를 가지고 있는 문자열
`Jsoup.parse()`
String html = """
<html><head><title>First parse</title></head>
<body><p>Parsed HTML into a doc.</p></body></html>
""";
Document doc = Jsoup.parse(html);
위에서 한번 예시로 보여줬던 부분입니다. HTML 전체 문서를 담고 있는 문자열을 `parse()` 메서드로 가져옵니다.
만약 해당 문자에서 HTML 태그들을 제외하고 순수 문자열을 얻고 싶다면 해당 doc에 `text()`를 붙여주면 됩니다.
Document doc = Jsoup.parse(html);
String text = doc.text(); // String text = Jsoup.parse(html).text();
1.2. 문서의 body 일부를 가지고 있는 문자열
` doc.body() `
String html = "<div><p>Example html</p>";
Document doc = Jsoup.parse(html);
Element body = doc.body();
`doc.body()`는 문서의 body 요소를 추출합니다.
뒤에서 설명하게 될 `doc.getElementByTag("body")`와 같은 역할입니다.
1.3. URL
`Jsoup.connect("URL").get()`
// '요즘IT'사이트의 개발 카테고리의 최신순
Document doc = Jsoup.connect("https://yozm.wishket.com/magazine/list/develop/?sort=new").get();
GET 호출을 주로 하는데 POST 방식으로도 사용할 수 있습니다.. user-agent나 cookie등을 담아 보낼 수도 있습니다.
참고로 jsoup은 http와 https만 지원합니다.
1.4. 파일
File inputFile = new File("/html/yozmExampleFile.html");
Document doc = Jsoup.parse(inputFile, "UTF-8");
`parse()`메서드의 첫 번째 인자는 파싱할 파일의 File 객체, 두 번째 인자는 파일의 캐릭터셋입니다.
+ 필자의 경우 블로그를 크롤링하는 코드를 짠 후 테스트 코드를 짜야할 때 따로 HTML 파일을 만들어서 테스트 코드를 짰습니다.
2. 문서 내부 돌아다니기
2.1. 필요한 요소 찾기
* getElementById(String id) : Element 객체를 반환합니다. 하나를 반환합니다. 없으면 null 을 반환합니다.
* getElementsByTag(String tag) : Elements 객체를 반환합니다. 없으면 size() 가 0 입니다.
* getElementsByClass(String className) : Elements 객체를 반환합니다. 없으면 size() 가 0 입니다.
2.2. Elements 객체
정리
그럼 이 세 가지 클래스들을 다 파악해봤으니 다음 포스트부터 본격적으로 블로그를 크롤링, 스크래핑 해보겠습니다.
참고자료