본문 바로가기
토이프로젝트/[크롤링] 네이버 영화 크롤링하기

[크롤링] 네이버에서 영화정보 가져오기 - #4 (방향잡기)

by 프룹 2022. 1. 2.
반응형

이번 시간에는 프로그램을 통해 사이트를 돌아다니면서 모든 영화의 정보를 가져오기 위해 필요한 작업에 대해 알아보고자 합니다.

 

 

앞으로 우리는 영화에서 위 붉은 박스에 해당하는 정보를 가져오려고 합니다. 

 -> 평점, 장르, 상영시간, 개봉일, 감독, 출연, 등급

이 되겠죠?

 

문제는 저 정보를 가져온다고 해도 네이버에 등록된 모든 영화를 어떻게 찾아가느냐가 문제가 됩니다. 각 영화마다의 url을 수동으로 등록해줄 수는 없으니! 먼저 각각의 영화를 찾아가는 방법에 대해 알아보고자 합니다!

 

1. 국가정보를 이용하기

네이버 영화에서 디렉터리를 보면 영화를 국가별로 모아놓은 것을 확인할 수 있다. 이때 '가봉'은 국가 코드가 GA인 것을 우측의 코드 영역을 통해 확인할 수 있다. 각 국가의 코드는 <dl> 태그 하위에 <a> 태그의 href에 쓰여있다.

즉, ㄱ국가는 총 12개 이므로 <a> 태그는 12개이다.

URL에서 nation에 GA라고 쓰면 '가봉'에서 만든 영화가 나오는 것을 확인할 수 있다.

그럼 우리는 사이트에서 국가코드를 가져오기 위한 코드를 짜면 된다. 앞선 강의에서 설명했는데, Inspector를 이용하면 쉽게 파싱 할 수 있다.

 

class 이름이 directory_item인 모든 <dl> 태그를 가져오면 된다. 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
import requests
from bs4 import BeautifulSoup
 
def getNation():
    url = 'https://movie.naver.com/movie/sdb/browsing/bmovie_nation.naver'
    response = requests.get(url)
 
    NationCode = {}
 
    if response.status_code == 200:
        html = response.text
        soup = BeautifulSoup(html, 'lxml')
        
        # html에서 dl 태그 중 class이름이 directory_item 태그를 찾아라
        directory_item = soup.findAll('dl','directory_item')
 
        # 각 directory_item에 대하여
        for item in directory_item:
            # 내부에 <a> 태그를 모두 찾아라
            for code in item.find_all('a'):
                # code : <a href="bmovie.naver?nation=IE">아일랜드</a>
                # code.text = 아일랜드
                NationCode[str(code.text)] = str(code).split('=')[2].split('"')[0]
    else : 
        print(response.status_code)
    
    # print(NationCode) # 확인용
    return NationCode
 
getNation()
cs

위 코드를 실행하면 다음과 같이 국가명과 코드가 딕셔너리 형태로 출력된다.

 

그럼 이 코드는 앞으로 Base URL에 국가 코드만 바꾸면 해당 국가 사이트의 내용을 크롤링할 수 있다.

https://movie.naver.com/movie/sdb/browsing/bmovie.naver?nation=KR

 

 

2. 각 국가의 영화코드 가져오기

국가코드 KR을 통해 한국영화 페이지로 들어가면 다음과 같이 각 영화 제목들이 나열된 걸 확인할 수 있다. 여기서 href를 보면 'code=177371'을 볼 수 있는데, 이 177371이 바로 0.0 MHz라는 영화의 고유 코드이다. 따라서 저 code만 알면 각 영화에 접근할 수 있다.

 

문제는 그 페이지의 개수인데, 첫 번째 페이지에서는 안 보였지만 페이지 버튼을 누르면 url에 page 파라미터도 생기는 걸 확인할 수 있다. 끝까지 넘어가려면 대충 큰 값 10000 정도를 넣으면 끝 페이지로 가진다. 그럼 우리는 1~1779페이지에 존재하는 모든 영화의 code를 파싱 해보면 되는 것이다. 그러려면 먼저

  1. 끝 페이지번호 알아오기

  2. 끝 페이지까지 code 파싱 하기

로 해야 할 일이 정해진다.

 

# 1. 끝 페이지번호 알아오기

class이름이 pagenavigation 중 <div> 태그를 가져온 후 <a> 태그 중 가장 마지막 태그의 값을 가져오면 된다.

 

# 2. 영화 code 파싱

class 이름이 directory_list 중 <ul> 태그를 가져온 후 모든 <a> 태그가 href만 가져오면 된다.

문제는 모든 <a>가 code가 아니라는 점이다. 가장 위에 <a>만 제대로 된 값을 얻을 수 있다. 

그러나 다행히도 가져와야 할 'code'는 한 번만 쓰이기 때문에 href에 'code' 단어의 존재 유무로 판단하면 된다. 다만, 영화 제목이 code가 있을 수 있으니 단순히 'code'가 있냐 없냐가 아니라 '? code='가 있냐 없냐로 판단하는 게 좋을 것 같다. 혹은 가장 위에 <a>가 code니 그냥 0번 인덱스만 가져와도 될 것 같다.

 

그래서 코드는 다음과 같다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
import requests
from bs4 import BeautifulSoup
 
def getNation():
    url = 'https://movie.naver.com/movie/sdb/browsing/bmovie_nation.naver'
    response = requests.get(url)
 
    NationCode = {}
 
    if response.status_code == 200:
        html = response.text
        soup = BeautifulSoup(html, 'lxml')
        
        # html에서 dl 태그 중 class이름이 directory_item 태그를 찾아라
        directory_item = soup.findAll('dl','directory_item')
 
        # 각 directory_item에 대하여
        for item in directory_item:
            # 내부에 <a> 태그를 모두 찾아라
            for code in item.find_all('a'):
                # code : <a href="bmovie.naver?nation=IE">아일랜드</a>
                # code.text = 아일랜드
                NationCode[str(code.text)] = str(code).split('=')[2].split('"')[0]
    else : 
        print(response.status_code)
    
    # print(NationCode) # 확인용
    return NationCode
 
def getMovieCodeByNation(NationCode):
 
    movieCode = []
 
    for key, val in NationCode.items():
        url = f'https://movie.naver.com/movie/sdb/browsing/bmovie.naver?nation={val}&page=10000'
 
        response = requests.get(url)
 
        if response.status_code == 200:
            html = response.text
            soup = BeautifulSoup(html, 'lxml')
            
            # html에서 div 태그 중 class이름이 pagenavigation 태그를 찾아라
            pagenavigation = soup.find('div','pagenavigation')
 
            # pagenavigation내 <a> 태그 중 마지막 태그의 text 값
            lastPage = pagenavigation.find_all('a')[-1].text
 
            for i in range(1int(lastPage)+1):
                url = f'https://movie.naver.com/movie/sdb/browsing/bmovie.naver?nation={val}&page={i}'
 
                response2 = requests.get(url)
                if response2.status_code == 200:
                    html = response2.text
                    soup = BeautifulSoup(html, 'lxml')
                    
                    # html에서 ul 태그 중 class이름이 directory_list 태그를 찾아라
                    directory_list = soup.find('ul','directory_list')
                    allA = directory_list.findAll('a')
                    for a in allA:
                        if '?code=' in str(a):
                            movieCode.append(str(a).split('?code=')[1].split('"')[0])
                else : 
                    print(response2.status_code)
        else : 
            print(response.status_code)
        
    return movieCode
 
 
movieCode = getMovieCodeByNation(getNation())
cs
반응형

댓글