#10 영화 데이터 크롤링

seojin's 개발블로그·2023년 8월 20일
0

영화 사이트 제작

목록 보기
10/19

📌 문제 상황

  1. 더미데이터로 영화 데이터 조회 테스트를 완료했으나 실제 영화 데이터를 넣어서 테스트하고 싶음
  2. 직접 등록하려니 너무 시간이 많이 소비됨

📌 해결

한 1년전쯤 했던 데이터 크롤링을 해보기로함

이용툴 : Colab
언어 : python
라이브러리 : requests, BeautifulSoup, json

라이브러리는 각각 데이터 요청을 위한 requests
html데이터를 객체화 시키기위한 BeautifulSoup
복붙해서 사용하기위해 json을 이용하였다.
requests 참고 블로그
BeautifulSoup 참고 블로그
Json 라이브러리 참고 블로그

1. 스켈레톤 코드 작성

import requests
from bs4 import BeautifulSoup
import json

def get_movie_info(url):
    response = requests.get(url)
    #해당 url이 응답을 해야함
    if response.status_code == 200:
        soup = BeautifulSoup(response.content, 'html.parser')

        # 필요한 정보를 추출하여 변수에 저장
        title = soup.select_one('')
        director = soup.select_one('')
        cast =soup.select_one('')
        country = soup.select_one('')
        genre = soup.select_one('')
        runtime = soup.select_one('')
        age = soup.select_one('')
        openingDate = soup.select_one('')
        content = soup.select_one('')
        
        # 영화 정보를 딕셔너리로 만듦
        movie_info = {
            'title': title,
            'director': director,
            'cast': cast,
            'country': country,
            'genre': genre,
            'runtime': runtime,
            'age': age,
            'openingDate': openingDate,
            'content': content
        }

        return movie_info
    else:
        return None

# 영화 URL
movie_url = ''

# 영화 정보 가져오기
movie_info = get_movie_info(movie_url)

to_json = json.dumps(movie_info, ensure_ascii=False, indent=4)

print(to_json)

위의 뼈대를 만들어놓고 후보 사이트들을 하나씩 대입해보기로 했다.

2. 후보 대입

I. 다음영화

  • 하단의 출연/제작탭의 데이터 추출이 안됨

    아래의 출연정보가 아마 동적인 데이터라서 추출이 안되는듯했다.

II. 왓챠피디아

  • 데이터 추출이 안됨 아마 모두 동적인 데이터는 아닐것같고 데이터추출을 웹에서 막고 있는듯 하다

III. cgv

  • 데이터 추출은 가능하지만 내가 이용할 정보들이 기본 정보라는 하나의 문자열로
    묶여있음

다음과 cgv를 같이 사용할까 하다가 결국 cgv에서만 크롤링을 하기로 결정했다.
데이터를 이용하는것이 아니라 페이지 자체에 정보들을 기입한것으로 보였다
그래서 전처리 과정이 좀 지저분해졌지만 두 웹을 이용하는것보다 코드를 재사용하기가 더 좋아보였고 자잘한? 파이썬 문법들을 다시 사용해보기 위함도 있었다.

3. 크롤링

import requests
from bs4 import BeautifulSoup
import json
from datetime import datetime


def get_movie_info(url):
    response = requests.get(url)
    if response.status_code == 200:
        soup = BeautifulSoup(response.content, 'html.parser')

        title = soup.select_one('#select_main > div.sect-base-movie > div.box-contents > div.title > strong').get_text().strip()
        director = soup.select_one('#select_main > div.sect-base-movie > div.box-contents > div.spec > dl > dd:nth-child(2) > a').get_text()
        cast_elements = soup.select('#select_main > div.sect-base-movie > div.box-contents > div.spec > dl > dd:nth-child(5) > a')
        cast_list = [cast_element.get_text().strip() for cast_element in cast_elements]
        cast = ', '.join(cast_list).replace(', ,', ',').replace(',  ,', ',').strip(', ')
        
        basic_info_element = soup.select_one('#select_main > div.sect-base-movie > div.box-contents > div.spec > dl > dd:nth-child(9)')
        basic_info_text = basic_info_element.get_text()
        basic_info_list = basic_info_text.split(',')
        age = basic_info_list[0].strip()
        runtime = basic_info_list[1].strip()
        
        country_genre = ','.join(basic_info_list[2:]).strip()
        countries = country_genre.split(' ')
        
        countries = countries[0]

        
        genre_element = soup.select_one('#select_main > div.sect-base-movie > div.box-contents > div.spec > dl > dt:nth-child(6)')
        genre_text = genre_element.get_text().strip()
        genre_list = [genre.strip() for genre in genre_text.split(',')]

        if genre_list[0].startswith("장르"):
            genre_list[0] = genre_list[0][5:] 


        openingDate = soup.select_one('#select_main > div.sect-base-movie > div.box-contents > div.spec > dl > dd:nth-child(11)').get_text()

        openingDate = datetime.strptime(openingDate, "%Y.%m.%d").strftime("%Y-%m-%d")

        content_element = soup.select_one('#menu > div.col-detail > div.sect-story-movie')
        content = content_element.text.strip() if content_element else ""

        movie_info = {
            'title': title,
            'director': director,
            'cast': cast,
            'age': age,
            'runtime': runtime,
            'countries': countries,
            'genre': genre_list,
            'openingDate': openingDate,
            'content': content
        }

        return movie_info
    else:
        return None

movie_url = 'http://www.cgv.co.kr/movies/detail-view/?midx=87175'
movie_info = get_movie_info(movie_url)

if movie_info:
    movie_json = json.dumps(movie_info, ensure_ascii=False, indent=4)
    print(movie_json)
else:
    print("영화 정보를 가져오지 못했습니다.")

추출 결과

{
    "title": "오펜하이머",
    "director": "크리스토퍼 놀란",
    "cast": "킬리언 머피, 에밀리 블런트, 맷 데이먼, 로버트 다우니 주니어, 플로렌스 퓨, 조쉬 하트넷, 케이시 애플렉, 라미 말렉, 케네스 브래너",
    "age": "15세이상관람가",
    "runtime": "180분",
    "countries": "미국, 영국",
    "genre": [
        "스릴러",
        "드라마"
    ],
    "openingDate": "2023-08-15",
    "content": "“나는 이제 죽음이요, 세상의 파괴자가 되었다.”\n세상을 구하기 위해 세상을 파괴할 지도 모르는 선택을 해야 하는 천재 과학자의 핵개발 프로젝트."
}

이제 영화 정보 등록을 위한 json을 자동으로 추출할 수 있게 되었다.
코드가 좀 지저분해 보이지만 지저분한 데이터를 전처리 하는것이라 어쩔수가 없었다,,,

출연진, 국가등도 각각 원소로 분리를 할까도 했지만 현재 만드는 서비스에서는
출연자별, 국가별 데이터를 제공할 예정이 없어서 일단 문자열로 넣기로 했다

📌 후기

오랜만에 파이썬을 써봤는데 역시 편리한것 같다.
필요한 기능이 있는 라이브러리가 모두 존재하고 사용하기도 간편하다

현재 프로젝트에서 꼭 필요한 부분은 아니지만 편리함을 위해 만들었는데
좀 뿌듯하다 다음에 진행할 프로젝트도 데이터를 참조할곳이 있다면 또 크롤링이 쓰이지
않을까 싶다

너무 간단해서 업무자동화라 해야할지도 모르겠지만 이런 자료 추출, 입력등은 파이썬이 정말 편리한 것 같다 간간히 잊지않게 공부를 해줘야겠다

profile
개발 공부하는 블로그

0개의 댓글