api 구현이 대략 끝났으니 이제는 영화 정보를 불러오기 위해서 open api를 활용할 차례다.
일단 받아오기 전에 정보를 어떻게 활용할지 먼저 생각해야 한다.
1. 영화진흥위원회 페이지에서 제공하는 api 인터페이스 구조 확인해보기
영화 목록 api에서 사용할 예정일 정보 대부분을 영화목록 조회 API 서비스에서 제공하기 때문에 해당 api 사용법을 알아보기로 했다.
기본 요청 URL : http://www.kobis.or.kr/kobisopenapi/webservice/rest/movie/searchMovieList.xml (또는 .json)
요청 인터페이스
요청 변수 | 값 | 설명 |
key | 문자열(필수) | 발급받은키 값을 입력합니다. |
curPage | 문자열 | 현재 페이지를 지정합니다.(default : “1”) |
itemPerPage | 문자열 | 결과 ROW 의 개수를 지정합니다.(default : “10”) |
movieNm | 문자열 | 영화명으로 조회합니다. (UTF-8 인코딩) |
directorNm | 문자열 | 감독명으로 조회합니다. (UTF-8 인코딩) |
openStartDt | 문자열 | YYYY형식의 조회시작 개봉연도를 입력합니다. |
openEndDt | 문자열 | YYYY형식의 조회종료 개봉연도를 입력합니다. |
prdtStartYear | 문자열 | YYYY형식의 조회시작 제작연도를 입력합니다. |
prdtEndYear | 문자열 | YYYY형식의 조회종료 제작연도를 입력합니다. |
repNationCd | 문자열 | N개의 국적으로 조회할 수 있으며, 국적코드는 공통코드 조회 서비스에서 “2204” 로서 조회된 국적코드입니다. (default : 전체) |
movieTypeCd | 문자열 | N개의 영화유형코드로 조회할 수 있으며, 영화유형코드는 공통코드 조회 서비스에서 “2201”로서 조회된 영화유형코드입니다. (default: 전체) |
응답 구조
응답 필드 | 값 | 설명 |
movieCd | 문자열 | 영화코드를 출력합니다. |
movieNm | 문자열 | 영화명(국문)을 출력합니다. |
movieNmEn | 문자열 | 영화명(영문)을 출력합니다. |
prdtYear | 문자열 | 제작연도를 출력합니다. |
openDt | 문자열 | 개봉일을 출력합니다. |
typeNm | 문자열 | 영화유형을 출력합니다. |
prdtStatNm | 문자열 | 제작상태를 출력합니다. |
nationAlt | 문자열 | 제작국가(전체)를 출력합니다. |
genreAlt | 문자열 | 영화장르(전체)를 출력합니다. |
repNationNm | 문자열 | 대표 제작국가명을 출력합니다. |
repGenreNm | 문자열 | 대표 장르명을 출력합니다. |
directors | 문자열 | 영화감독을 나타냅니다. |
peopleNm | 문자열 | 영화감독명을 출력합니다. |
companys | 문자열 | 제작사를 나타냅니다. |
companyCd | 문자열 | 제작사 코드를 출력합니다. |
companyNm | 문자열 | 제작사명을 출력합니다. |
초기에 받아오기로 계획한 정보 중 러닝타임, 영화 포스터, 줄거리 요약, 배우명, 배역명에 대한 정보를 제외하고 받아오는게 가능하다.
일단은 open api에서 받아올 수 있는 정보로만 구성해보고 더 진행해보는게 좋아보인다.
그리고 기본요청 url 뒷 부분에 parameter로 인터페이스 목록에 있는 요청 변수를 넣어 url로 사용하면 response가 도착하는 것이 확인됐다.
ex >
http://kobis.or.kr/kobisopenapi/webservice/rest/boxoffice/searchDailyBoxOfficeList.xml
?key=f5eef3421c602c6cb7ea224104795888 //해당 부분이 발급받은 key가 들어가는 부분
&targetDt=20120101
...
2. java에서 selenium API를 이용해 크롤링
java에서도 크롤링을 할 수 있는 방법이 있어서 크롤링을 통해 정보를 받아오는 방법을 알아봤다.
Jsoup과 selenium이라는 api를 이용하는 방법이 있다. 그중 Jsoup의 사용법이 더 간단해서 사용법을 공부했는데 동적 페이지에서 나오는 정보는 얻을수 없는 단점이 있어서 selenium을 사용하기로 했다.
1.Chrome Driver 설치
자신의 크롬 버전과 일치하는 버전을 설치해야한다.
2. 설치한 chromedriver.exe를 프로젝트 폴더에 넣기
굳이 넣지 않아도 되지만 관리를 편하게 하기위해서 일단 넣어놨다.
3. 구현
test로 간단하게 실행되는 프로그램을 구현했다.
import java.io.IOException;
import java.util.ArrayList;
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 Main {
private static final String url = "http://www.cine21.com/rank/boxoffice/domestic";
private static String WEB_DRIVER_ID = "webdriver.chrome.driver";
private static String WEB_DRIVER_PATH = "./chromedriver.exe";
public static void main(String[] args) throws IOException {
// 크롬 드라이버 설정
System.setProperty(WEB_DRIVER_ID, WEB_DRIVER_PATH);
// 크롬 옵션 설정
ChromeOptions options = new ChromeOptions();
options.addArguments("--disable-popup-blocking"); // 팝업 안띄움
options.addArguments("headless"); // 브라우저 안띄움
options.addArguments("--disable-gpu"); // gpu 비활성화
options.addArguments("--blink-settings=imagesEnabled=false"); // 이미지 다운 안받음
options.addArguments("--remote-allow-origins=*"); //없으면 접근 안됨
WebDriver driver = new ChromeDriver(options);
driver.get(url);
List<WebElement> elements = driver.findElements(By.cssSelector("li.boxoffice_li > a"));
List<String> detailList = new ArrayList<>();
//detail 링크 저장
for(int i=0;i<elements.size();i++){
WebElement noticeElement = elements.get(i);
String detailLink = noticeElement.getAttribute("href");
detailList.add(detailLink);
}
List<MovieDataDto> movieDtoList = new ArrayList<>();
for(int i=0;i<detailList.size();i++){
String code = detailList.get(i).split("=")[1];
driver.navigate().to(detailList.get(i));
WebElement imgAttr = driver.findElement(By.cssSelector("div.mov_poster > img"));
String imgUrl = imgAttr.getAttribute("src");
WebElement element = driver.findElement(By.cssSelector("div.mov_info"));
WebElement summaryAttr = driver.findElement(By.cssSelector("div.story_area > div"));
WebElement titleAttr = element.findElement(By.cssSelector("p.tit"));
WebElement nationAttr = element.findElement(By.cssSelector("p:nth-child(3) > span:nth-child(2)"));
WebElement genreAttr = element.findElement(By.cssSelector("p:nth-child(4) > span:nth-child(1)"));
WebElement directorAttr = element.findElement(By.cssSelector("p:nth-child(6) > a"));
WebElement runningTimeAttr = element.findElement(By.cssSelector("p:nth-child(4) > span:nth-child(2)"));
WebElement actorAttr;
try{
actorAttr = element.findElement(By.cssSelector("p:nth-child(7)"));
}catch (Exception e){
actorAttr = null;
}
movieDtoList.add(
new MovieDataDto(imgUrl, titleAttr.getText(), code, nationAttr.getText(), genreAttr.getText(),
directorAttr.getText(), runningTimeAttr.getText(), summaryAttr.getText(), actorAttr == null?"":actorAttr.getText()));
// System.out.println(movieDtoList.get(i).toString());
}
// WebDriver 종료
driver.quit();
System.out.println("Hello world!");
}
}
다른 블로그에 있는 글을 참고해서 작성했다.
cssSelector에 들어갈 인자를 찾는게 제일 힘들었는데 그 방법도 다행히 잘 설명되있어서 해결했다.
reference - https://velog.io/@yewo2nn16/Selenium-공지-크롤링으로-Selenium-배우기
[Selenium] 공지 크롤링으로 Selenium 배우기
공지 크롤링으로 Selenium 배우기
velog.io
3. 프로젝트에 적용
3가지 방법을 테스트해봤는데, 한번에 정보를 얻을 수 있는 2번 방법이 가장 적합하다고 생각해서 selenium을 프로젝트에 적용해 주기적으로 영화 정보를 크롤링해오는 api를 구현하기로 했다.
나중에 이 부분에 batch가 적용된다면 정보를 크롤링해오는 프로그램이 될 수도 있을것같다.
sellenium 사용법
'토이프로젝트 > 리뷰어(영화 리뷰 사이트)' 카테고리의 다른 글
백엔드 cicd 구축하기 (0) | 2023.06.02 |
---|---|
영화 정보 크롤링 Api 구현 (0) | 2023.06.01 |
16일차 - JPA N+1 문제 (0) | 2022.11.07 |
14일차 - 영화 상세정보 조회 api 구현 (0) | 2022.11.04 |
비즈니스 로직 구현과 단위테스트 (0) | 2022.10.28 |