코딩 개발일지/웹개발 종합반(스파르타 코딩클럽)

<스파르타 코딩클럽 웹개발 종합반 4주차>

찐쥬 2023. 3. 12. 14:44

<웹개발 종합반 4주차 개발일지>

*엄청 긴 글 주의*

 

 

 

4주차 강의는 백엔드!

백엔드란 뭘까 궁금했었는데 드뎌 배워보게 된다.

 

 

 

서버 만들기

 

서버를 만드는건 굉장히 어려운 일!

그래서 어느정도 만들어져 있는 프레임워크를 이용해볼 것

이번에 사용해 볼 프레임워크는 Flask

 

 

폴더를 연다 -> app.py 파일을 만든다 -> 터미널을 켠다 -> 가상환경을 잡는다

-> 터미널에 'python3 -m venv venv' 입력한다(가상환경 잡힘) -> venv 폴더 확인한다

* 가상환경  : 프로젝트별로 라이브러리를 담아두는 폴더

-> 오른쪽 하단 python버전 클릭한다(3.8.6) -> (venv:venv)가 있는걸 선택한다

-> 터미널을 x표 눌러 꺼준 뒤, 다시 새터미널을 켜준다 -> 터미널에 (venv) 있는지 확인한다

-> 터미널에 pip install flask 프레임워크 설치

 

flask 시작 코드

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)

이대로 저장한 뒤 실행하면 되는데

은 이렇게 오류가 날때가 있다고 한다.

그럴땐 control + c 를 눌러주고, 코드에 port=5000을 port=5001로 바꿔주고 저장, 실행! 

 

브라우저 링크 입력창에 localhost:5001입력하면 이렇게 This is Home! 문구가 나온다

내 컴퓨터에서 내가 만든 웹서비스에 접속한 것

This is Home은 코드에 입력된 return 값!

코드에 내용을 수정하고 저장한뒤, 브라우저에서 새로고침을 하면 자동으로 바뀐다

 

 

from flask import Flask
app = Flask(__name__)

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

@app.route('/mypage')
def mypage():  # ㄴmypage 추가, home을 mypage로 바꿔줌
   return 'This is my Page!' #home을 page로 바꿔줌

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

코드에 위와같이 추가해서 저장한 뒤,

브라우저 링크 입력창에 localhost:5001/mypage 를 추가하면 아래와 같이 뜬다

localhost:5001 까지는 내 컴퓨터의 주소, /mypage 는 창구의 이름

 

 

추가로 버튼을 한 번 넣어본다면,

@app.route('/mypage')
def mypage():
   return '<button> 버튼입니다</button>'  # 버튼태그 추가

버튼 생성

짜잔, 버튼이 생성됐다.

그렇다는 건 return 값에 <html>을 입려해도 나온다는 의미!

 

그러나 저 코드에 전부 입력하면 힘들기 때문에, 백엔드와 프론트엔드를 다른 방식으로 연결해줘야한다.

다른 곳에 있는 html 파일을 저 안에 넣어주면 됨!

 

vscode에 templats 라는 폴더를 하나 만들어주고,

폴더 하위에 index.html 파일을 만들어준다.

 

코드스니펫에 저장된 index.html 예제파일을 우선 붙여놓고 저장!

 

 

다시 app.py 에 와서 , render_tamplate 를 추가해준다(flask에 있는 기능) 

from flask import Flask, render_template  # ,rendet_remplate 추가
app = Flask(__name__)

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

@app.route('/mypage')
def mypage():
   return render_template('index.html') # render_template('index.html') 추가

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

return 값에도 똑같이 render_template를 넣어주고, 괄호 안에 따옴표, ('html 파일명')을 입력 후 저장

하면 백엔드가 html을 불러와서 브라우저에 보여주게 되는 과정을 거치는 것

브라우저에 돌아가서 새로고침을 하면 정상적으로 떠....

 

(야 하는데............

나는 또 웬 처음보는 오류가 떠서 즉문즉답에 물어보면서 시간 날리는 중 ㅠ_ㅠ 엉엉

다른분들은 나랑 같은 오류가 났던적이 없는 것 같다. 와이라노!!!!!!!)

? 1시간을 저것때문에 즉문즉답에서 알려주시는대로 수정하고 실행하고x100 했는데도..

계속 오류만 떠서 그냥 전부 삭제하고 4주차 첨부터 다시 했다..

(진작 이렇게 할걸...)

다시 했더니 되네..........ㅎ................................... 난 똑같이 했는데.. 부들부들...

 

쨋든.. 버튼이 나왔고, index.html 파일 <body>부분에

<h1> 제목을 입력합니다</h1> 도 추가한 후 저장하고 실행했더니 위와 같이 떴다.

 

 

 

이제 본격적으로 api를 만들고

프론트 엔드가 api를 부르고, 데이터를 받는것에 대해 배워본다고 한다.

 

 

프론트엔드와 백엔드가 데이터를 받는데에는 여러가지 방법이 있음!

여태까지 배웠던건 get방식이었고, post를 추가로 배울것

 

get방식

데이터를 링크에 ?(물음표) 입력하면 url로 받는다.(key:values)

브라우저에 칠 수 있는 형태

통상적으로 데이터 조회를 요청할 때 사용한다

ex) 영화 목록 조회

 

 

post방식

데이터가 눈에 안보이고(보이지 않는 html),

컴퓨터끼리만 알아들을 수 있는 방식으로 데이터를 주고 받는다.

통상적으로 데이터를 생성, 변경, 삭제 요청할 때 사용한다

ex) 회원가입, 회원탈퇴, 비밀번호 수정

 

 

api를 만들고 사용하는 과정에서는

requestjsonify 두 가지 기능이 필요하다. 따라서 import에 추가

get요청 api코드를 복사해서 이전 app.py 파일에 붙여넣어주기

 

 

 

GET요청

*간단하게 설명해주신 순서도는 하기 코드에 주석으로 달았으니 참고!

# import에 request, jsonify 추가
from flask import Flask, render_template, request, jsonify
app = Flask(__name__)

@app.route('/')
def home():
   return render_template('index.html')

# get요청 코드 추가
@app.route('/test', methods=['GET']  # 1. /test라는 창구로 get요청으로 들어온다.
def test_get():
   title_receive = request.args.get('title_give')  # 2. 그때 title_give라는 데이터가 있으면
                                                   # 그 데이터를 가져와서 title_receive라는 변수에 넣어주고
   print(title_receive)  # 3. 개발자들이 볼 수 있게 출력을 해주자
   return jsonify({'result':'success', 'msg': '이 요청은 GET!'})
       # 4. 백엔드에서 프론트엔드로 데이터 내려주기를 어떻게 내려주냐면
       #    result는 success로, msg는 '이 요청은 get!'으로 내려준다

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

 

추가로 get요청 확인 fetch코드를 복붙해서 index.html 에 복붙해준다.

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
    <title>Document</title>

    <script>
        function hey() {  # get 요청 확인 fetch코드 복붙
            fetch("/test").then(res => res.json()).then(data => {
                console.log(data) # /test라는 url에 데이터를 요청해 받으면 
            })                    # 데이터를 consol탭에 보이게 해달라는 것
        }
    </script>
</head>

<body>
    <h1>제목을 입력합니다</h1>
    <button onclick="hey()">나는 버튼!</button>
</body>

* 붙여넣을 때 정렬이 잘못되면 쉬프트 + 옵션 + f (mac기준) 누르면 정렬됨

 

링크에 localhost:5000을 입력해서 들어간 뒤

나는 버튼! 을 클릭하고 콘솔탭을 열어보면,

이렇게 백엔드 app.py에 입력했던 return값이 나오는 걸 볼 수 있다.

 

get방식의 흐름은,

 

백엔드(app.py)에 있는 값이

return jsonify('result':'sucess', 'msg':'이 요청은 GET!')

프론트엔드(index.html)에 있는 

consol.log(data) 안에 들어온 것!

 

 

 

 

POST요청

from flask import Flask, render_template, request, jsonify
app = Flask(__name__)

@app.route('/')
def home():
   return render_template('index.html')

# post 요청 코드로 변경
@app.route('/test', methods=['POST']) 
def test_post():
   title_receive = request.form['title_give']
   print(title_receive)
   return jsonify({'result':'success', 'msg': '이 요청은 POST!'})

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

index.html 에도 마찬가지로, function 내용에 post요청 코드 복붙

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
    <title>Document</title>

    <script>
        function hey() {    # post 요청 코드로 변경
            let formData = new FormData();
            formData.append("title_give", "블랙팬서");

            fetch("/test", { method: "POST", body: formData }).then(res => res.json()).then(data => {
                console.log(data)  # { method: "POST", body: formData }가 추가되었음
            })                     # post는 formdata를 만들어서, 거기에 데이터를 실어서 보냄
        }
    </script>
</head>

<body>
    <h1>제목을 입력합니다</h1>
    <button onclick="hey()">나는 버튼!</button>
</body>

</html>

이후 마찬가지로 브라우저 가서 링크들어가고, 버튼클릭

콘솔확인

터미널에 '블랙펜서' 프린트 확인

 

 

post방식의 흐름은,

(긴 흐름 주의)

 

버튼을 클릭하면 프론트엔드(index.html)에 데이터가 쌓이게 됨

                                                                               function hey() {
                                                                                           let formData = new FormData();
                                                                                           formData.append("title_give", "블랙팬서"); <- 데이터가 쌓임

 

formdata를 담아가지고 /test 라고 하는데에 보냄(fetch)

fetch("/test", { method: "POST", body: formData }).then(res => res.json()).then(data => {
                console.log(data)

 

백엔드(app.py)에서 프론트엔드의 데이터를 받음 /test

@app.route('/test', methods=['POST'])

 

백엔드가 받은 상태에서 title_give가 있는지 있는지 프론트엔드에서 찾아본다

title_receive = request.form['title_give']

 

프론트엔드에 가서보니 있네?

formData.append("title_give", "블랙팬서"); (프론트엔드 코드)

 

그럼 백엔드에 title_receive 변수가 프론트엔드의 블랙팬서 데이터를 받아오고, 프린트

                                                                            title_receive = request.form['title_give'] (= "블랙팬서")
                                                                            print(title_receive)

그리고 다 끝났으니, 이거를 내려줘라

return jsonify({'result':'success', 'msg': '이 요청은 POST!'})

 

내려온 데이터가 어디로 담기냐면? 프론트엔드의 consol.log(data)안으로

 console.log(data)

 

백엔드에서 보낸 데이터가 프론트엔드 fetch의 결과에 담긴다는 것!

끝..!

 

..선생님이 알려주신 설명대로 눈으로 차근차근 따라가보긴 했으나

post는 여기갔다 저기갔다 복잡하긴 한 것 같다,,?

 

 

 

화성땅 공동구매 실습!

 

우선 새폴더 열고,

app.py 새파일을 만들어서 가상환경 잡아주기

추가로 templates 폴더 추가 생성하고 하위에 index.html 폴더 만들기

app.py 파일로 들어가서 필요한 라이브러리 설치하기

pip install flask

pip install pymongo

pip install dnspython

 

코드스니펫에 app.py과 index.html 코드 복붙해서 저장하고

mongodb 에 로그인

로그인 후 browse collections 클릭

전에 만들었던 users movies 지워주기

 

다시 vscode로 들어와서 app.py를 실행하고,

브라우저에 localhost:5000 을 입력하면, 만들어 놓은 html을 볼 수 있다.

준비완료 상태!

 

 

우선, 데이터를 저장하고 불러오기를 할건데

기본적으로 저장하기와 불러오기가 있으면 저장하기를 먼저 해놓는게 좋다고 한다!

불러오기를 먼저하면 데이터가 없기 때문에 제대로 되는건지 확인이 안된다는 것

 

이번 실습의 순서

이름, 주소, 평수 데이터를 넣고 주문하기를 누르면

이걸 fetch로 데이터를 가지고 서버로 넘어가고,

서버에서 데이터베이스에 저장을 하든 뭐든.. 알아서 처리가 되면

잘 저장됐음! 이라는 데이터를 다시 받아온 후

브라우저에서 alert로 잘 저장됐다고 합니다! 를 띄워주면 됨

마지막에 refresh 한 번 해주면 끝!

 

1) 데이터 명세

이름, 주소, 평수를 보내야한다

2) 클라이언트와 서버 연결 확인하기

프론트엔드 코드에 어떤 버튼이 들어가 있는지 봐야한다

html 뼈대에 주문하기 버튼이 있고 save_order() 가 있음을 확인

save_order() 스크립트로 올라가 보면 '샘플데이터'를 만들었고

sample_give라는 이름으로 어떤 데이터를 주고 있는 걸 확인

그 데이터를 실어다가 /mars에 요청을 보냄(프론트->백)

백엔드 post 코드에 /mars 이름으로 데이터가 받아오는걸 확인하고

sample_give라는 데이터를 찾으려 프론트엔드에 가서 다시 찾음

프론트엔드에서 sample_give데이터에는 '샘플데이터'가 있고

그 '샘플데이터'가 백엔드 sample_receive 변수의 데이터로 들어옴

sample_receive를 출력했으니 터미널에 찍힐 것이고

마지막으로 'msg : post 연결 완료'를 내려줄 거임(백->프론트)

저 내려준 'msg'가 프론트에 콘솔로그안의 데이터로 들어와서 콘솔탭에 찍히고

data['msg']의 벨류값이 alert의 값으로 들어가서

브라우저에 'post 연결 완료' 가 뜰 것임

3) 서버부터 만들기

서버가 할 일은 이름, 주소, 평수 를 받아서 db에 넣어주면 됨

app.py에 이름, 주소, 평수를 받는 변수를 생성해주고

def mars_post():
    name_receive = request.form['name_give']
    address_receive = request.form['address_give']
    size_receive = request.form['size_give']

pymongo를 활용해서 DB에 넣어준다

이전 mongodb 연습 파일을 꺼내와서 import 값을 붙여넣어주고

from pymongo import MongoClient
client = MongoClient('mongodb+srv://sparta:test@cluster0.ukydtzw.mongodb.net/?retryWrites=true&w=majority')
db = client.dbsparta

DB에 저장하기 위해, 저장하는 코드를 복붙해와 doc 값을 바꿔준다

    doc = {
        'name' : name_receive,
        'address' : address_receive
        'size' : size_receive
    }
    db.users.insert_one(doc)

추가로 users라는 콜렉션 이름 대신 mars 로 바꿔주면 됨

    db.mars.insert_one(doc)

추가로 저장버튼 눌렀을 때 post 저장 완료 라고 뜨는것보다,

직관적으로 저장완료가 나을것같으니 msg의 벨류값을 수정해줌

return jsonify({'msg':'저장완료'})

4) 클라이언트 만들기

index.htmldp 가서 이제 save_order를 수정하면 됨

이름에 대한 input 값, 주소에 대한 input 값, 그리고 선택한 평수 값을

sample_give처럼 담아서 넘겨주는게 클라이언트의 역할

name에 입력한 input 값을 가져와야 하기 때문에,

save_order function에 저 input값을 지정해줘야한다.

jquery로 해야하니 id=name을 지정하고($('id명')) .val() 하면 값을 가져온다함

function save_order() {
            let name = $('#name').val()

나머지 주소, 평수도 마찬가지로 id값을 찾아 변수로 지정해주면 됨

  let name = $('#name').val()
        let address = $('#address').val()
   let size = $('#size').val()

이제 저장한 데이터를 줘야하니, append에 변수를 넣어줌

let formData = new FormData();
            formData.append("name_give", name);
            formData.append("address_give", address);
            formData.append("size_give", size);

콘솔탭은 찍을 필요 없으니 지우기

다시 브라우저에 localhost:5000 을 새로고침해서 들어가고,

이름, 주소, 평수를 선택한 후 저장을 누른다.

몽고디비에 들어가 refresh를 누르면 데이터베이스에 저장된 것을 확인.

이름, 주소, 평수를 저장했을 때 데이터베이스가 자동 refresh눌러졌음 한다면

index.html fetch 아래에 window.location.reload() 추가

            fetch('/mars', { method: "POST", body: formData }).then((res) => res.json()).then((data) => {
                alert(data["msg"])
                window.location.reload()

저장완료가 잘뜨고, 몽고디비에도 잘올라간걸 확인할 수 있다.

데이터를 넣는 것까지 하였으니,

이제 데이터를 읽어 브라우저 하단에 나타나게 붙여줘야함

(휴....주문하기를 누르면 저장완료가 떠야하는데,

또 무슨 오류가 난건지 alert가 뜨질 않고, 몽고디비에도 올라가질 않았다.ㅠ

다시 즉문즉답 시간이 돌아와서.. 몽고디비 연결할 때 안되서 추가로 넣었던 코드를

넣어보라 하셔서 따라하니 잘 작동된다..

몽고디비... 때문에 데이터베이스에서 두 발자국 멀어진 느낌이랄까,,.싫다 저 녀석..,)

 

ㅡ_ㅡ..........................

저기 위에까지 쓰고 한.. 4일?만에 들어와서 다시 강의듣고 이후 작업 열심히 정리했는데

갑자기 멈춰서 다 날라갔음,하아-!!!!!!!!!!!!!!!!!!11

정말.,,,... 다시 쓰기 번거롭지만 대강 생각나는 포괄적인 순서를 적겠다.

서버와 클라이언트가 연결되는지 확인하기 위해

선착순 공동구매 사이트를 열었을 때 index.html에서 show_order가 실행되는 걸 볼 수 있음

index.html에서 /mars라고 하는 곳에 보냄.

app.py 에 get방식에 /mars를 확인해보면, msg : get 연결 완료! 라는 문구를 내려줌

다시 index.html 에 가보면 그 값을 콘솔에 한 번 찍고, msg의 값을 alert 시키는 걸 알 수 있음

마찬가지로, 서버 먼저 만들면됨(서버 : 우리가 갖고있는 데이터를 다 내려주는 것)

app.py get요청에 몽고디비의 데이터값을 다 내려주면됨.

다 내려주는 코드를 이전 몽고디비 코드 작성한 것에서 복붙하면됨

(데이터를 다 받아온 뒤, 그 값을 클라이언트로 싹 내려주는 것)

# 여러개 찾기 - 예시 ( _id 값은 제외하고 출력)
all_users = list(db.users.find({},{'_id':False}))

users를 데이터베이스 콜렉션 이름 mars로 바꿔주고, 변수 이름도 mart_data로 바꿔줌

@app.route("/mars", methods=["GET"])
def mars_get():
    mars_data = list(db.mars.find({},{'_id':False}))
    return jsonify({'result':mars_data})

그 데이터들을 result 라는 변수에 넣어주고, result를 index.html에서 받으면 됨

function show_order() {
            fetch('/mars').then((res) => res.json()).then((data) => {

concsole(data)

우선 저장후 웹사이트에 새로고침을 해서 콘솔에 값이 찍히는지 확인해보면

리스트로 잘 올라간걸 볼 수 있음(리스트? -> 반복)

index.html에 우선 콘솔은 이제 지우고 data의 'result' 값(app.py에서 result로 저장함)을 가져옴

해당 값을 rows의 변수로 받아 rows를 반복문으로 돌리면됨.

전에 여러번 한 것처럼 반복문으로 돌리고, temp_html ``을 만들어서

index.html의 어느 부분에 붙일 것인지 형태를 복사해와 붙여주고

rows를 돌려 받은 값을 각각의 변수로 지정해주고(name, address, size) temp_html에 붙임

이후 id값을 찾아와 $('#아이디값').append(temp_html)해주면 됨

기존에 있던 데이터들은 없어져야하니,  $('#아이디값').empty 해주고 저장!

function show_order() {                                          
            fetch('/mars').then((res) => res.json()).then((data) => {
                let rows = data['result']                                         
                $('#order-box').empty()                                         
                  rows.forEach((a)=>{                                                  
                    let name = a['name']                          
                     let address = a['address']                   
                    let size = a['size']                                
 
                    let temp_html = `<tr>                        
                                                  <td>${name}</td> 
                                                    <td>${address}</td>
                                                 <td>${size}</td> 
                             </tr>`
                    $('#order-box').append(temp_html)  

5) 완성 확인하기

몽고DB에 저장된 내역이 브라우저에 잘 뜨는 걸 확인할 수 있음

 

전체적인 정리..!

프론트엔드에서 액션이 있음

(로딩이 되면 부른다던지, 뭘 띄운다던지)

그럼 프론트엔드에서 서버쪽으로 날림

서버쪽에서 액션을 해줌

(데이터베이스에서 저장을 한다던가, 데이터를 읽어다 준다던가)

다시 서버에서 클라이언트 쪽으로 데이터(fetch 끝나고 data)를 내려줌

요 데이터가 들어오면, 클라이언트가 작업함

(붙이기도하고, alert로 띄우기도 하는 것)

 

 

이까지하면,, 프로젝트 1완성..

강의를 보는데 텀이 넘 길어서 다시 하려니까 앞에 내용이 하나도 기억 안났다 ㅠ_ㅠ

프로젝트 3가지를 해본다고 하니 여러번 반복해보면 나아지겠지?ㅠ

 

 

 

 

스파르타 피디아!

 

새로운 프로젝트를 시작하려면 해야할 기초작업!

새폴더 열고, app.py 파일 생성

가상환경 만들기 python3 -m venv venv

오른쪽 하단 (venv) 있는 버전 클릭후 다시 새터미널 열기

templates 폴더 만들기

templates 하위에 index.html 파일 만들기

라이브러리 깔기 pip install flask pymongo dnspython requests bs4

 

 

이 후 서버 만들기 전에,

내가 모르는 기능을 구현해 본 다음에 내가 아는 기능을 만들어야함!

내가 하는 기능부터 만들었다가 나중에 모르는 기능을 추가했는데 에러가 나면

어디서 에러가 나는지 찾기가 어려움

그렇기 때문에, 영화 url을 붙여 넣었을 때(크롤링)

자동으로 이미지, 제목, 영화설명이 나오는 잘 모르겠는 작업부터 만들어보기

 

 

조각기능!

url만 붙였는데, 이미지 제목 설명이 나오는 경우

이런 것들을 og image, og title, og description 이라고 부른다.

 

크롤링 기본코드

import requests
from bs4 import BeautifulSoup

url = 'https://movie.naver.com/movie/bi/mi/basic.naver?code=191597'

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

# 여기에 코딩을 해서 meta tag를 먼저 가져와보겠습니다.

위에 링크를 타고 들어가면 보스베이비 영화가 뜨는데,

오른쪽마우스 - 검사 클릭하여 head 부분을 보면 meta라는 태그가 많은 걸 볼 수 있다.

head의 역할 : 우리 눈에는 보이지 않지만 뭔가 필요한 정보들을 담고 있다.

 

크롤링하기 위해선, 뷰티풀숩을 이용해야 하는데, 오늘 새로 배우는 크롤링 방법

ogtitle = soup.select_one('meta[property="og:title"]')

soup.select_one까지는똑같고, 원래는 검사에서 copy selector를 이용해서 위치를 붙였는데

오늘은 다른 방법을 알려주심!

'meta[]' <- 메타 태그인데~

[property="og:title"] <- 프로펄티가 오지 타이틀인 것을 가져와라.

하단에 print(ogtilte) 을 해보면 <meta content="보스 베이비 2" property="og:title"/> 가 나옴

print(ogtitlt['content']) 를 해주면 보스 베이비 2 출력!

 

동일한 방법으로 제목, 이미지, 설명 모두 가져오면 됨

ogtitle = soup.select_one('meta[property="og:title"]')['content']
ogdesc = soup.select_one('meta[property="og:description"]')['content']
ogimage = soup.select_one('meta[property="og:image"]')['content']
print(ogtitle,ogdesc,ogimage)

이제 요렇게 만든 코드 조각을

app.py에 서버를 만들면서 사용할 것!

 

서버 만들기 시작

app.py 코드 복붙, index.html 코드 복붙, 몽고디비로그인 준비

 

 

데이터를 쌓는 것 먼저!(post)

 

영화 url과 코멘트를 받아서,

받은 url을 기반으로 제목 이미지 설명을 가져온 다음에

url 코멘트까지 다 해서 db에 넣어주면 된다.

 

app.py의 이 부분부터 하면 된다. url과 코멘트 받으면 됨

#app.py 수정전
@app.route("/movie", methods=["POST"])
def movie_post():
    sample_receive = request.form['sample_give']
    print(sample_receive)
    return jsonify({'msg':'POST 연결 완료!'})
#app.py 수정후-1
@app.route("/movie", methods=["POST"])
def movie_post():
    url_receive = request.form['url_give'] #내가 받아야 하는 것으로 수정
    comment_receive = request.form['comment_give'] #내가 받아야 하는 것으로 수정

    return jsonify({'msg':'POST 연결 완료!'})

 

이후 크롤링 만든 코드를 가져와야 하기 때문에,

위에 보스베이비 크롤링코드 만든 것을 가져와 추가해준다

(app.py 제일 위에 라이브러리도 임포트해줘야함)

import requests
from bs4 import BeautifulSoup

#app.py 수정후-2
app.route("/movie", methods=["POST"])
def movie_post():
    url_receive = request.form['url_give']
    comment_receive = request.form['comment_give']
    # headers 부터 크롤링 만든 것 가져온것
    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) #url -> url_receive로 바꿔주기

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

    ogtitle = soup.select_one('meta[property="og:title"]')['content']
    ogdesc = soup.select_one('meta[property="og:description"]')['content']
    ogimage = soup.select_one('meta[property="og:image"]')['content']

    return jsonify({'msg':'POST 연결 완료!'})

추가로, 사용자가 써넣은 url을 받아와야 하기 때문에.

data 부분의 url을 url_receive로 바꿔준다

data = requests.get(url_receive,headers=headers)

 

다음에 url, comment, ogtitile, ogdesc, ogimage를 DB에 보내줘야함.

그렇다는건? db입력 코드 불러와서 복붙하기

(동일하게 라이브러리 임포트 해줘야함)

from pymongo import MongoClient
import certifi
ca = certifi.where()
client = MongoClient('mongodb+srv://(아이디:비번)@cluster0.ukydtzw.mongodb.net/?retryWrites=true&w=majority',tlsCAFile=ca)
db = client.dbsparta

 

 

불러온 다음에? document만들어서 insert_one 해주면 됨

#app.py 수정후-3
@app.route("/movie", methods=["POST"])
def movie_post():
    url_receive = request.form['url_give']
    comment_receive = request.form['comment_give']

    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_receive,headers=headers)

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

    ogtitle = soup.select_one('meta[property="og:title"]')['content']
    ogdesc = soup.select_one('meta[property="og:description"]')['content']
    ogimage = soup.select_one('meta[property="og:image"]')['content']

    doc = {                # DB에 저장하기 위해 딕셔너리 형태 doc 만들기
        'title' : ogtitle,  # 이름과, 내가 저장한 변수로 값 붙여주기
        'desc' : ogdesc,    # 필요한 5개 전부!
        'iamge' : ogimage,
        'url' : url_receive,
        'comment' : comment_receive,
    }

    db.movies.insert_one(doc)  # DB 저장하기 코드 복붙해주고 users대신 movies로 콜렉션이름만들기

    return jsonify({'msg':'POST 연결 완료!'})

백엔드 서버 만들기는 완성

 

 

이제 클라이언트 만들기

index.html 에 가서 함수 실행되는 곳 찾기

#index.html 수정전
        function posting() {
            let formData = new FormData();
            formData.append("sample_give", "샘플데이터");

            fetch('/movie', { method: "POST", body: formData }).then((res) => res.json()).then((data) => {
                console.log(data)
                alert(data['msg'])
            })

사용자가 입력한 url과 comment를 받아야 하기 때문에,

url이 들어가는 코드를 찾으면 됨

#index.html url, comment가 필요한 곳 찾기

    <div class="mypost" id="post-box">
        <div class="form-floating mb-3">
            <input id="url" type="email" class="form-control" placeholder="name@example.com">
            <label>영화URL</label> #여기!! 위에 input 부분 보면 url이라는 id 가 있음
        </div>
        <div class="form-floating">
            <textarea id="comment" class="form-control" placeholder="Leave a comment here"></textarea>
            <label for="floatingTextarea2">코멘트</label> #코멘트도 마찬가지로 id값이 comment

id 값을 찾은 뒤, 위 포스팅 함수 안에 변수로 지정해 넣어주기

let url = 

let comment =

 

하단에 있는 id를 불러오려면, id지정후 .val()

# index.html 수정후-1
        function posting() {
            let url = $('#url').val() #하단에 있는 id 값을 불러오려면, $('#id명').val() 하면됨
            let comment = $('#comment').val() #코멘트도 마찬가지

            let formData = new FormData();
            formData.append("sample_give", "샘플데이터");

            fetch('/movie', { method: "POST", body: formData }).then((res) => res.json()).then((data) => {
                console.log(data)
                alert(data['msg'])
            })

이제 url, comment를 지정해서 잘 가져오면,

데이터를 formdata에 넣어서 보내줘야함.

# index.html 수정후-2
 function posting() {
            let url = $('#url').val()
            let comment = $('#comment').val()

            let formData = new FormData();
            formData.append("url_give", url); # 우리가 만든 url을 보내줘야하니, 값으로 넣어주기
            formData.append("comment_give", comment); # comment도 마찬가지

            fetch('/movie', { method: "POST", body: formData }).then((res) => res.json()).then((data) => {
                console.log(data) #콘솔에 굳이 찍을 필요없으니 요것도 지워버리기
                alert(data['msg']) #app.py에 가서 msg 문구 '저장완료!'로 바꿔주기
            })
        }

fetch에 있는 콘솔을 굳이 찍을 필요가 없으니 지워주고,

alert로 띄우는 msg를 app.py에 가서 보니

return jsonify({'msg':'POST 연결 완료!'}) 라고 뜨는걸 확인

문구도 굳이 저 문구가 뜰 필요 없으니 ' 저장완료'로 바꿔준다

 

이쯤에서 테스트!

스파르타 피디아 웹사이트 가서 새로고침 눌러주고

영화 기록하기 클릭해서 아무거나 영화 url 넣어주고, 코멘트 달아 기록하기 클릭

저장완료! 로 바꾼 문구 뜨는것 확인 ok

 

몽고DB에 들어가서 refresh 눌러주고 확인하면

movies 콜렉션 생성되고, 안에 데이터가 잘 들어간 걸 볼 수 있다.

title, desc, image, url, comment

 

몽고 db가 자동으로 refresh 되도록 구현하는 것 추가!

# index.html 수정후-3
        function posting() {
            let url = $('#url').val()
            let comment = $('#comment').val()

            let formData = new FormData();
            formData.append("url_give", url);
            formData.append("comment_give", comment);

            fetch('/movie', { method: "POST", body: formData }).then((res) => res.json()).then((data) => {
                alert(data['msg'])
                window.location.reload() #자동으로 refresh 되는 코드 추가!
            })
        }

여기까지 하면 데이터 쌓는 것 끝!!!1

(오, 두 번 해보니까 좀 기억나고 이해 되는듯하다?!)

 

 

이젠 데이터를 가져와 챡챡챡 붙여주는 것 하면 완성!(get)

 

처음에 해야할 것은,

웹사이트 들어갔을 때 로딩이 완료되면 자동으로 카드들이 착착챡 붙는 것.

(로딩완료시 fetch를 날려서 결과를 가지고 카드를 붙여주는 작업)

 

index.html의 이부분을 수정하면 됨

# index.html 수정전
   <script>
        $(document).ready(function () {
            listing();
        });

        function listing() {
            fetch('/movie').then((res) => res.json()).then((data) => {
                console.log(data)
                alert(data['msg'])
            })

 

서버부터 만들기!

# app.py 수정전
@app.route("/movie", methods=["GET"])
def movie_get():
    return jsonify({'msg':'GET 연결 완료!'})

 

서버에서 할일은? 영화를 다 가져와서 내려주면 되는 것

몽고db 에서 데이터 다 가져오는 코드 복붙!

all_users = list(db.users.find({},{'_id':False}))

# app.py 수정후-1
@app.route("/movie", methods=["GET"])
def movie_get():
    all_movies = list(db.movies.find({},{'_id':False})) # 콜렉션 이름 바꿔주고, 변수 이름도 바꿔주기
    return jsonify({'result':all_movies}) #메세지를 가져올 필요 없으니 result란 변수 만들고, 무비스 데이터 값으로 받기

요렇게 데이터를 받아오면 서버의 역할은 끝!

 

index.html에서 저 result값을 받아와야 하기 때문에 코드 수정

#index.html 수정후-1
    <script>
        $(document).ready(function () {
            listing();
        });

        function listing() {
            fetch('/movie').then((res) => res.json()).then((data) => {
                let rows = data['result'] # rows 변수 생성후, data의 result값 받아오기
                console.log(rows) # 콘솔로 rows 찍어서 확인해보기
            })
        }

콘솔에 잘찍히는지 테스트!

 

웹사이트에서 새로고침 후 검사들어가서 콘솔에 잘 찍히는지 확인해 보기(영화 2개 저장했음)

리스트로 2개 들어가 있음을 확인!

 

리스트? -> 반복문 돌려서 빼내기!

# index.html 수정후-2
        function listing() {
            fetch('/movie').then((res) => res.json()).then((data) => {
                let rows = data['result']
                rows.forEach((a)=>{ #for문 돌리기
                    let comment = a['comment'] # 빼내야할 데이터 변수 지정해주기
                    let title = a['title']
                    let desc = a['desc']
                    let image = a['image']
                    console.log(comment,title,desc,image) #콘솔로 찍어서 테스트
                })
            })
        }

다시 웹사이트 새로고침해서 테스트!

title, comment, desc, iamge가 잘 찍혀 나오는 것 확인 완!

 

그렇다면?

이제 들어가야 하는 부분 찾아서 넣어줘야함 temp_html!

#index.html 수정후-3
function listing() {
            fetch('/movie').then((res) => res.json()).then((data) => {
                let rows = data['result']
                $('#cards-box').empty()  # 기존에 있던 내용 삭제
                rows.forEach((a) => {
                    let comment = a['comment']
                    let title = a['title']
                    let desc = a['desc']
                    let image = a['image']

                    let temp_html = `<div class="col"> # 해당되는 영역 복붙
                                        <div class="card h-100">
                                            <img src="${image}" #데이터 들어갈부분 @{변수명} 지정
                                                class="card-img-top">
                                            <div class="card-body">
                                                <h5 class="card-title">${title}</h5>#데이터 들어갈부분 @{변수명} 지정
                                                <p class="card-text">${desc}</p>#데이터 들어갈부분 @{변수명} 지정
                                                <p>⭐⭐⭐</p>
                                                <p class="mycomment">${comment}</p>#데이터 들어갈부분 @{변수명} 지정
                                            </div>
                                        </div>`
                    $('#cards-box').append(temp_html) # 카드 들어가는 부분 id 찾아서 append 해주기
                })
            })
        }

다시 저장 후 테스트!

잘 찍히는 것 확인 완료!

 

(요 과정에서 이미지가 안뜨고 오류나서 뭔가... 하고 코드를 봤떠니

app.py에 내가 iamge라고 오타가 났더라!

그래서 수정하고 저장후 다시 실행했는데도 반영이 안되길래 남자친구한테 물어봤눈데

데이터베이스에 가보라니까 거기에 iamge라고 저장이 되어있더라!

쿄쿄, 데이터베이스는 독립적이라 새로 업데이트를 하지 않으면 수정이 안된다길래

데이터 데이스에 수정하는 부분이 있어서 image로 바꿨더니 제대로 떴당^,^ 남자친구 쵝오)

 

 

새로운 영화 추가해서 기록하기 누르니 저장완료! 가 뜨고

알아서 새로고침이 되어 영화 3가지가 뜨는걸 볼 수 있었다.

 

 

여기까지 하고, 별점 추가하는 것 숙제!

 

index.html에 가서 별점이 들어가야하는 부분 코드스니펫 복붙해서 넣어주고,

백엔드를 각자!

 

 

 

쿄쿄, 사실 코드 저장되있는거 복붙해서 없는것 찾아보고 똑같이 하니..

내가 직접 머리 굴려서 푼것보다,ㅎ 그냥 있는대로 배낀 것 같은데

하긴 했음!ㅋ

 

 

이렇게 4주차 끝!

이렇게 포스팅이 길어질 줄이야,,

시간차가 많아서 내가 쓰는 말투나 설명이 뒤죽박죽일 것 같은데, 읽기 구찮아서 그냥 막 올리려함.ㅎ

여튼! 확실히 백엔드 프론트엔드 왔다갔다 하니 복잡하나 여러번 하니까 익숙해지는 것 같다.

앞으로 남은 실습 2가지 화이탱!!!!!!