웹크롤링
네이버 영화 평점 사이트 분석
- 영화랭킹에서 평점순(현재상영영화) 선택
- 접근 URL 확인
- 웹 페이지의 주소에 많은 정보가 담겨있음, 원하는 정보를 얻기 위해 변화시켜야하는 주소의 규칙이 보이기도 함
- 이 경우 날짜 정보를 변경해주면 해당 페이지에 접근이 가능하다
import pandas as pd
from bs4 import BeautifulSoup
from urllib.request import urlopen
url ="https://movie.naver.com/movie/sdb/rank/rmovie.naver?sel=cur&date=20180315"
page = urlopen(url)
soup = BeautifulSoup(page, "html.parser")
- 매 페이지마다 가져오는 영화의 갯수가 다르다, 따라서 end 변수에 한 페이지의 영화제목 갯수를 넣고 0 부터 갯수만큼 for을 돌려준다.
end = len(soup.find_all("div", "tit5"))
movie_name = [soup.find_all("div", "tit5")[n].a.text for n in range(0, end)]
movie_name
end = len(soup.find_all("td", "point"))
movie_point = [soup.find_all("td", "point")[n].string for n in range(0, end)]
movie_point
영화 평점 데이터 확보
- pandas의 date_range를 이용해 날짜를 쉽게 생성가능(freq="D" : day가 주기)
date = pd.date_range("2017.12.01", periods=100, freq="D")
date
- 날짜형 데이터들은 원하는 형태로 출력이 가능하다
date[0]
output : Timestamp('2017-12-01 00:00:00', freq='D')
date[0].strftime("%Y-%m-%d")
output : '2017-12-01'
date[0].strftime("%Y.%m..%d")
output : '2017.12..01'
for today in tqdm_notebook(date):
html ="https://movie.naver.com/movie/sdb/rank/rmovie.naver?sel=cur&date={date}"
response = urlopen(html.format(date=today.strftime("%Y%m%d")))
soup = BeautifulSoup(response, "html.parser")
end = len(soup.find_all("td", "point"))
movie_date.extend([today for _ in range(0, end)])
movie_name.extend([soup.find_all("div", "tit5")[n].a.string for _ in range(0, end)])
movie_point.extend([soup.find_all("td", "point")[n].string for _ in range(0, end)])
time.sleep(0.5)
- 데이터프레임으로 만들기, 이 데이터가 raw data가 된다.
movie = pd.DataFrame({
"data": movie_date,
"name": movie_name,
"point": movie_point
})
movie.head()
movie.info()
- point가 숫자가 아니라 object 타입!
movie["point"] = movie["point"].astype(float)
movie.info()
영화 평점 데이터 정리
import numpy as np
import pandas as pd
movie = pd.read_csv("./data/04_naver_movie_raw_data.csv")
movie.head()
- 영화 이름으로 인덱스를 잡고 점수의 합산을 구함, 100일 간 네이버 영화 평점 합산기준 베스트 10
movie_unique = pd.pivot_table(movie, index=["name"], aggfunc=np.sum)
movie_best = movie_unique.sort_values(by="point", ascending=False)
movie_best.head(10)
- 아래처럼 쓸 때 큰따옴표(" "), 작은따옴표(' ') 를 안과 밖 서로 다르게 구분해서 줘야 오류안생김
tmp = movie.query('name ==["1987"]')
tmp
movie_pivot = pd.pivot_table(movie, index=["date"], columns=["name"], values=["point"])
movie_pivot.columns = movie_pivot.columns.droplevel()movie_pivot.head()
시각화
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from matplotlib import rc
rc("font", family="Malgun Gothic")
%matplotlib inline
plt.figure(figsize=(20, 8))
plt.plot(tmp["date"], tmp["point"]);
plt.title("날짜별 평점")
plt.xlabel("날짜")
plt.ylabel("평점")
plt.xticks(rotation="vertical")
plt.legend(labels=['평점추이'], loc="best")
plt.show()
target_col = ["12 솔져스", "1987", "50가지 그림자: 해방"]
plt.figure(figsize=(20, 8))
plt.title("날짜별 평점")
plt.xlabel("날짜")
plt.ylabel("평점")
plt.xticks(rotation="vertical")
plt.tick_params(bottom="off", labelbottom="off")
plt.plot(movie_pivot[target_col])
plt.legend(target_col, loc="best")
plt.grid(True)