일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- visualvm
- WEB SOCKET
- MYSQL
- 항해99
- 시큐리티
- 생성자 주입
- @jsonproperty
- emqx
- 웹개발
- CentOS
- JWT
- Spring
- 데이터베이스
- 스웨거
- 남궁성과 끝까지 간다
- EC2
- java
- 프로그래머스
- Kafka
- 카프카
- Spring Security
- 스파르타코딩클럽
- 스프링의 정석
- docker
- 패스트캠퍼스
- 개인프로젝트
- JavaScript
- 쇼트유알엘
- AWS
- DB
- Today
- Total
Nellie's Blog
[스파르타코딩클럽] 웹개발 종합반 4주차 정리 본문
👉 4주차 수업목표
1. Flask 프레임워크를 활용해서 API를 만들 수 있다.
2. '화성에 땅사기' API를 만들고 클라이언트에 연결한다.
3. '스파르타피디아' API를 만들고 클라이언트와 연결한다.
1,2주차에는 html,css,js를 배웠고, 3주차에는 서버를 다룰수있는 python과 저장소인 db를 배웠다.
4주차에는 드디어 서버를 배워본다!
👉 Flask 시작하기 - 서버만들기
참고) 파이썬으로 웹개발을 할 때 가장 유명한 것은 Django(장고)인데, 장고는 무겁고 기능이 많아서 복잡하여 초보가 쓰기 쉬운 라이트한 flask프레임워크를 사용한다. (자바의 Spring)
- HTML과 mongoDB까지 연동해서 서버를 만들어보자!
1. 파이참에서 Flask 패키지 설치 (Flask 프레임워크: 서버를 구동시켜주는 편한 코드 모음)
2. app.py파일만들고 flask시작코드 넣고 우클릭- run 해서 실행 (보통 flask 서버돌리는 파일은 app.py라고 짓는다)
- flask 시작 코드
from flask import Flask #flask모듈 임포트
app = Flask(__name__) #flask객체를 app이라는 변수에 할당. 현재 스크립트가 main스크립트임을 확인하는것.
@app.route('/') #Flask에서는 URL을 방문할때 준비된 함수가 트리거되도록 바인딩하기위해 route()데코레이터를 사용한다. 이를 '웹을 라우팅한다'라고 한다.
def home():
return 'hello world!'
if __name__ == '__main__': #현재 스크립트가 main스크립트이기 때문에 app.run()을 실행하게 해주는것!
app.run('0.0.0.0', port=5000, debug=True) #서버 실행!!!
#debug=True라고 명시하면 해당 파일의 코드를 수정할 때마다 Flask가 변경된 것을 인식하고 다시 시작한다. 코딩시 내용을 바로 반영해서 결과를 확인하기 편하다.
- 그럼 아래 창에 이렇게 뜰거고, 크롬에서 http://localhost:5000/ 으로 접속 후 Hello World! 보이면 성공!
터미널 창을 클릭하고, ctrl + c 을 누르면 서버를 종료할 수 있다.
3. URL 나눠보기
- @app.route('/) 부분을 수정해서 URL을 나눌 수 있다. (중복되면 안된다)
from flask import Flask
app = Flask(__name__)
@app.route('/') #URL에서 첫 화면 주소 (localhost:5000)
def home():
return 'hello world!'
@app.route('/mypage') #URL 주소 추가 (localhost:5000/mypage)
def mypage():
return 'This is mypage!' #⭐이쯤 의문이 드는것.. return뒤에 html구조가 들어가는거 같은데..
#⭐모든 html을 return뒤에 쭉쭉 다 써줘야하나?..놉 아래를 계속 보자!
if __name__ == '__main__':
app.run('0.0.0.0', port=5000, debug=True)
👉 Flask 시작하기 - HTML파일 주기
1. Flask 기본 폴더구조
Flask 서버를 만들 때, 항상, 프로젝트 폴더 안에,
ㄴstatic 폴더 (이미지, css파일을 넣는곳)
ㄴtemplates 폴더 (html파일을 넣는곳)
ㄴapp.py 파일 이렇게 세 개를 만들어두고 시작하기! (env는 실제로는 보이지만, 안보인다고 생각! )
2. HTML 파일 불러오기 (렌더링)
1) templates 폴더에 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() {
alert('안녕!')
}
</script>
</head>
<body>
<button onclick="hey()">나는 버튼!</button>
</body>
</html>
2) app.py파일에서 flask내장함수인 render_template을 사용해서 html을 불러오기. (2줄 추가)
- 맨위에 ,render_template 넣기
- return뒤에 'hello world' 지우고 render_template('index.html') 써주면 된다.
from flask import Flask, render_template #⭐ ,render_template 넣기
app = Flask(__name__)
@app.route('/')
def home():
return render_template('index.html') #⭐ render_template('index.html') 넣기. index.html파일을 렌더링해줘!
if __name__ == '__main__':
app.run('0.0.0.0', port=5000, debug=True)
3) 그렇게 하고 app.py에서 실행하면 html이 그대로 따와져서 로컬호스트화면에 나타난다.
- 이런 과정을 렌더링이라고 한다. 렌더링이란 서버로부터 HTML 파일을 받아 브라우저에 뿌려주는 과정이다.
👉 GET / POST 방식 이해하기
* GET → 데이터 조회를 요청할 때 (서버에서 데이터를 가져와줘!)
예) 영화 목록 조회 → 데이터 전달 : URL 뒤에 물음표를 붙여 key=value로 전달
→ 예: google.com?q=북극곰
요청형태 : google.com?q=북극곰
요청데이터 : q=북극곰
* POST → 데이터 생성, 변경, 삭제를 요청 할 때 (데이터를 서버에 저장해줘!)
예) 회원가입, 회원탈퇴, 비밀번호 수정 → 데이터 전달 : 바로 보이지 않는 HTML body에 key:value 형태로 전달
요청형태 : google.com
요청데이터 : 노출되지 않는다.
👉 Flask시작하기 - 본격 API 만들기
1. (클라이언트) index.html파일에서 ajax로 요청하는 함수 만들기
1) JQuery 임포트하기. ajax를 사용하기위해 필요하다.
2) <script>에 ajax코드 작성하기. GET, POST요청코드를 작성할수 있다. (GET요청시 url : "/창구이름?key=value")
//⭐index.html 파일
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script> //제이쿼리임포트. 그래야 ajax로 요청을 할수 있으니까!
<script> //여기에 ajax써줄거야.
function hey() { //함수를 만들어서 버튼을 누르면 ajax가 실행되도록 만들자.
$.ajax({
type: "GET",
url: "/test?title_give=봄날은간다", // /test라는 창구에 갔는데, title_give(주민번호)의 내용중에 봄날은간다(980101)라는 데이터를 내가 갖고갈게! 근데../test창구는 어떻게 만들지?
data: {},
success: function (response) {
console.log(response)
}
})
$.ajax({
type: "POST",
url: "/test",
data: {title_give: '봄날은간다'}, // /test창구에 이 data정보를 가져가서, 저장해줘!요청
success: function (response) {
console.log(response['msg'])
}
})
}
</script>
</head>
<body>
<button onclick="hey()">나는 버튼!</button>
</body>
</html>
2. (서버) app.py파일에서 정보를 반환하는 함수 만들기 - 내가 만든 창구(API)를 만들기
1) request, jsonify 임포트 해주기. (jsonify : 사전or 배열을 던져서 쉽게 JSON 타입의 HTTP 응답 데이터를 생성해줌)
2) @app.route('/창구이름', methods=['GET']) ~ 라고 시작한후 함수 만들기
#⭐app.py 파일
from flask import Flask, render_template, request, jsonify #여기서 request, jsonify 추가로 임포트 해주기
app = Flask(__name__)
@app.route('/')
def home():
return render_template('index.html')
@app.route('/test', methods=['GET']) #내가 만든 get요청 api코드 5줄!! 내가 /test창구를 만든거야 !!
def test_get():
title_receive = request.args.get('title_give') #title_give라는애를 title_receive변수에 넣고 print로 찍어줄게!
print(title_receive)
return jsonify({'result': 'success', 'msg': '이 요청은 GET!'})
@app.route('/test', methods=['POST'])
def test_post():
title_receive = request.form['title_give'] #너 'title_give'가져왔니? 응 가져왔어! -> 그럼 title_receive에 넣고 찍어줄게!
print(title_receive)
return jsonify({'result': 'success', 'msg': 'POST!'})
if __name__ == '__main__':
app.run('0.0.0.0', port=5000, debug=True)
👉 화성땅 공동구매 사이트 만들기 (+ DB사용)
- 웹페이지에서 이름, 주소, 평수를 선택하고 주문하기 버튼을 누르면, (POST)
- 자동으로 그 밑에 저장한 값들이 보여지게 해보자 (GET)
- 먼저, 패키지 설치 (4개) : flask, pymongo, dnspython, requests
1. POST 연습(주문 저장)
1. 요청 정보 : URL= /mars , 요청 방식 = POST
2. 클라(ajax) → 서버(flask) : name , address , size (서버에 저장해 주세요!) -> 서버는 데이터를 DB에 저장한다.
3. 서버(flask) → 클라(ajax) : 메시지를 보냄 (주문 완료!)
1) 클라이언트와 서버 연결 확인하기
- 같은창구(/mars)인지, 같은방식(POST)인지, 같은 데이터(sample_give)를 주고받는지 확인!
#⭐app.py 파일
@app.route("/mars", methods=["POST"])
def web_mars_post():
sample_receive = request.form['sample_give']
print(sample_receive)
return jsonify({'msg': 'POST 연결 완료!'})
// ⭐index.html 파일
function save_order() {
$.ajax({
type: 'POST',
url: '/mars',
data: {sample_give: '데이터전송'},
success: function (response) {
alert(response['msg'])
}
});
}
2) 서버부터 만들기
#⭐app.py 파일
from flask import Flask, render_template, request, jsonify
app = Flask(__name__)
#⭐DB를사용하려면 항상 이 pymongo3줄이 필요하다고 했다. DB와 서버 연결을 위해 추가해주기!
from pymongo import MongoClient
client = MongoClient('mongodb+srv://test:sparta@cluster0.ryuvr6l.mongodb.net/Cluster0?retryWrites=true&w=majority')
db = client.dbsparta
@app.route("/mars", methods=["POST"])
def web_mars_post(): #⭐기계적으로 쓰자!!
name_receive = request.form['name_give'] #⭐'_give'가 중간다리 역할이라고 생각하자! 얘가 받아서 또 담아주니까!
address_receive = request.form['address_give']
size_receive = request.form['size_give']
#⭐doc변수에 데이터를 담고, mars데이터베이스에 저장해주기!
doc = {
'name': name_receive,
'address': address_receive,
'size': size_receive
}
db.mars.insert_one(doc)
return jsonify({'msg': '주문 완료!'}) #⭐화면에 알림창 띄우기. return문은 함수를 종료시키니 db저장코드 다음에 써줄것!!!
3) 클라이언트 만들기
// ⭐index.html 파일
<script>
function save_order() {
let name = $('#name').val() // ⭐아래<body>에서 내가 원하는 정보의 id값을 확인해서 .val()로 원하는값 추출하고 다시 변수에 넣기
let address = $('#address').val()
let size = $('#size').val()
$.ajax({
type: 'POST',
url: '/mars',
data: {name_give: name, address_give:address, size_give:size}, // ⭐드디어 데이터에 담아서 서버에 보낼 준비. 항상 '_give' 에 담아서 서버의 중간다리로 사용되게 하자.
success: function (response) {
alert(response['msg'])
window.location.reload() // ⭐입력완료 후, 글씨가 남아있으면 지저분하니까 새로고침 해주기!
}
});
}
</script>
.....
<body>
<div class="order-info">
<div class="input-group mb-3">
<span class="input-group-text">이름</span>
<input id="name" type="text" class="form-control"> // ⭐id="name" 찾고
</div>
<div class="input-group mb-3">
<span class="input-group-text">주소</span>
<input id="address" type="text" class="form-control"> // ⭐id="address" 찾고
</div>
<div class="input-group mb-3">
<label class="input-group-text" for="size">평수</label>
<select class="form-select" id="size"> // ⭐ id="size" 찾았으면 위로 올라가서 추출!
<option selected>-- 주문 평수 --</option>
<option value="10평">10평</option>
</select>
</div>
<button onclick="save_order()" type="button" class="btn btn-warning mybtn">주문하기</button>
</div>
</div>
<body>
4) 웹사이트에서 이름,주소,평수 넣고 DB에 잘 저장 되있는것 확인!
2. GET 연습 (주문 한것 보여주기)
1. 요청 정보 : URL= /mars , 요청 방식 = GET
2. 클라(ajax) → 서버(flask) : (없음)
3. 서버(flask) → 클라(ajax) : 전체 주문을 보내주기
1) 클라이언트와 서버 연결 확인하기
- 같은창구(/mars)인지, 같은방식(GET)인지 확인!
2) 서버부터 만들기
@app.route("/mars", methods=["GET"])
def web_mars_get():
orders_list = list(db.mars.find({}, {'_id': False})) #⭐mars데이터베이스에 있는 값을 모두 가져온다.
return jsonify({'orders': orders_list}) #⭐항상 key : value 값으로 적어야해. 'orders'같은 중간다리변수를 key로 만들어줘야해.
3) 클라이언트 만들기
- 클라이언트에서는 항상 let변수가 여러개 들어간다!!
<script>
$(document).ready(function () { //⭐저장된데이터를 로딩되자마자 자동으로 보여줘야하니까.
show_order();
});
function show_order() {
$.ajax({
type: 'GET',
url: '/mars',
data: {},
success: function (response) {
let rows = response['orders'] //⭐DB에서 받은 데이터를 한줄한줄 뽑아야 하니까 rows변수로 받아주기!
for(let i = 0; i < rows.length; i++){ //⭐한줄씩 반복해야하니까 for문!
let name = rows[i]['name'] //⭐내가 원하는데이터를 받아올 변수 만들고 데이터담기! [i]빼먹지말자!!!
let address = rows[i]['address']
let size = rows[i]['size']
let temp_html = `<tr> //⭐데이터를 이 모양으로 넣어줄게!
<td>${name}</td>
<td>${address}</td>
<td>${size}</td>
</tr>`
$('#order-box').append(temp_html) //⭐넣은데이터를 이곳에 붙여줄게!
}
}//⭐헷갈리니까 중간중간 console.log()찍어서 확인하면서 코딩하자..!!!
});
}
......
}
</script>
4) 웹사이트에서 내가 넣은 이름,주소,평수가 잘 나타나는지 확인!
3. POST / GET 비교
👉 스파르타피디아 사이트에 서버 추가하기 (+ 크롤링)
- 사이트에서 url,별점,코멘트(3가지정보)를 입력하면, url에서 자동으로 영화제목, 이미지, 영화설명까지 불러와서 화면에 표시되도록 해보자. (화면에 표시되는것 5가지 : 영화제목, 이미지, 영화설명, 별점, 코멘트)
- 패키지 설치하기 5개 : flask, pymongo, dnspython, bs4, requests
1. URL에서 페이지 정보 가져오기 (meta태그 스크래핑)
- meta태그란?
URL만 입력했는데, 자동으로 불러와지는 부분. 눈으로 보이는 것(body) 외에 사이트의 속성을 설명해주는 태그들.
예) 구글 검색 시 표시 될 설명문, 사이트 제목, 카톡 공유 시 표시 될 이미지 등
이런 데이터들은 'meta'태그를 크롤링으로 추출, 우리는 그 중 og:image / og:title / og:description을 크롤링 할 것이다.
#⭐meta_prac.py파일
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')
#⭐여기까지는 크롤링 기본코드 복붙
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)
#⭐여기까지 하고 대기. 이따가 app.py파일에 복붙해서 쓸거다.
2. POST 연습 (포스팅하기)
1) 서버 만들기
from flask import Flask, render_template, request, jsonify
app = Flask(__name__)
import requests #⭐meta_prac.py에서 두줄 복붙(크롤링시 필요)
from bs4 import BeautifulSoup
from pymongo import MongoClient #⭐dbprac.py에서 3줄 복붙 (db저장시 필요)
client = MongoClient('mongodb+srv://test:sparta@cluster0.ryuvr6l.mongodb.net/Cluster0?retryWrites=true&w=majority')
db = client.dbsparta
@app.route('/')
def home():
return render_template('index.html')
@app.route("/movie", methods=["POST"])
def movie_post():
url_receive = request.form['url_give'] #⭐여기서 받아온 url은 평소처럼 doc에 바로저장하는게 아니라 크롤링코드로 한번 돌린후 title,image,desc를 추출!
star_receive = request.form['star_give'] #⭐doc에 바로 저장
comment_receive = request.form['comment_give'] #⭐doc에 바로 저장
#⭐mata_prac.py에서 만들어놓은 headers ~ desc 까지 6줄 복붙 (title,image,desc 정보가져온거 저장하려고)
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) #⭐url -> url_receive 수정. 위에서 받은 url을 data에 넣고 굴리는거다.
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,
'star' : star_receive,
'comment' : comment_receive
}
db.movies.insert_one(doc)
return jsonify({'msg': '저장 완료!'})
2) 클라이언트 만들기
function posting() {
let url = $('#url').val() //⭐val()까먹지말자!
let star = $('#star').val()
let comment = $('#comment').val()
$.ajax({
type: 'POST',
url: '/movie',
data: {url_give:url, star_give:star, comment_give:comment},
success: function (response) {
alert(response['msg']) //⭐저장완료! 메시지출력
window.location.reload() //⭐새로고침도 꼭 잊지말고 해줘!
}
});
}
.......
<div class="mypost" id="post-box">
<div class="form-floating mb-3">
<input id="url" type="email" class="form-control" placeholder="name@example.com"> //⭐id="url"확인
<label>영화URL</label>
</div>
<div class="input-group mb-3">
<label class="input-group-text" for="inputGroupSelect01">별점</label>
<select class="form-select" id="star"> //⭐id="star"확인
<option selected>-- 선택하기 --</option>
</select>
</div>
<div class="form-floating">
<textarea id="comment" class="form-control" placeholder="Leave a comment here"></textarea> //⭐id="comment"확인
<label for="floatingTextarea2">코멘트</label>
</div>
</div>
3. GET 연습 (보여주기)
1) 서버 만들기
@app.route("/movie", methods=["GET"])
def movie_get():
movie_list = list(db.movies.find({}, {'_id': False}))
return jsonify({'movies': movie_list}) #⭐중간다리 역할을 하는 movies변수..제발 까먹지말고 잘쓰자.
2) 클라이언트 만들기
<script>
$(document).ready(function () {
listing();
});
function listing() {
$('#cards-box').empty()
$.ajax({
type: 'GET',
url: '/movie', //⭐3주차 초에 한 스파르타피디아에 openAPI붙인거와의 차이점은 이 url이랑, POST작업이 없다는것!!!
data: {},
success: function (response) {
let rows = response['movies']
for(let i =0; i<rows.length; i++){
let title = rows[i]['title']
let star = rows[i]['star']
let image = rows[i]['image']
let desc = rows[i]['desc']
let comment = rows[i]['comment']
let star_image = '⭐'.repeat(star)
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>${star_image}</p>
<p class="mycomment">${comment}</p>
</div>
</div>
</div>`
$('#cards-box').append(temp_html)
}
}
})
}
👉 GET, POST 에서 서버, 클라이언트 만들기 정리
POST (클라이언트 -> 서버) | |
<서버만들기> #app.py 파일에 flask, pymongo임포트 @app.route("/mars", methods=["POST"]) name_receive = request.form['name_give'] doc = { 'name': name_receive, } db.mars.insert_one(doc) return jsonify({'msg': '주문 완료!'}) name_give는 중간다리 변수. name_receive는 여기서만 두번 쓰이고 끝나는 변수. |
<클라이언트만들기> function save_order() { let name = $('#name').val() $.ajax({ type: 'POST', url: '/mars', data: {name_give: name,}, success: function (response) { alert(response['msg']) window.location.reload() } }); ⭐POST에서 클라이언트를 만들때는 함수명 밑에 바로 let 변수로 받아올 데이터를 담아줘야 하는구나. |
GET (서버 -> 클라이언트) | |
<서버만들기> @app.route("/mars", methods=["GET"]) def web_mars_get(): orders_list = list(db.mars.find({}, {'_id': False})) return jsonify({'orders': orders_list}) orders_list 는 여기서만 두번 쓰이고 끝나는 변수. orders는 중간다리 변수. |
<클라이언트만들기> <script> $(document).ready(function () { show_order(); }); function show_order() { $.ajax({ type: 'GET', url: '/mars', data: {}, success: function (response) { let rows = response['orders'] for(let i = 0; i < rows.length; i++){ let name = rows[i]['name'] let temp_html = `<tr> <td>${name}</td> </tr>` $('#order-box').append(temp_html) } } }); ⭐GET에서 클라이언트를 만들때는 response 밑에 바로 let rows 변수로 받아온 데이터를 한줄한줄 담아줘야 하는구나. |
조금 정리가 되는 것 같지만 숙달이 필요할 것 같다!!
출처 : [스파르타코딩클럽] 웹개발 종합반 4주차
'회고록 > 항해99' 카테고리의 다른 글
프로젝트 서버에 올리기 정리 (0) | 2022.11.04 |
---|---|
[스파르타코딩클럽] 웹개발 종합반 5주차 정리 (2) | 2022.09.23 |
[스파르타코딩클럽] 웹개발 종합반 3주차 정리 (4) | 2022.09.21 |
[스파르타코딩클럽] 웹개발 종합반 2주차 정리 (4) | 2022.09.20 |
[스파르타코딩클럽] 웹개발 종합반 1주차 정리 (5) | 2022.09.19 |