본문 바로가기

웹 개발강의/파이썬 웹개발

[파이썬 웹개발] 5_1_GET,POST 연습 [무비스타]

무비스타

👉 폴더 구조

 

1. DB 데이터 셋팅(init_db.py)

import requests
from bs4 import BeautifulSoup

from pymongo import MongoClient

client = MongoClient('localhost', 27017)
db = client.dbsparta


# DB에 저장할 영화인들의 출처 url을 가져옵니다.
def get_urls():
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36'}
    data = requests.get('https://movie.naver.com/movie/sdb/rank/rpeople.nhn', headers=headers)

    soup = BeautifulSoup(data.text, 'html.parser')

    trs = soup.select('#old_content > table > tbody > tr')

    urls = []
    for tr in trs:
        a = tr.select_one('td.title > a')
        if a is not None:
            base_url = 'https://movie.naver.com/'
            url = base_url + a['href']
            urls.append(url)

    return urls


# 출처 url로부터 영화인들의 사진, 이름, 최근작 정보를 가져오고 mystar 콜렉션에 저장합니다.
def insert_star(url):
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36'}
    data = requests.get(url, headers=headers)

    soup = BeautifulSoup(data.text, 'html.parser')

    name = soup.select_one('#content > div.article > div.mv_info_area > div.mv_info.character > h3 > a').text
    img_url = soup.select_one('#content > div.article > div.mv_info_area > div.poster > img')['src']
    recent_work = soup.select_one(
        '#content > div.article > div.mv_info_area > div.mv_info.character > dl > dd > a:nth-child(1)').text

    doc = {
        'name': name,
        'img_url': img_url,
        'recent': recent_work,
        'url': url,
        'like': 0
    }

    db.mystar.insert_one(doc)
    print('완료!', name)


# 기존 mystar 콜렉션을 삭제하고, 출처 url들을 가져온 후, 크롤링하여 DB에 저장합니다.
def insert_all():
    db.mystar.drop()  # mystar 콜렉션을 모두 지워줍니다.
    urls = get_urls()
    for url in urls:
        insert_star(url)


### 실행하기
insert_all()

데이터 쌓기

 

2. 서버(app.py)

👉 GET방식 -> DB에 저장된 무비스타 보여주기
👉 POST방식 -> 선택한 무비스타 좋아요+1

👉 POST방식 -> 선택한 무비스타 삭제하기

from pymongo import MongoClient

from flask import Flask, render_template, jsonify, request

app = Flask(__name__)

client = MongoClient('localhost', 27017)
db = client.dbsparta


# HTML 화면 보여주기
@app.route('/')
def home():
    return render_template('index.html')


# API 역할을 하는 부분
@app.route('/api/list', methods=['GET'])
def show_stars():
    movie_star = list(db.mystar.find({},{'_id':False}).sort('like',-1))
    return jsonify({'movie_stars': movie_star})

@app.route('/api/like', methods=['POST'])
def like_star():
    name_receive = request.form['name_give']

    target_star = db.mystar.find_one({'name':name_receive})
    current_like = target_star['like']

    new_like = current_like + 1

    db.mystar.update_one({'name': name_receive}, {'$set': {'like': new_like}})

    return jsonify({'msg': '좋아요 완료!'})

@app.route('/api/delete', methods=['POST'])
def delete_star():
    name_receive = request.form['name_give']

    db.mystar.delete_one({'name': name_receive})

    return jsonify({'msg': '삭제 완료!'})


if __name__ == '__main__':
    app.run('0.0.0.0', port=5000, debug=True)

 

3. 클라이언트(index.html)

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8"/>
    <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
    <title>마이 페이보릿 무비스타 | 프론트-백엔드 연결 마지막 예제!</title>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bulma@0.8.0/css/bulma.min.css"/>
    <script defer src="https://use.fontawesome.com/releases/v5.3.1/js/all.js"></script>
    <style>
        .center {
            text-align: center;
        }

        .star-list {
            width: 500px;
            margin: 20px auto 0 auto;
        }

        .star-name {
            display: inline-block;
        }

        .star-name:hover {
            text-decoration: underline;
        }

        .card {
            margin-bottom: 15px;
        }
    </style>
    <script>
        $(document).ready(function () {
            showStar();
        });

        function showStar() {
            $.ajax({
                type: 'GET',
                url: '/api/list?sample_give=샘플데이터',
                data: {},
                success: function (response) {
                    let mystars = response['movie_stars']
                    for (let i = 0; i < mystars.length; i++) {
                        let name = mystars[i]['name']
                        let img_url = mystars[i]['img_url']
                        let recent = mystars[i]['recent']
                        let url = mystars[i]['url']
                        let like = mystars[i]['like']

                        let temp_html = `
                            <div class="card">
                                <div class="card-content">
                                    <div class="media">
                                        <div class="media-left">
                                            <figure class="image is-48x48">
                                                <img
                                                        src="${img_url}"
                                                        alt="Placeholder image"
                                                />
                                            </figure>
                                        </div>
                                        <div class="media-content">
                                            <a href="${url}" target="_blank" class="star-name title is-4">${name} (좋아요: ${like})</a>
                                            <p class="subtitle is-6">${recent}</p>
                                        </div>
                                    </div>
                                </div>
                                <footer class="card-footer">
                                    <a href="#" onclick="likeStar('${name}')" class="card-footer-item has-text-info">
                                        위로!
                                        <span class="icon">
                                      <i class="fas fa-thumbs-up"></i>
                                    </span>
                                    </a>
                                    <a href="#" onclick="deleteStar('${name}')" class="card-footer-item has-text-danger">
                                        삭제
                                        <span class="icon">
                                      <i class="fas fa-ban"></i>
                                    </span>
                                    </a>
                                </footer>
                            </div>
                        `

                        $('#star-box').append(temp_html)
                    }
                }
            });
        }

        function likeStar(name) {
            $.ajax({
                type: 'POST',
                url: '/api/like',
                data: {name_give: name},
                success: function (response) {
                    alert(response['msg']);
                    window.location.reload()
                }
            });
        }

        function deleteStar(name) {
            $.ajax({
                type: 'POST',
                url: '/api/delete',
                data: {name_give: name},
                success: function (response) {
                    alert(response['msg']);
                    window.location.reload()
                }
            });
        }

    </script>
</head>
<body>
<section class="hero is-warning">
    <div class="hero-body">
        <div class="container center">
            <h1 class="title">
                마이 페이보릿 무비스타😆
            </h1>
            <h2 class="subtitle">
                순위를 매겨봅시다
            </h2>
        </div>
    </div>
</section>
<div class="star-list" id="star-box">
</div>
</body>
</html>