Stage1 - 순서를 활용해서 데이터 선택하기

5주차 첫번째 스테이지에서는 네이버 영화의 현재 상영영화 페이지(https://movie.naver.com/movie/running/current.nhn)에서 제목, 평점, 장르, 감독, 배우 데이터를 수집합니다.

앞에서 다룬 데이터 수집을 복습하며 기존 방법으로 선택할 수 없었던 데이터 선택방법을 공부합니다.

네이버 영화에서 데이터 수집하기

네이버TV, 네이버 기사수집 등 앞에서 만들어본 데이터 수집기와 마찬가지로 아래 순서에 따라 데이터를 수집합니다.

  1. 웹에서 소스코드를 가져와 html 파싱하기

  2. 컨테이너 수집하기

  3. 상세 데이터 수집하기

    • 제목

    • 평점

    • 장르

    • 감독

    • 배우

  4. 수집한 데이터 출력하기

#1. 웹에서 소스코드를 가져와 html파싱

requestsbs4를 활용해서 소스코드를 가져와 html파싱 해줍니다. * 네이버 영화 - 현재상영영화(https://movie.naver.com/movie/running/current.nhn)

week5_1.py
import requests
from bs4 import BeautifulSoup
# 웹페이지에서 소스코드를 가져와 BeautifulSoup으로 파싱
raw = requests.get("https://movie.naver.com/movie/running/current.nhn",
headers={'User-Agent':'Mozilla/5.0'})
html = BeautifulSoup(raw.text, 'html.parser')

#2. 컨테이너 수집하기

<dl class='lst_dsc' ...>

컨테이너(영화 정보를 모두 포함하고 있는 영역)는 쉽게 찾을 수 있습니다. 선택자를 찾은 후에는 꼭 검사창에서 검색을 통해 영화를 모두 포함하고 있는지 확인하셔야 합니다. *현재상영 중인 영화 수만큼 컨테이너가 검색되어야합니다.

컨테이너 선택자: dl.lst_dsc

선택자를 활용해서 컨테이너를 수집합니다.

week5_1.py
import requests
from bs4 import BeautifulSoup
# 웹페이지에서 소스코드를 가져와 BeautifulSoup으로 파싱
raw = requests.get("https://movie.naver.com/movie/running/current.nhn",
headers={'User-Agent':'Mozilla/5.0'})
html = BeautifulSoup(raw.text, 'html.parser')
# 컨테이너 수집하기
movie = html.select("dl.lst_dsc")
for m in movie:
# 영화별 데이터 수집하기

*데이터 수집이 익숙해졌으므로 바로 상세데이터 수집 준비(반복문)

#3-1. 제목/평점 데이터 수집

제목 데이터 선택
평점 데이터 선택

각 컨테이너 안의 제목과 평점 데이터 역시 쉽게 선택할 수 있습니다.

제목 선택자: dt.tit a 평점 선택자: div.star_t1 span.num

선택자를 활용해서 아래와 같이 제목과 평점 데이터를 수집합니다.

week5_1.py
... 생략
# 컨테이너 수집하기
movie = html.select("dl.lst_dsc")
for m in movie:
# 영화별 데이터 수집하기
title = m.select_one("dt.tit a")
score = m.select_one("div.star_t1 span.num")

#3-2. 장르/감독/평점 데이터 수집

장르/감독/평점 데이터 수집을 하기 위해서 선택자를 찾아보면 위와 같이 같은 선택자로 선택되는 데이터에 저장되어 있는 것을 알 수 있습니다. 이런 경우에는 아이디나 클래스로 선택자를 구분할 수 없고, 같은 태그 안의 같은 위치에 있기 때문에 상하관계를 통해서도 구분할 수 없습니다.

방법 1. 리스트 활용하기

select함수를 활용하면 데이터를 리스트 형태로 저장하므로 리스트에 저장된 데이터를 인덱싱 방법을 활용하여 특정 순서의 데이터를 수집할 수 있습니다.

week5_1.py
... 생략
# 컨테이너 수집하기
movie = html.select("dl.lst_dsc")
for m in movie:
# 영화별 데이터 수집하기
title = m.select_one("dt.tit a")
score = m.select_one("div.star_t1 span.num")
# info에 dd태그의 리스트를 저장합니다.
info = m.select("dl.info_txt1 dd")
genre = info[0].select("a")
directors = info[1].select("a")
actors = info[2].select("a")

dd태그 안의 a태그에 장르, 감독, 배우에 대한 데이터가 들어있고 한 영화에 여러개의 장르, 감독, 배우에 대한 데이터가 있을 수 있으므로 select함수를 활용해서 리스트로 저장합니다.

방법 2. 선택자 응용하기(nth-of-type)

선택자 레벨에서도 이 문제를 해결할 수 있습니다. 아래와 같이 nth-of-type()을 활용하면 n번째 데이터를 선택할 수 있습니다.

week5_1.py
... 생략
# 컨테이너 수집하기
movie = html.select("dl.lst_dsc")
for m in movie:
# 영화별 데이터 수집하기
title = m.select_one("dt.tit a")
score = m.select_one("div.star_t1 span.num")
# nth-of-type을 활용해서 데이터를 선택합니다.
genre = m.select("dl.info_txt1 dd:nth-of-type(1) a")
directors = m.select("dl.info_txt1 dd:nth-of-type(2) a")
actors = m.select("dl.info_txt1 dd:nth-of-type(3) a")

태그이름:nth-of-type(N) 방법을 활용하면 N번째 태그 데이터를 선택할 수 있습니다. 프로그래밍 언어는 대부분을 숫자를 0부터 세지만 nth-of-type()방법의 경우는 숫자를 1부터 세게 됩니다.

그리고 nth-of-type()의 앞에는 클래스 또는 아이디가 올 수 없기 때문에 해당하는 태그가 몇번째 태그인지도 꼭 확인해야합니다.

#4. 수집한 데이터 출력

아래와 같이 수집한 데이터를 보기 좋은 모양으로 출력합니다.

week5_1.py
import requests
from bs4 import BeautifulSoup
# 웹페이지에서 소스코드를 가져와 BeautifulSoup으로 파싱
raw = requests.get("https://movie.naver.com/movie/running/current.nhn",
headers={'User-Agent':'Mozilla/5.0'})
html = BeautifulSoup(raw.text, 'html.parser')
# 컨테이너 수집하기
movie = html.select("dl.lst_dsc")
for m in movie:
# 영화별 데이터 수집하기
title = m.select_one("dt.tit a")
score = m.select_one("div.star_t1 span.num")
# nth-of-type을 활용해서 데이터를 선택합니다.
genre = m.select("dl.info_txt1 dd:nth-of-type(1) a")
directors = m.select("dl.info_txt1 dd:nth-of-type(2) a")
actors = m.select("dl.info_txt1 dd:nth-of-type(3) a")
# 구분선을 출력해줍니다.
print("="*50)
print("제목:", title.text)
print("-"*50)
print("평점:", score.text)
# 장르, 감독, 배우는 데이터가 여러개일 수 있으므로
# 반복문을 통해 출력해줍니다.
print("-" * 50)
print("장르:")
for g in genre:
print(g.text)
print("-" * 50)
print("감독:")
for d in directors:
print(d.text)