semtax의 개발 일지

예매 알리미 프로젝트 1 : 메가박스 영화목록 & 잔여좌석 크롤링 본문

개발/Python

예매 알리미 프로젝트 1 : 메가박스 영화목록 & 잔여좌석 크롤링

semtax 2020. 1. 27. 15:59
반응형

개요

이번 시리즈에서는 사용자가 등록한 메가박스 영화의 잔여좌석을 조회해서 알려주는 프로젝트를 진행할 예정입니다.

이번 포스팅에서는, 메가박스 영화 잔여좌석 목록을 크롤링하는 크롤링 함수를 제작할 예정입니다.

메가박스 데이터 수집

일단, 메가박스에서, 영화목록 및 영화 잔여좌석 목록을 어떻게 가져오는지 분석을 해봅시다.

먼저, 아래와 같이 크롬 브라우저로 메가박스에 접속을 해줍시다. 그런 뒤, F12로 개발자 도구를 켜서 네트워크 탭을 클릭한 상태로 예매버튼을 눌러줍시다. 그리고, XHR 탭을 클릭해 줍시다.

그러면은 위 그림과 같이 메가박스 예매버튼을 클릭했을때, 크롬 개발자 도구를 통해 HTTP를 이용해서 서버와 브라우저간에 어떤 데이터가 왔다갔다 하는지 확인할 수 있습니다.

계속해서 개발자 도구를 킨 상태에서 영화관 선택, 보고싶은 영화목록 선택 등을 해줍시다.

그러고 난 뒤, 개발자도구의 네트워크 탭에 쌓인 로그들을 오른쪽 클릭을 이용해 HAR으로 저장해줍시다..

(사실 크롬 브라우저에서 바로 봐도 되기는 합니다.)

분석

그럼 이제 저장한 데이터를 분석해보도록 합시다.

사실 메가박스와 같은 경우, 데이터를 요청하는 로직이 아래와 같이 매우 간단한 편입니다.

(편의를 위해 json 형식으로 표시하였습니다. 실제로는. HTTP POST form 형식으로 인자를 요청합니다.)

    param_data = {
        "siteCode" : 36,
        "startNo" :    0,
        "count"    : 999,
        "playDate" : "2019-01-24",
        "cinemaCode1" : 1003,
        "movieTypeYn_all" : "Y",
        "movieTypeYn_2D" : "N",
        "movieTypeYn_3D" : "N",
        "movieTypeYn_dubbing" : "N",
        "movieTypeYn_caption" : "N",
        "movieTypeYn_atmos" : "N",
        "_command" : "Booking.getBookingMovieListByDate"
    }
...

    param_data = {
        "siteCode" : 36,
        "startNo" :    0,
        "count"    : 999,
        "playDate" : "2019-01-24",
        "cinemaCode1" : 1003,
        "movieCode1" : 016882,
        "movieTypeYn_all" : "Y",
        "movieTypeYn_2D" : "N",
        "movieTypeYn_3D" : "N",
        "movieTypeYn_dubbing" : "N",
        "movieTypeYn_caption" : "N",
        "movieTypeYn_atmos" : "N",
        "_command" : "Booking.getBookingMovieListByDate"
    }

각 변수별 의미는 아래 표와 같습니다

필드명 의미
sitecode 불명(하지만 36으로 고정해놓고 쓰면 상관없을듯 합니다.)
startNo 몇 번째 부터 조회할것인지
count 조회 개수(몇개 가져 올건지)
cinemaCode1 영화관 코드(각 지점별로 영화관 코드가 구분되어있음, 1030번은 동대문점을 의미함)
movieCode1 영화 코드(각 영화별로 지정된 코드를 의미합니다)
movieTypeYn_all 모든 종류의 영화를 조회할것인지?
_command 요청 종류(영화 목록을 가져올건지, 영화 시작시간을 가져올건지 등등)

개발자도구로 얻은 데이터를 조금만 분석해보면 알 수 있는 사실이긴 하지만,

1차적으로는 결국 "getFilteredBookingMovieList" 요청만 있으면 된다는 사실을 알 수 있습니다.

(결국 원하는 영화의 잔여좌석을 계속 체크하면 되는거니깐요)

"getFilteredBookingMovieList"의 응답 데이터는 아래와 같습니다.

{
   "resultIP":"137",
   "resultCode":"0000",
   "screenList":[
      {
         "totalSeatCnt":258,
         "cinemaCode":"1003",
         "cinemaName":"동대문",
         "remainSeatCnt":0,
         "screenName":"7관",
         "playTimeType":"0",
         "endTime":"22:10",
         "filmRating":"00",
         "startTime":"19:00",
         "movieCode":"016882",
         "event1":"",
         "event2":"",
         "event3":"",
         "event4":"",
         "showMovieCode":"016882",
         "showSeq":6,
         "screenCode":"07",
         "eventName3":"",
         "eventName4":"",
         "eventName1":"",
         "koreanTitle":"[라이브뷰잉] Pastel*Palettes Special Live Manmaru Oyamani Irodori Special☆~",
         "eventName2":"",
         "playDate":"2020-01-27",
         "runningTime":180,
         "showMovieType":"40",
         "sale_close_yn":"Y,매진",
         "movieTypeName":"라이브뷰잉",
         "screenImage":"0"
      },
      {
         "totalSeatCnt":180,
         "cinemaCode":"1003",
         "cinemaName":"동대문",
         "remainSeatCnt":0,
         "screenName":"8관",
         "playTimeType":"0",
         "endTime":"22:10",
         "filmRating":"00",
         "startTime":"19:00",
         "movieCode":"016882",
         "event1":"",
         "event2":"",
         "event3":"",
         "event4":"",
         "showMovieCode":"016882",
         "showSeq":6,
         "screenCode":"08",
         "eventName3":"",
         "eventName4":"",
         "eventName1":"",
         "koreanTitle":"[라이브뷰잉] Pastel*Palettes Special Live Manmaru Oyamani Irodori Special☆~",
         "eventName2":"",
         "playDate":"2020-01-27",
         "runningTime":180,
         "showMovieType":"40",
         "sale_close_yn":"Y,매진",
         "movieTypeName":"라이브뷰잉",
         "screenImage":"0"
      },
     ....
   ],
   "resultMessage":"정상처리"
}

각 변수별 의미는 아래 표와 같습니다.

필드명 의미
totalSeatCnt 총 좌석수
screenName 상영관
koreanTitle 제목
runningTime 상영시간
screenList 영화를 상영하는 상영관 관련 정보 목록
cinemaName 영화관 지점 이름

이제 이 요청을 python requests를 이용해서 그대로 복제해서 던져주면 데이터를 잘 가져올 수 있습니다.

크롤링 함수 작성

크롤링 함수작성은 매우 간단합니다.

requests.post 함수에, 요청할 url과 request parameter만 넣어서 함수를 호출하면 되기 때문입니다.

코드는 아래와 같습니다.

def getFilteredBookingMovieList(date, cinema_code):
    param_data = {
        "siteCode" : 36,
        "startNo" :    0,
        "count"    : 999,
        "playDate" : date,
        "cinemaCode1" : cinema_code,
        "movieTypeYn_all" : "Y",
        "movieTypeYn_2D" : "N",
        "movieTypeYn_3D" : "N",
        "movieTypeYn_dubbing" : "N",
        "movieTypeYn_caption" : "N",
        "movieTypeYn_atmos" : "N",
        "_command" : "Booking.getBookingMovieListByDate"
    }
    req = requests.post(url,data = param_data)
    return req.json()

실행해보면 정상적으로 json데이터를 잘 받아오는것을 알 수 있습니다.

다음 포스팅에서는, 키워드에 포함된 영화 목록 가져오기 기능 및 잔여좌석이 생겼을때 알림 기능, 그리고 일정 주기마다 해당 기능들을 실행하는 부분을 구현하도록 하겠습니다.

반응형
Comments