스파르타 코딩 클럽 내일 배움단 - 웹개발 5주차

스파르타 코딩 클럽 내일 배움단 10일 차 일지

오늘로 스파르타 코딩 클럽 내일 배움단 10일간의 혈투 끝에 웹개발 5주차까지 마무리하게 되었다.

웹개발 기준 분량이 하루에 8편씩 열리는게 2주차에 딱 떨어지게 만들어졌구나 싶다. (나는 주말도 포함해서 10일 했지만 평일 5일씩 2주하면 10일이니)

5주차에는 초반에 간단한 API 복습 이후, 실 서버 세팅에 대한 내용을 다룬다.

지금까지 머리를 싸매는 연속이었는데 이건 명령어도 많지 않고 따라하기만 되서 나름 편하게 넘어갔다.

 

이렇게 앱개발 웹개발 5주차를 마무리 했다.

스파르타 메이킹 챌린지가 언제 시작될지는 모르겠지만 메이킹 챌린지까지 참여할 생각이다.

그 전까지는 공부를 많이 해둬야겠다.

 

학습 내용

1. 무비스타 만들어보기

2. AWS를 이용해 서버 구축하기

3. 쇼핑몰 업로드 해보기

 

1. 무비스타 만들어보기

무비스타 DB 만들기

당장 DB에 데이터가 없으므로 영화배우들의 데이터를 네이버 영화에서 가져오는 파이썬 코드

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()

 

코드 그대로 붙여넣고 실행하면 DB에 데이터가 구성된다.

 

 

무비스타 기본 코드

< app.py >

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():
    sample_receive = request.args.get('sample_give')
    print(sample_receive)
    return jsonify({'msg': 'list 연결되었습니다!'})


@app.route('/api/like', methods=['POST'])
def like_star():
    sample_receive = request.form['sample_give']
    print(sample_receive)
    return jsonify({'msg': 'like 연결되었습니다!'})


@app.route('/api/delete', methods=['POST'])
def delete_star():
    sample_receive = request.form['sample_give']
    print(sample_receive)
    return jsonify({'msg': 'delete 연결되었습니다!'})


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

 

< templates/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) {
                        alert(response['msg']);
                    }
                });
            }

            function likeStar(name) {
                $.ajax({
                    type: 'POST',
                    url: '/api/like',
                    data: {sample_give:'샘플데이터'},
                    success: function (response) {
                        alert(response['msg']);
                    }
                });
            }

            function deleteStar(name) {
                $.ajax({
                    type: 'POST',
                    url: '/api/delete',
                    data: {sample_give:'샘플데이터'},
                    success: function (response) {
                        alert(response['msg']);
                    }
                });
            }

        </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 class="card">
                <div class="card-content">
                    <div class="media">
                        <div class="media-left">
                            <figure class="image is-48x48">
                                <img
                                        src="https://search.pstatic.net/common/?src=https%3A%2F%2Fssl.pstatic.net%2Fsstatic%2Fpeople%2Fportrait%2F201807%2F20180731143610623-6213324.jpg&type=u120_150&quality=95"
                                        alt="Placeholder image"
                                />
                            </figure>
                        </div>
                        <div class="media-content">
                            <a href="#" target="_blank" class="star-name title is-4">김다미 (좋아요: 3)</a>
                            <p class="subtitle is-6">안녕, 나의 소울메이트(가제)</p>
                        </div>
                    </div>
                </div>
                <footer class="card-footer">
                    <a href="#" onclick="likeStar('김다미')" class="card-footer-item has-text-info">
                        위로!
                        <span class="icon">
              <i class="fas fa-thumbs-up"></i>
            </span>
                    </a>
                    <a href="#" onclick="deleteStar('김다미')" class="card-footer-item has-text-danger">
                        삭제
                        <span class="icon">
              <i class="fas fa-ban"></i>
            </span>
                    </a>
                </footer>
            </div>
        </div>
    </body>
</html>

 

무비스타 목록 구현하기

< app.js > - show_stars()

@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})

 

< templates/index.html > - 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)
            }
        }
    });
}

 

 

무비스타 좋아요 구현하기

< app.js > - like_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.js > - likeStar()

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

 

무비스타 삭제하기 구현하기

< app.js > - delete_star()

@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': '삭제 완료!'})

 

< app.js > - deleteStar()

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

 

2. AWS를 이용해 서버 구축하기

AWS는 아마존에서 제공해주는 가상서버를 이용할 수 있게 해주는 서비스이다.

회원가입을 하면 무료 서버를 1년 정도 사용할 수 있으며, 1년 사용 이후에는 비용이 추가적으로 청구될 수 있으니

학습 이외 불필요할때는 서버를 종료해주는게 좋다.

 

무료 서버를 구매한 뒤 (무료서버 성능은 기대하지 않는 것이 좋다), SSH를 통해 접속한다.

 

AWS 이용하기

터미널 명령어 입력

ssh -i 받은키페어를끌어다놓기 ubuntu@AWS에적힌내아이피

 

리눅스 명령어 기본

ls: 내 위치의 모든 파일을 보여준다.

pwd: 내 위치(폴더의 경로)를 알려준다.

mkdir: 내 위치 아래에 폴더를 하나 만든다.

cd [갈 곳]: 나를 [갈 곳] 폴더로 이동시킨다.

cd .. : 나를 상위 폴더로 이동시킨다.

cp -r [복사할 것] [붙여넣기 할 것]: 복사 붙여넣기

rm -rf [지울 것]: 지우기

sudo [실행 할 명령어]: 명령어를 관리자 권한으로 실행한다.
sudo su: 관리가 권한으로 들어간다. (나올때는 exit으로 나옴)

 

 

FileZilla 이용하기

아마존에서 얻은 키파일을 사용해서 로그인한다.

 

 

테스트할 파일(test.py)을 루트 디렉토리에 넣은 뒤, 파이썬 파일 테스트

# home 디렉토리로 이동
cd ~

# 실행. 콘솔창에 hellow world!가 뜨는 것을 확인 할 수 있습니다.
python3 test.py

 

파이썬 개발환경 한번에 만들기

아래 파일을 만든 뒤 파일질라로 업로드한다.

< initial_ec2.sh >

# UTC to KST
# 컴퓨터의 시간대를 한국으로
sudo ln -sf /usr/share/zoneinfo/Asia/Seoul /etc/localtime

# python3 -> python
# python3 명령어를 python으로
sudo update-alternatives --install /usr/bin/python python /usr/bin/python3 10

# pip3 -> pip
# pip3 설치 및 pip3 명령어를 pip로
sudo apt-get update
sudo apt-get install -y python3-pip
pip3 --version
sudo update-alternatives --install /usr/bin/pip pip /usr/bin/pip3 1

# port forwarding
# 포트 포워딩 -> 80 포트로 들어오면 5000포트를 넘겨줌
sudo iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j REDIRECT --to-port 5000

# MongoDB - install
# MongoDB 설치
wget -qO - https://www.mongodb.org/static/pgp/server-4.4.asc | sudo apt-key add -
echo "deb [ arch=amd64,arm64 ] https://repo.mongodb.org/apt/ubuntu bionic/mongodb-org/4.4 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-4.4.list
sudo apt-get update
sudo apt-get install -y mongodb-org

sudo mkdir -p /data/db

# MongoDB - run
sudo service mongod start
sleep 7
netstat -tnlp

# MongoDB set user, set conf file
mongo admin --eval 'db.createUser({user: "test", pwd: "test", roles:["root"]});'
sudo sh -c 'echo "security:\n  authorization: enabled" >> /etc/mongod.conf'
sudo sed -i "s,\\(^[[:blank:]]*bindIp:\\) .*,\\1 0.0.0.0," /etc/mongod.conf

# MongoDB 재시작
sudo service mongod stop
sudo service mongod start
sleep 5
netstat -tnlp

 

권한 설정후 실행 (이후, python3 명령어를 python으로 쳐도 됨)

sudo chmod 755 initial_ec2.sh
python test.py

 

FLASK 서버 임시 실행해보기

아래의 샘플 코드로 app.py 파일을 만든 뒤 파일질라로 서버에 업로드 해주기

< app.py >

from flask import Flask
app = Flask(__name__)

@app.route('/')
def home():
   return 'This is Home!'

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

 

ssh로 명령어 입력

# 실행
python app.py

 

pip로 패키지 설치

pip install flask

 

3. 쇼핑몰 업로드 해보기

Robo 3T를 사용해서 AWS MongoDB에 연결해서 DB 잘 뜨는지 확인

 

app.py에서 mongodb 연결 코드 수정

< app.py >

client = MongoClient('mongodb://아이디:비밀번호@localhost', 27017)

 

AWS에서 pymongo설치

# 설치하기
pip install pymongo

 

SSH 접속을 끊어도 서버가 유지되게끔 설정하기 (nohup)

# 아래의 명령어로 실행하면 된다
nohup python app.py &

 

이후, 서버 종료를 하려면? 프로세스를 찾은 뒤 프로세스 번호로 강제종료 시켜줘야 한다

# 아래 명령어로 미리 pid 값(프로세스 번호)을 본다
ps -ef | grep 'app.py'

# 아래 명령어로 특정 프로세스를 죽인다
kill -9 [pid값]

 

 

도메인 구입하기

도메인은 한국 도메인 사이트에서 필요한 것 구하기

가비아 - https://www.gabia.com/

 

웹을 넘어 클라우드로. 가비아

그룹웨어부터 멀티클라우드까지 하나의 클라우드 허브

www.gabia.com

호스팅KR - https://hosting.kr/

 

글로벌 IT 파트너 - 호스팅케이알(HK)

KISA 고객만족도 최다 선정, 도메인 최저가 제공, 기업/공공도메인, 도메인연결/웹호스팅 무료, 서버, 아마존클라우드(AWS), G Suite, 홈페이지제작 1644-7378

www.hosting.kr

 

도메인 호스트 설정 해주기

 

OG 태그로 카카오톡이나 메신저에서 사전정보 표시되게 하기

<meta property="og:title" content="내 사이트의 제목" />
<meta property="og:description" content="보고 있는 페이지의 내용 요약" />
<meta property="og:image" content="{{ url_for('static', filename='ogimage.png') }}" />
 

공유 디버거 - Facebook for Developers

공유 디버거를 사용하면 Facebook에 공유될 때 콘텐츠가 표시되는 모습을 미리 보거나 오픈 그래프 태그를 사용하여 문제를 디버깅할 수 있습니다. 이 도구를 사용하려면 Facebook에 로그인하세요.

developers.facebook.com

 

 

카카오계정 로그인

여기를 눌러 링크를 확인하세요.

accounts.kakao.com

 

 

5주 과정을 갖고 2주간의 길고 긴 학습이 드디어 끝이 났다.

앞으로 한 1~2주간은 지금까지 배운 과정을 복습 하는 기간이 필요할 것 같다.

 

2일 뒤에 웹/앱 5주과정을 모두 듣고 난 후기를 남기도록 하겠다.

+ Recent posts