자바 크롤링 (Selenium)

나무에물주기·2023년 3월 31일
1
post-thumbnail

Selenium을 사용한 Java 웹 크롤링 예제

이번 글에서는 Selenium을 사용하여 Java에서 웹 크롤링을 수행하는 방법을 알아보겠습니다. 이를 위해 Upbit 공지사항을 크롤링하여 데이터베이스에 저장하는 기능을 구현한 예제 코드를 작성해보겠습니다.

의존성 관리

먼저, Gradle을 사용하여 의존성을 관리합니다. 이를 위해 build.gradle 파일에 아래와 같이 의존성을 추가합니다.

dependencies {
    //...
    implementation 'org.seleniumhq.selenium:selenium-java:4.1.4'
    implementation 'org.seleniumhq.selenium:selenium-chrome-driver:4.1.4'
}

위 코드에서 selenium-java는 Selenium의 Java 라이브러리, selenium-chrome-driver는 Chrome 브라우저를 조작하는 데 필요한 드라이버입니다.

ChromeDriver 다운로드 및 설정

ChromeDriver는 Chrome 브라우저를 조작하는 데 필요한 드라이버입니다. 따라서 이 예제에서는 ChromeDriver를 다운로드하고 설정해야 합니다.

ChromeDriver는 OS별로 다르게 제공됩니다. 이 예제에서는 Windows 운영체제를 기준으로 설명하겠습니다. 다른 운영체제에서는 해당 OS에 맞는 드라이버를 다운로드하시면 됩니다.(자신의 크롬 브라우저 버전(예시 버전 : 111.0 ….)에 맞는 드라이버를 설치해야 합니다.) → chrome://version/ URL을 통해 자신의 크롬 버전 확인 가능

  1. ChromeDriver 다운로드 페이지로 이동합니다.
  2. 다운로드 페이지에서 최신 버전의 ChromeDriver를 다운로드합니다.
  3. 다운로드한 파일을 압축해제한 후, chromedriver.exe 파일을 프로젝트 디렉토리에 저장합니다.

upbit 공지사항 페이지 크롤링

이제 Upbit 공지사항 페이지를 크롤링하는 기능을 구현해보겠습니다. 이를 위해 UpbitCrawlerService 클래스를 작성합니다.

@Service
public class UpbitCrawlerService {
    // NoticeRepository 주입
    private final NoticeRepository noticeRepository;

    // 생성자를 통한 의존성 주입
    @Autowired
    public UpbitCrawlerService(NoticeRepository noticeRepository) {
        this.noticeRepository = noticeRepository;
    }

    // Upbit 공지사항 크롤링 메소드
    public List<NoticeDto> crawlUpbitNotices() {
        // 크롬 드라이버 설정
        System.setProperty("webdriver.chrome.driver", "./chromedriver.exe"); // 윈도우
        // System.setProperty("webdriver.chrome.driver", "./chromedriver"); // 리눅스, 맥

        // 크롬 옵션 설정
        ChromeOptions options = new ChromeOptions();
        options.addArguments("--remote-allow-origins=*");
        WebDriver driver = new ChromeDriver(options);

        // Upbit 공지사항 페이지 접속
        driver.get("https://upbit.com/service_center/notice");

        // 공지사항 목록을 가져옵니다.
        List<WebElement> elements = driver.findElements(By.cssSelector("tr.top"));

        // 반환할 NoticeDto 리스트 생성
        List<NoticeDto> notices = new ArrayList<>();

        // 각 공지사항에 대하여
        for (WebElement noticeElement : elements) {
            // 공지사항의 제목과 링크를 가져옵니다.
            // "td.lAlign > a"는 "td" 태그 중 클래스가 "lAlign"인 태그의 자식 "a" 태그를 선택합니다.
            WebElement anchorElement = noticeElement.findElement(By.cssSelector("td.lAlign > a"));
            String title = anchorElement.getText(); // "a" 태그의 텍스트(제목)를 가져옵니다.
            String link = anchorElement.getAttribute("href"); // "a" 태그의 "href" 속성(링크)를 가져옵니다.

            // 제목과 링크 출력
            System.out.println("title = " + title);
            System.out.println("link = " + link);

            // 공지사항의 날짜를 가져옵니다.
            // "td:nth-child(2)"는 "td" 태그 중 두 번째 자식에 해당하는 태그를 선택합니다.
            WebElement dateElement = noticeElement.findElement(By.cssSelector("td:nth-child(2)"));
            String dateText = dateElement.getText(); // "td" 태그의 텍스트(날짜)를 가져옵니다.
            LocalDate date = LocalDate.parse(dateText, DateTimeFormatter.ofPattern("yyyy.MM.dd")); // 날짜 문자열을 LocalDate 객체로 변환합니다.

            // Notice 객체 생성 및 저장
            Notice notice = Notice.builder()
                    .title(title)
                    .link(link)
                    .date(date)
                    .build();

            // Notice 객체를 DB에 저장합니다.
            noticeRepository.save(notice);

            // 저장된 Notice 객체를 NoticeDto로 변환하여 리스트에 추가합니다.
            notices.add(new NoticeDto(notice));
        }

        // WebDriver 종료
        driver.quit();

        // NoticeDto 리스트 반환
        return notices;
    }
}

위 코드에서는 크롬 드라이버를 설정하고, ChromeOptions를 설정합니다. 그 다음 WebDriver 객체를 생성하고 Upbit 공지사항 페이지에 접속합니다. 공지사항 목록을 가져와 각 공지사항의 제목, 링크, 날짜를 추출하여 Notice 객체를 생성하고 데이터베이스에 저장합니다. 마지막으로 WebDriver를 종료하고, NoticeDto 리스트를 반환합니다.

Controller 작성

이제 API를 제공하기 위해 Controller를 작성합니다. 이를 위해 UpbitCrawlerController 클래스를 작성합니다.

@RestController
@RequiredArgsConstructor
@RequestMapping("/api/v1/crawl")
public class UpbitCrawlerController {
    private final UpbitCrawlerService upbitCrawlerService;

    @GetMapping("/upbit/notices")
    public List<NoticeDto> crawlUpbitNotices() {
        return upbitCrawlerService.crawlUpbitNotices();
    }
}

위 코드에서는 UpbitCrawlerService를 주입받고, /api/v1/crawl/upbit/notices API를 제공합니다. 이 API는 UpbitCrawlerServicecrawlUpbitNotices() 메서드를 호출하여 Upbit 공지사항을 크롤링한 후 NoticeDto 리스트를 반환합니다.

요약

이 글에서는 Java에서 Selenium을 사용하여 Upbit 공지사항 페이지를 크롤링하는 방법을 알아보았습니다. 이를 위해 먼저 Maven 또는 Gradle을 사용하여 Selenium 및 ChromeDriver 의존성을 추가하고, ChromeDriver를 다운로드하였습니다. 이후 UpbitCrawlerService
클래스를 작성하여 Selenium을 사용하여 Upbit 공지사항 페이지를 크롤링하고, 데이터베이스에 저장하는 기능을 구현하였습니다. 마지막으로 UpbitCrawlerController
클래스를 작성하여 /api/v1/crawl/upbit/notices
API를 제공하였습니다.

프로젝트 레포 :

GitHub - ejong2/java_crawl

profile
개인 공부를 정리함니다

0개의 댓글