서버는 워드, 포토샵 같은 컴퓨터에서 돌아가는 하나의 프로그램이다!
우리는 컴퓨터가 1대이기 때문에 같은 컴퓨터에 서버도 만들고, 요청도 하게된다.
즉 클라이언트 = 서버가 되는 것인데 이것을 "로컬 개발환경"이라고 한다.

프로젝트 만들 폴더의 위치를 설정해주고 venv가 잘 써져 있는지 check! python3.8 check! 맨 아래 체크박스 해제 check! 해주고 만들어준다.
그 다음에 우선 app.py 파일 하나 만들어준다.
✔ 서버를 구동시켜주는 편한 코드 모음이다.
✔ 대부분의 개발자들은 서버를 만들때 flask 프레임워크를 사용한다.
이때 라이브러리와 프레임워크는 남이 만들어놓은 것을 가져다 쓰는 것은 같지만, 프레임 워크는 남이 짜둔 하나의 틀 안에서 내가 코딩을 자유롭게 하는 것, 라이브러리는 코딩을 하다가 남이 만들어놓은 라이브러리를 중간에 갖다쓴다는 차이가 있다.
✔ flask 설치 : setting - pythoninterpreter - flask 검색 후 install
프레임워크를 쓸때는 정해진 규칙들을 따라야하는데, 이때 flask는 정해진 폴더 구조를 따라야한다.
[ project ]
ㄴ static (이미지, css파일을 넣어둠)
ㄴ templates (html파일을 넣어둠) -> 중요!!
ㄴ app.py
서버를 돌아가게 하는 python 파일의 이름은 통상적으로 app.py 라고 짓는다.
app.py 파일에 넣고 시작!
from flask import Flask
app = Flask(__name__)
## URL 별로 함수명이 같거나,
## route('/') 등의 주소가 같으면 안됩니다.
@app.route('/')
def home():
return 'This is Home!'
if __name__ == '__main__':
app.run('0.0.0.0',port=5000,debug=True)
run 하고 localhost:5000을 열면 서버가 잘 들어오는 것을 확인할 수 있다.
from flask import Flask
app = Flask(__name__)
@app.route('/')
def home():
return 'home 입니다!'
@app.route('/mypage')
def mypage():
return 'mypage 입니다!'
if __name__ == '__main__':
app.run('0.0.0.0',port=5000,debug=True)
@app.route('/')부분을 수정해 URL을 나눌 수 있다.
📌 이때 URL별로 route('/')내의 주소( ,mypage)와 함수명(home,mypage)이 달라야한다.

URL을 바꿔주면 화면이 달라지는 것을 확인 할 수 있다 !
✔ flask 내장함수인 render_tamplate를 이용한다.
from flask import Flask, render_template ##render_template를 불러와줌
app = Flask(__name__)
@app.route('/')
def home():
return render_template('index.html')
if __name__ == '__main__':
app.run('0.0.0.0', port=5000, debug=True)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h3> 나는 index.html이다 ! </h3>
</body>
</html>

서버를 돌리고 브라우저에 localhost:5000을 쳐서 접속하여 확인하면 index.html 내용을 받아와서 보여주는 것을 확인할 수 있다.
✔ 서버가 클라이언트의 요청을 받기 위해 만들어 놓은 창구
✔ 규칙과 그에 해당하는 주소가 있음
API는 은행이 고객을 받기 위해 만들어 놓은 창구와 같은 개념으로 이해!(입금을 하려면 입출금창구로 가는 것처럼)
또한 은행에 창구마다 '주민등록증은 꼭 가져오세요.'와 같은 규칙이 있는 것처럼 API도 규칙이 있고 그에 해당하는 주소가 있다.
◽ GET
✔ 데이터 조회(read)를 요청할 때 사용
✔ ex) 영화 목록 조회
◽ POST
✔ 데이터를 변경할 때 사용 -> 생성(create), 변경(update), 삭제(delete)
✔ ex) 회원가입, 회원탈퇴
이때 서버에 뭔가를 요청할 때는 Ajax로 call 한다는 것을 기억!
우리는 서버에서 API를 만들고, 클라이언트에서 Ajax로 요청을 한다.
이때 import 부분에 request , jsonify를 더해준다.
from flask import Flask, render_template, request, jsonify
그 다음 GET API코드를 넣어준다.
@app.route('/test', methods=['GET'])
def test_get():
title_receive = request.args.get('title_give')
print(title_receive)
return jsonify({'result':'success', 'msg': '이 요청은 GET!'})
# 결과
봄날은 간다
$.ajax({
type: "GET",
url: "/test?title_give=봄날은간다",
data: {},
success: function(response){
console.log(response)
}
})
// 결과
{msg: '이 요청은 GET!', result: 'success'}
코드를 해석해보자면
고객(클라이언트)이 ajax로 call을 하고, ajax로 가져온 것을 창구(api)에서 받아 처리를 하고 response를 서버에게 줌. 그러면 ajax가 response를 consloe.log 볼 수 있도록 하는 로직이다.
흠 이 로직을 이해하는 것이 어렵하고 하는데..... 정말 어렵구만....알거 같으면서도 모를거 같은 느낌이랄까...?
@app.route('/test', methods=['POST'])
def test_post():
title_receive = request.form['title_give']
print(title_receive)
return jsonify({'result':'success', 'msg': '이 요청은 POST!'})
# 결과
봄날은 간다
$.ajax({
type: "POST",
url: "/test",
data: { title_give:'봄날은간다' },
success: function(response){
console.log(response)
}
})
// 결과
{msg: '이 요청은 POST!', result: 'success'}
ㄴ static
ㄴ temlates
ㄴ app.py

✔ flask : 서버구동을 위한 프레임워크
✔ pymongo : 데이터베이스를 조작하기 위한 라이브러리
⭐️ 순서확인!
✔ 클라이언트와 서버 확인
✔ 서버부터 만들기
✔ 클라이언트 만들기
✔ 완성 확인하기
▶️ 클라이언트와 서버 확인
서버 코드
## API 역할을 하는 부분
@app.route('/review', methods=['POST'])
def write_review():
sample_receive = request.form['sample_give']
print(sample_receive)
return jsonify({'msg': '이 요청은 POST!'})
클라이언트 코드
<script>
function makeReview() {
$.ajax({
type: "POST",
url: "/review",
data: {sample_give:'샘플데이터'},
success: function (response) {
alert(response["msg"]);
window.location.reload();
}
})
}
</script>
▶️ 서버 만들기
1. 클라이언트가 준 title, author, review 가져오기.
2. DB에 정보 삽입하기
3. 성공 여부 & 성공 메시지 반환하기
@app.route('/review', methods=['POST'])
def write_review():
# title_receive로 클라이언트가 준 title 가져오기
title_receive = request.form['title_give']
# author_receive로 클라이언트가 준 author 가져오기
author_receive = request.form['author_give']
# review_receive로 클라이언트가 준 review 가져오기
review_receive = request.form['review_give']
# DB에 삽입할 review 만들기
doc = {
'title': title_receive,
'author': author_receive,
'review': review_receive
}
# reviews에 review 저장하기
db.bookreview.insert_one(doc)
# 성공 여부 & 성공 메시지 반환
return jsonify({'msg': '리뷰가 성공적으로 작성되었습니다.'})
▶️ 클라이언트 만들기
1. input에서 title, author, review 가져오기
2. 입력값이 하나라도 없을 때 alert 띄우기.
3. Ajax로 서버에 저장 요청하고, 화면 다시 로딩하기
function make_Review() {
// 화면에 입력어 있는 제목, 저자, 리뷰 내용을 가져옵니다.
let title = $("#title").val();
let author = $("#author").val();
let review = $("#bookReview").val();
// POST /review 에 저장(Create)을 요청합니다.
$.ajax({
type: "POST",
url: "/review",
data: { title_give: title, author_give: author, review_give: review },
success: function (response) {
alert(response["msg"]);
window.location.reload();
}
})
}
▶️ 완성 확인하기
제목, 저자, 리뷰 작성 후 '리뷰 작성하기' 버튼을 눌렀을 때 '리뷰가 성공적으로 작성되었습니다'는 alert이 뜬다.

⭐️ 마찬가지로 순서확인!
✔ 클라이언트와 서버 확인
✔ 서버부터 만들기
✔ 클라이언트 만들기
✔ 완성 확인하기
▶️ 서버 만들기
1. DB에서 리뷰 정보 모두 가져오기
2. 성공 여부 & 리뷰 목록 반환하기
@app.route('/review', methods=['GET'])
def read_reviews():
# 1. DB에서 리뷰 정보 모두 가져오기
reviews = list(db.bookreview.find({}, {'_id': False}))
# 2. 성공 여부 & 리뷰 목록 반환하기
return jsonify({'all_reviews': reviews})
▶️ 클라이언트 만들기
1. 리뷰 목록을 서버에 요청하기
2. 요청 성공 여부 확인하기
3. 요청 성공했을 때 리뷰를 올바르게 화면에 나타내기
function showReview() {
$.ajax({
type: "GET",
url: "/review",
data: {},
success: function (response) {
let reviews = response['all_reviews']
for (let i = 0; i < reviews.length; i++) {
let title = reviews[i]['title']
let author = reviews[i]['author']
let review = reviews[i]['review']
let temp_html = `<tr>
<td>${title}</td>
<td>${author}</td>
<td>${review}</td>
</tr>`
$('#reviews-box').append(temp_html)
}
}
})
}
▶️ 완성 확인하기
화면을 새로고침 했을 때, DB에 저장된 리뷰가 화면에 나타난다!!

❕ 모든 프로젝트를 시작하기 전에는 API를 설계하는 일이 가장 처음에 해야될 일이다.
❕ 프로젝트 시작 전 API를 잘 설계한 것인지 검증하기 위해 작게 test해보는 것이 좋음 -> 조각 기능
-> API에서 수행해야하는 작업 중 익숙하지 않은 것들은 따로 python 파일을 만들어 작게 실행해보고, 잘 되면 그 코드를 붙여넣는 방식으로 하는 것이 효율적!
✔ Meta tag란?
: (head) 부분에 들어가며, 눈으로 보이는 것(body) 외에 사이트의 속성을 설명해주는 태그들이다.
▶️ 크롤링 기본 코드
import requests
from bs4 import BeautifulSoup
url = 'https://movie.naver.com/movie/bi/mi/basic.nhn?code=171539'
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일 때 select 사용방법
title = soup.select_one('meta[property="og:title"]')['content']
image = soup.select_one('meta[property="og:image"]')['content']
desc = soup.select_one('meta[property="og:description"]')['content']
print(title,image,desc)
✔ 클라이언트와 서버 확인
✔ 서버부터 만들기
✔ 클라이언트 만들기
✔ 완성 확인하기
▶️ 서버 만들기
❕ 이때
1. 클라이언트로부터 데이터(url, comment) 받기
2. meta tag(title, image, desc, image_url) 크롤링 하기
3. mogoDB에 데이터 저장
@app.route('/memo', methods=['POST'])
def saving():
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')
title = soup.select_one('meta[property="og:title"]')['content']
image = soup.select_one('meta[property="og:image"]')['content']
desc = soup.select_one('meta[property="og:description"]')['content']
doc = {
'title':title,
'image':image,
'desc':desc,
'url':url_receive,
'comment':comment_receive
}
db.articles.insert_one(doc)
return jsonify({'msg':'저장이 완료되었습니다!'})
▶️ 클라이언트 만들기
❕ 이때
1. 유저가 입력한 데이터(url, comment)를 #post-url/#post-comment에서 가져오기
2. POST 방식으로 메모 생성 요청하기 -> Ajax로 call!
3. 성공시 페이지 새로고침하기
function postArticle() {
let url = $('#post-url').val()
let comment = $('#post-comment').val()
$.ajax({
type: "POST",
url: "/memo",
data: {url_give:url, comment_give:comment},
success: function (response) { // 성공하면
alert(response["msg"]);
window.location.reload() //페이지 새로고침!
}
})
}
▶️ 완성 확인하기
✔ mongoDB에 데이터가 저장되는지 확인!

✔ url과 comment 입력 후 기사저장 눌렀을 때 '저장이 완료되었습니다!' alert창이 뜬다!
✔ 클라이언트와 서버 확인
✔ 서버부터 만들기
✔ 클라이언트 만들기
✔ 완성 확인하기
▶️ 서버 만들기
❕ 이때
1. mongoDB에서 모든 데이터 조회해오기
2. 정보 보내주기
@app.route('/memo', methods=['GET'])
def listing():
articles = list(db.articles.find({}, {'_id': False}))
return jsonify({'all_articles':articles})
▶️ 클라이언트 만들기
❕ 이때
1. 메모 정보 받기
2. 카드 붙이기
$.ajax({
type: "GET",
url: "/memo",
data: {},
success: function (response) {
let articles = response['all_articles']
for (let i = 0; i < articles.length; i++) {
let title = articles[i]['title']
let image = articles[i]['image']
let url = articles[i]['url']
let desc = articles[i]['desc']
let comment = articles[i]['comment']
let temp_html = `<div class="card">
<img class="card-img-top"
src="${image}"
alt="Card image cap">
<div class="card-body">
<a target="_blank" href="${url}" class="card-title">${title}</a>
<p class="card-text">${desc}</p>
<p class="card-text comment">${comment}</p>
</div>
</div>`
$('#cards-box').append(temp_html)
}
}
})
}
▶️ 완성 확인하기

▶️ 나의 결과

💬 이번 숙제.. 너무 막힘이 많았다... 자꾸 실행은 안되고 어디가 잘못된 것인지 모르겠고ㅜ 눈이 빠져라 코드 비교해가며 어차저차 완성된 숙제였다...😫
💬 가장 중요하다고 깨달은 점은 중간에 확인해 보는 습관이다!!!! console.log, print를 중간중간 습관화 하자!!!! 이거 진짜 중요한거 같다. 한번에 코드작성하고 넘어가는 순간 건널수 없는 강을 건너버리는 느낌이랄까.....잘 실행되고 있는지 확인 하지 않는다면 무엇이 잘못된건지 찾는데만 만만치 않은 시간을 쓰게될 것이니....반드시 하길....!
4주차가 3주차보다는 조큼 복잡하고 어려운 느낌.... 그치만 차분하게 규칙과 순서를 지키면서 하나하나 만들어 나간다면 생각보다 해볼만 하다는 생각이 들기도 했다.ㅎ 그렇지만 나는 숙제에서 탈탈 털려버렸지 허허(자꾸 실행이 안되는 매직을 경험)😂😂 강의 보다보면 뚝딱뚝딱 쉽게 하는 것 같은데 왜 난 안되지?라는 생각만 수십번했다. 그래도 끝까지 매달려서 해결하고 나니까 뿌듯-!