본문 바로가기
Java & Kotlin/Java

[Java] 크롤링 crawling, 셀레니움 Selenium

by heekng 2021. 2. 22.
반응형

[Java] 크롤링 crawling, 셀레니움 Selenium

웹 크롤링의 정식 명칭은 Web Scraping이며, 웹 사이트에서 원하는 정보를 추출하는 것을 의미한다.

보통 웹 사이트는 HTML기반이기 때문에 정보를 추출할 페이지에서 개발자모드 실행 후 원하는 정보를 가지고 있는 태그를 검색하는 스킬이 요구된다.

 

크롤링을 할 때에 크롤링한 데이터를 소장, 활용하는 것은 불법이 아니지만, 해당 데이터를 배포할 경우 문제가 될 수 있다.

때문에 이러한 경우에는 해당 사이트의 허락을 반드시 맡아야 한다.

목차
  1. 목차1
  2. 목차2

웹 크롤링 라이브러리의 종류

웹 크롤링 라이브러리는 Jsoup, Selenium 2가지가 있다.

Jsoup

정적인 자료를 수집하는 경우에 주로 사용한다.

정적 데이터를 비교적 빠르게 수집할 수 있지만 브라우저가 아닌 HTTP Request를 사용하기 떄문에 동적 데이터를 수집하기 위해서는 해당 서버의 인증키 요구 등 수집할 수 없는 경우가 많다.

또한 동적인 기능을 지원하지 않는 경우가 많다.

Selenium

빅데이터관련, 동적인 자료를 수집할 때 주로 사용한다.

Jsoup에 비해 속도는 느리지만 브라우저 드라이버를 사용하여 동적 데이터도 수집 가능하다.


Selenium 셀레니움 환경 설치방법

자신의 브라우저에 맞는 드라이버 다운로드

셀레니움을 이용해 크롤링을 하는 가장 첫번째 단계는 브라우저 드라이버를 다운로드 하는 것이다.

나의 경우 Chrome브라우저를 이용하기 때문에 크롬을 기준으로 설명하지만, 다른 브라우저도 비슷한 방법으로 진행된다.

 

먼저 크롬 브라우저의 우측 상단 메뉴 -> 도움말 -> 크롬 정보를 들어간다.

버전 88을 사용한다.

 

다음은 내 크롬 버전에 맞는 크롬 드라이버를 다운받는다.

구글에 "크롬 드라이버 다운로드"를 검색하거나, 아래 주소로 접속하고, 본인 버전에 맞는 최신 드라이버를 다운로드한다.

chromedriver.chromium.org/downloads

 

Downloads - ChromeDriver - WebDriver for Chrome

WebDriver for Chrome

chromedriver.chromium.org

셀레니움 서버 다운로드

구글에 "셀레니움 서버 다운로드" 또는 아래 링크로 접속한다.

www.selenium.dev/downloads/

 

Downloads

Firefox GeckoDriver is implemented and supported by Mozilla, refer to their documentation for supported versions. Internet Explorer Only version 11 is supported, and it requires additional configuration. Safari SafariDriver is supported directly by Apple,

www.selenium.dev

Selenium Server (Grid) 의 가장 최신버전을 다운로드한다.


Java에서 크롤링하기

셀레니움 서버 Build Path

위에서 브라우저 드라이버와 셀레니움 서버를 다운받았을 것이다.

먼저 셀레니움 서버를 Build Path해준다.

 

크롤링 순서

java파일에서 작성하는 크롤링의 순서는 다음과 같다.

드라이버 설정 -> 크롬설정을 담은(선택) 크롬 드라이버를 담은 WebDriver 객체 생성 -> WebDriver을 크롬 브라우저라 생각하고, 원하는 URL의 원하는 태그에 접근 및 내용 get하기

 

항상 기본적인 틀은 같다.

하지만 내가 접근한 URL에서 원하는 element를 받아올 때에는 WebElement객체에 findElement한 값을 담는다는 로직을 이해한다면 쉬울거라 생각한다.

EX) 네이버 뉴스의 IT/과학 뉴스 제목 가져오기

네이버 뉴스의 IT/과학 탭의 <strong>태그로 감싸진 뉴스의 제목들을 가져와 출력해보자.

가장 대표적인 방법들을 이용하여 자바 코드를 작성했다.

아래의 코드들의 주석을 잘 살펴보고 분석하면 누구나 셀레니움을 이용한 크롤링이 가능하다.

package blog;

import java.util.List;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;

public class blog1 {
	
	public static final String WEB_DRIVER_ID = "webdriver.chrome.driver"; //드라이버 ID
	public static final String WEB_DRIVER_PATH = "C:\\chromedriver.exe"; //드라이버 경로
	
	public static void main(String[] args) {
		//드라이버 설정
		try {
			System.setProperty(WEB_DRIVER_ID, WEB_DRIVER_PATH);
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		//크롬 설정을 담은 객체 생성
		ChromeOptions options = new ChromeOptions();
		//브라우저가 눈에 보이지 않고 내부적으로 돈다.
		//설정하지 않을 시 실제 크롬 창이 생성되고, 어떤 순서로 진행되는지 확인할 수 있다.
		options.addArguments("headless");
		
		//위에서 설정한 옵션은 담은 드라이버 객체 생성
		//옵션을 설정하지 않았을 때에는 생략 가능하다.
		//WebDriver객체가 곧 하나의 브라우저 창이라 생각한다.
		WebDriver driver = new ChromeDriver(options);
		
		//이동을 원하는 url
		String url = "https://www.naver.com";
		
		//WebDriver을 해당 url로 이동한다.
		driver.get(url);
		
		//브라우저 이동시 생기는 로드시간을 기다린다.
		//HTTP응답속도보다 자바의 컴파일 속도가 더 빠르기 때문에 임의적으로 1초를 대기한다.
		try {Thread.sleep(1000);} catch (InterruptedException e) {}
		
		//class="nav" 인 모든 태그를 가진 WebElement리스트를 받아온다.
		//WebElement는 html의 태그를 가지는 클래스이다.
		List<WebElement> el1 = driver.findElements(By.className("nav"));
		
		for (int i = 0; i < el1.size(); i++) {
			//nav 클래스의 객체 중 "뉴스"라는 텍스트를 가진 WebElement를 클릭한다.
			if(el1.get(i).getText().equals("뉴스")) {
				el1.get(i).click();
				break;
			}
		}
		
		//1초 대기
		try {Thread.sleep(1000);} catch (InterruptedException e) {}

		//버튼을 클릭했기 때문에 브라우저는 뉴스창으로 이동돼 있다.
		//이동한 뉴스 창의 IT/과학 뉴스 헤드라인을 가져온다.
		
		//iT/과학뉴스를 담은 div
		WebElement el2 = driver.findElement(By.id("section_it"));
		
		//div속에서 strong태그를 가진 모든 element를 받아온다.
		List<WebElement> el3 = el2.findElements(By.tagName("strong"));
		
		int count = 0;
		for (int i = 0; i < el3.size(); i++) {
			//뉴스의 제목을 모두 출력한다.
			System.out.println(++count + "번 뉴스: "+ el3.get(i).getText());
		}
		
		
		try {
			//드라이버가 null이 아니라면
			if(driver != null) {
				//드라이버 연결 종료
				driver.close(); //드라이버 연결 해제
				
				//프로세스 종료
				driver.quit();
			}
		} catch (Exception e) {
			throw new RuntimeException(e.getMessage());
		}
	}
}

결과:

위와 같이 정상적으로 출력됨을 확인할 수 있다.

반응형