영화추천시스템을 위한 db구축
영화추천시스템에서 필요한 것
- 부트캠프에서 진행중인 final project의 주제를 영화 추천 시스템으로 선정했다.
- 추천시스템에서 가장 중요한건 양질의 데이터이다.
-> 디즈니플러스, 티빙등의 OTT와 영화관 3사의 웹 스크래핑(크롤링)과 TMDB의 api를 이용하기로 하였다.
OTT 웹 스크래핑
1. 먼저 넷플릭스의 현재 상영중인 시리즈(TV)의 데이터와 영화 데이터는 셀레니움을 이용한 웹 스크래핑을 생각하게 되었다.

2. 작품 제목, 썸네일, 세부정보url 가져오기
- 넷플릭스의 시리즈 내림차순 주소를 접속
- send_keys를 이용하여 page_down을 반복
- xpath를 find_element로 이름, 상세정보 url, 썸네일을 찾은 후 각각의 리스트에 append.
def get_prevalue(driver):
driver.get(serise_url_up)
S_name=[]
S_url=[]
S_img=[]
for i in range(0, 400, 1):
driver.find_element(by='tag name', value='body').send_keys(Keys.PAGE_DOWN)
time.sleep(0.1)
slider_items = driver.find_elements(by='xpath',value='//div[starts-with(@class, "slider-item")]')
for item in slider_items:
tag = item.find_element(by='xpath', value='.//a')
name = anchor_tag.get_attribute('aria-label')
url = anchor_tag.get_attribute('href')
image_url = item.find_element(by='xpath', value='.//img').get_attribute('src')
S_name.append(name)
S_url.append(url)
S_img.append(image_url)
S_detail = [url.split('?')[0].replace("/watch/", "/browse/genre/83?so=az&jbv=") for url in S_url]
return S_name, S_url, S_img, S_detail
3. 가져온 세부정보 url을 이용하여 세부정보 가져오기
def get_detailvalue(driver, S_name, S_detail):
S_creator = []
S_actor = []
S_genre = []
S_char = []
S_age = []
S_BC = []
S_year = []
for detail_url in S_detail:
driver.get(detail_url)
tags = driver.find_elements(by='class name', value='previewModal--tags')
creator = None
actor = None
genre = None
char = None
BC = None
age = None
year = None
for tag in tags:
label = tag.find_element(by='class name', value='previewModal--tags-label').text
items = tag.find_elements(by='class name', value='tag-item')
if label == '출연:':
actor = [item.text for item in items]
elif label == '크리에이터:':
creator = [item.text for item in items]
elif label == '장르:':
genre = [item.text for item in items]
elif label == '시리즈 특징:':
char = [item.text for item in items]
try:
maturity_wrapper = driver.find_element(by='class name', value='maturity-rating-wrapper')
BC = maturity_wrapper.find_element(by='class name', value='maturity-number').text
age = maturity_wrapper.find_element(by='class name', value='maturityDescription').text
except NoSuchElementException:
BC = None
age = None
try:
broadcaster_element = driver.find_element(by='class name', value='broadcaster')
BC = broadcaster_element.find_element(by='tag name', value='div').text
year = broadcaster_element.find_element(by='tag name', value='div').text
except NoSuchElementException:
BC = None
year = None
S_creator.append(creator if creator else None)
S_actor.append(actor if actor else None)
S_genre.append(genre if genre else None)
S_char.append(char if char else None)
S_BC.append(BC if BC else None)
S_age.append(age if age else None)
S_year.append(year if year else None)
return S_creator, S_actor, S_genre, S_char, S_BC, S_age, S_year
문제점
- 셀레니움을 이용하여 웹 스크래핑을 하게되면 해당 사이트에 많은 부하를 가하게 된다는 문제가 있다.
- 너무 빠른속도로 세부정보에 접속하다보면 350개가 넘어갈 즈음 404에러를 목격하게 된다.
time 모듈을 임포트한 이후 wait를 이용하여 적절한 시간을 주고,
데이터를 다 저장한 이후에는 db에 없는 작품에 대해서만 세부정보를 접속해야할 것 같다.