ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Python] API 로 받아온 JSON 을 파싱하여 DB 에 저장하기
    Python/미니 프로젝트 : LINK Cinema 2019. 12. 23. 02:26

    'LINK Cinema' 의 메인화면은 현재 상영중인 영화의 리스트를 보여주는 화면인데, 처음에는 어떻게 구성해야 할 지 난감했다. 

    영화진흥원의 API 를 쓸까 하다가, 다른 곳의 API 가 Return 값이 더 좋아보여서 다른 곳의 API 를 사용해보기로 했다.

    사실 어느 API 든 다른 곳에서 개발한 Open API 를 사용해보는 것이 내 목표여서 사실 큰 상관은 없었다.

     

    사용하는 Open API

    https://developer.movieglu.com/

    전세계 영화관과 영화 정보를 API 로 제공하는 곳인데, 일정 호출 건 수까지는 무료여서 사용해보기로 했다. 

    가입을 하고 메일로 API 를 사용할 수 있는 Key 를 얻었다.

    여기서 내가 사용한 API 는 'GET filmsNowShowing' 으로 미국의 현재 상영중인 영화의 Data 를 사용해보기로 했다.

     

    The API for Movies, Theaters and Showtimes | Easy to use API's for building apps and websites

    The API for Movies, Theaters and Showtimes. A range of APIs from films now showing, to today’s showtimes at your nearest movie theater. Try for free

    developer.movieglu.com


    직접 만든 API

    오늘 직접 구현한 서비스에서 사용할 API 는 하단의 두 가지.

    • MovieGlu 의 'GET filmsNowShowing' API 를 통해 가져온 Data 를 파싱해서 원하는 것만 내 MongoDB 에 저장하는 post_now_showing

    • DB 에 저장된 영화 정보를 조회하는 get_now_showing

     

     

    Step 1) 'GET filmsNowShowing' API 호출

    @app.route('/movieList', methods=['POST'])
    def post_now_showing():
    # movieGlu 의 GET filmsNowShowing 받기
       url = "https://api-gate2.movieglu.com/filmsNowShowing/?n=10"
       apikey = "xxxx"
       geolocation = "51.510408;-0.130105"
       authorization = "xxxx"
       params = {"client" : "xxxx",
                 "x-api-key" : apikey,
                 "Authorization" : authorization,
                 "api-version" : "v200",
                 "geolocation" : geolocation,
                 "territory" : "US",
                 "device-datetime" : "2018-09-14T08:30:17.360Z"}
       movieList = requests.get(url, headers= params).json()
       movies = movieList["films"]

    API 호출에 필요한 Header 값은 params 로 정리하여 request 를 날렸다. (보안을 위해 일부는 가렸다.)

    파이썬으로 API Header 를 작성하는 법을 몰라서 한참을 구글링했다. 

    requests 를 날릴 때 'headers' 를 꼭 표기해주고, params 의 Key 값은 꼭 'GET filmsNowShowing' API 명세의 Headers (mandatory) 항목은 모두 채워서 날려야 한다. 

    'device-datetime' 을 현재 Device 의 Time 으로 설정해주면 현재 미국에서 상영중인 영화의 리스트를 가져올 수 있겠지만, 우선은 임의의 날짜와 시간을 넣어보았다.

    받아온 Return 값은 movieList 에 저장.

     

     

     

    Step 2) 받은 Data 를 원하는 형태로 Parsing 하여 DB 에 저장

     db.movies.remove({})
    
     for film in movies:
        movieTitle = film["film_name"]
        movieReleaseDate = film["release_dates"][0]["release_date"]
        movieAge = film["age_rating"][0]["rating"]
        movieImage = film["images"]["poster"]["1"]["medium"]["film_image"]
        movieDescription = film["synopsis_long"]
    
        movie = {'Title': movieTitle, 'Age Rating':movieAge, 'Release Date': movieReleaseDate, 'Poster': movieImage, 'Description': movieDescription}
        db.movies.insert_one(movie)
        
      return jsonify({'result': 'success'})

    받은 movies 에서 하나씩 돌면서 영화 제목, 상영 일자, 영화 등급, 포스터 이미지, 설명을 DB 에 저장한다. 

    Parsing 할 때 주의할 것은 'GET filmsNowShowing' API Return 되는 JSON Format 을 잘 타고 들어가야 한다. (여기서 나도 에러가 나서 조금 고생했다 ㅠㅠ)

     

     

    Step 3) DB 에 저장된 Data 를 조회하는 API 구현

    @app.route('/movieList', methods=['GET'])
    def get_now_showing():
       all_movies = list(db.movies.find({}, {'_id': 0}))
       return jsonify({'result': 'success', 'info': all_movies})

    post_now_showing API 를 통해 DB 에 저장된 모든 영화의 정보를 조회한다. 

    DB 의 id 값은 제외하고 조회.

    info 에 모든 영화의 리스트가 담긴다.

     

     

    Step 4) Front 화면과 연결하기

    $(document).ready(function(){
    	$('#cards-container-row').html('');
    	movieList();
    });
    
    function makeList() {
    	$.ajax({
    		type: "POST",
    		url: "/movieList",
    		data: {},
    		success: function(response){
    			if(response['result'] == 'success'){
    				alert('영화 리스트 갱신!');
    				window.location.reload();
    			}
    		}
    	})
    }
    
    function movieList() {
    	$.ajax({
    		type: "GET",
    		url: "/movieList",
    		data: {},
    		success: function(response){
    			let movie = response['info'];
    			for (let i = 0 ; i < 8 ; i++){
    				makeCard(movie[i]["Title"], movie[i]["Description"], movie[i]["Age Rating"], movie[i]["Poster"])
    			}
    		}
    	})
    }
    
    function makeCard(title, description, age, poster) {
    	let temp_card =
    		'<div class="card" style="width: 16rem;">\
    			<img class="card-img" src="'+ poster +'" alt="Card image cap">\
    			<div class="card-body">\
    			<h5 class="card-title" style="text-align: center">'+ title +'</h5>\
    			<h6 class="card-subtitle mb-2 text-muted" style="text-align: center">'+ age +'</h6>\
    			<p class="card-text">'+ description +'</p>\
    			<a href="#" class="card-link">See Details</a>\
    			<a href="#" class="card-link">Get Tickets</a>\
    		</div>';
    	$('#cards-container-row').append(temp_card);
    }

    프론트 HTML 에서 위의 javascript 코드를 넣어주었다. 총 3개의 함수가 있는데, 각 함수의 역할은 아래와 같다.

    • makeList() : 내가 만든 'post_now_showing' API 를 통해 영화 리스트를 갱신하여 DB 에 저장한다. movieGlu 의 API 는 무료로 호출할 수 있는 횟수가 제한되어 있으므로 무작정 호출했다가는 무료 횟수를 다 쓸 것 같아서 원할 때만 새로 호출하여 DB 에 저장할 수 있도록 버튼을 만들어서 연결하였다.

    • movieList() : 내가 만든 'get_now_showing' API 를 통해 DB 에 저장된 Data 를 조회한다. 

    • makeCard() : 영화마다 조회한 Data 를 Front 의 Card 에 넣어주고, Card List 에 append 한다. 이 과정에서 당연한 거지만 HTML 에 jQuery 가 import 되어 있어야 한다 ㅠㅠ

     

    화면에서 확인하면 아래와 같다. 데이터가 잘 담긴 것 같긴 한데.. 모양이 마음에 안들어서 디자인은 나중에 손봐야겠다. 

    일단은 기능에 집중하는 것으로..

     

    영화 리스트 조회

    댓글

Designed by Tistory.