13일차
- 공부계획 : 웹개발 4주차 완강
< 미니 프로젝트 - 화성땅 공동구매 사이트 >
1) flask 폴더 구조 만들기
2) 가상환경(venv), 패키지 설치(flask, pymongo, dnspython)
*개발환경 복구 - pip freeze 활용(현재 서버에 설치된 라이브러리 목록을 저장할 수 있고, 새로운 가상환경에서 패키지들을 한번에 설치할 수 있다!)
3) mongoDB 창 띄우기
( POST 연습 )
4) API 만들기 - 이름, 주소, 평수 저장 (Creat -> POST)
(1) URL = /mars, 요청방식 = POST
(2) 클라이언트(fetch) -> 서버(flask) : name, address, size
(3) 서버(flask) -> 클라이언트(fetch) : 메세지를 보냄 (주문 완료!)
5) 클라이언트와 서버 연결 확인하기
6) 서버 만들기:DB에 연결
from pymongo import MongoClient
import certifi
ca = certifi.where()
client = MongoClient('mongodb+srv://sparta:test@cluster0.fqfuc0t.mongodb.net/?retryWrites=true&w=majority', tlsCAFile=ca)
db = client.dbsparta
7) DB에 name, address, size 받아 저장할 코드 작성
@app.route("/mars", methods=["POST"])
def web_mars_post():
name_receive = request.form['name_give']
address_receive = request.form['address_give']
size_receive = request.form['size_give']
doc = {
'name':name_receive,
'address':address_receive,
'size':size_receive
}
db.mars.insert_one(doc)
return jsonify({'msg': '주문완료!'})
8) 클라이언트 만들기 : name, address, size 정보 보내기
~~~
function save_order() {
let name = $('#name').val()
let address = $('#address').val()
let size = $('#size').val()
let formData = new FormData();
formData.append("name_give", name);
formData.append("address_give", address);
formData.append("size_give", size);
fetch('/mars',{method: "POST", body: formData,
}).then((res) => res.json()).then((data) => {
alert(data["msg"]);
window.location.reload();
});
}
~~~
9) 완성, 데이터 입력 하고 DB에 잘 들어갔는지 확인
( GET 연습 )
4) 저장된 주문 화면에 보여주기 (Read -> GET)
(1) URL = /mars, 요청방식 = GET
(2) 클라이언트(fetch) -> 서버(flask) : 없음 XXX
(3) 서버(flask) -> 클라이언트(fetch) : 전체 주문을 보내주기
5) 클라이언트와 서버 연결 확인하기
서버
@app.route("/mars", methods=["GET"])
def mars_get():
return jsonify({'msg': 'GET 연결 완료!'})
클라이언트
$(document).ready(function() {
show_order()
})
function show_order() {
fetch('/mars').then((res) => res.json()).then((data) => {
console.log(data);
alert(data["msg"]);
});
}
6) 서버 만들기
@app.route("/mars", methods=["GET"])
def mars_get():
mars_data = list(db.mars.find({},{'_id':False}))
return jsonify({'result':mars_data})
//DB에서 모든 data를 갖고와서 mars_data에 넣고, result로 mars_data를 클라이언트에 내려줌
7) 클라이언트 만들기
(1)주문 정보 : List형식 => forEach문 반복으로 데이터 뽑기
(2) 뽑은 데이터를 temp_html에 담기
(3) temp_html를 넣을 자리 찾아서 jQuery로 append
function show_order() {
$("#order-box").empty();
fetch('/mars').then((res) => res.json()).then((data) => {
let rows = data['result']
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);
});
});
}
< 미니프로젝트 - 스파르타피디아 >
1) 프로젝트 세팅 (폴더 구조 생성, 가상환경 및 패키지 설치)
2) 조각 기능 구현 : app.py 밖에서 조각으로 구현한 다음 붙이는 것
=> 테스트를 일일이 flask에서 브라우저를 열고 진행하지 않아 편하고 빠름
=> 새 파일을 만들어 코드를 작업하고 성공하면 복사 후 app.py에 붙이기
3) 웹 스크래핑 사용해서 URL에서 페이지 정보 크롤링
(1) meta 태그 활용
- meta 태그 : 눈에 보이는 것 이외의 '웹의 속성 '을 설명해주는 태그
- meta 태그 예시) 카카오톡에서 url을 보냈을 때 자동으로 딸려오는 썸네일 사진,제목,설명 등
- 썸네일 사진 = og:image, 썸네일 제목 = og:title, 썸네일 설명 = og:description
(2) meta 태그 정보를 가져오는 조각기능 만들기
- 새 파일(meta_prac.py) 생성
- 크롤링 기본 코드 넣기
- meta 태그 크롤링 (구글링 : meta 태그 크롤링)
- select_one을 이용해 meta태그 가져오기
og_image = soup.select_one('meta[property="og:image"]')['content']
og_title = soup.select_one('meta[property="og:title"]')['content']
og_description = soup.select_one('meta[property="og:description"]')['content']
print(og_image,og_title,og_description)
=> 코드 조각 준비 완료
4) app.py 준비
from flask import Flask, render_template, request, jsonify
app = Flask(name)
@app.route('/')
def home():
return render_template('index.html')
@app.route("/movie", methods=["POST"])
def movie_post():
sample_receive = request.form['sample_give']
print(sample_receive)
return jsonify({'msg':'POST 연결 완료!'})
@app.route("/movie", methods=["GET"])
def movie_get():
return jsonify({'msg':'GET 연결 완료!'})
if __name__ == '__main__':
app.run('0.0.0.0', port=5000, debug=True)
5) index.html 준비
6) mongoDB창 띄우기
( POST 연습 ) 포스팅 API
7) API 만들고 사용 - (Creat -> POST)
1) URL = /movie, 요청방식 = POST
(2) 클라이언트(fetch) -> 서버(flask) : url, comment
(3) 서버(flask) -> 클라이언트(fetch) : 메세지를 보냄 (포스팅 완료!)
8) 클라이언트와 서버 연결 확인하기
9) 서버 만들기
- DB에 연결
from pymongo import MongoClient
import certifi
ca = certifi.where()
client = MongoClient('mongodb+srv://sparta:test@cluster0.fqfuc0t.mongodb.net/?retryWrites=true&w=majority', tlsCAFile=ca)
db = client.dbsparta
- url, comment 정보 받아서 저장 (만들어둔 코드 조각 붙이고, DB에 저장)
@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')
ogimage = soup.select_one('meta[property="og:image"]')['content']
ogtitle = soup.select_one('meta[property="og:title"]')['content']
ogdesc = soup.select_one('meta[property="og:description"]')['content']
doc = {
'image':ogimage,
'title':ogtitle,
'desc':ogdesc,
'comment':comment_receive
}
db.movies.insert_one(doc)
return jsonify({'msg':'포스팅 완료!'})
10) 클라이언트 만들기
url, comment 정보 보내기 (formData에 데이터 넣고 보내기)
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() // 새로고침
})
}
( GET 연습 )
7) API 만들고 사용하기 - 포스트 보여주기 API (Read -> GET)
(1) URL = /movie, 요청방식 = GET
(2) 클라이언트(fetch) -> 서버(flask) : 없음
(3) 서버(flask) -> 클라이언트(fetch) : 전체 주문 보내주기
8) 클라이언트와 서버 연결 확인하기
9) 서버 만들기
받을 것 없으니 orders에 주문 정보를 담아서 보내주기만 하면 끝
@app.route("/movie", methods=["GET"])
def movie_get():
all_movies = list(db.movies.find({},{'_id':False}))
return jsonify({'result':all_movies})
10)클라이언트 만들기
주문정보 : List 형식 -> forEach문으로 반복해서 데이터 뽑기
뽑은 데이터 temp_html에 담고 temp_html넣을 자리 찾아서 append로 붙이기
11) 전체 완성 코드!! (별점 기능 추가)
💻app.py 코드(백엔드 - 스파르타 피디아 서버)
from flask import Flask, render_template, request, jsonify
app = Flask(__name__)
from pymongo import MongoClient
import certifi
ca = certifi.where()
client = MongoClient('mongodb+srv://sparta:test@cluster0.fqfuc0t.mongodb.net/?retryWrites=true&w=majority')
db = client.dbsparta
import requests
from bs4 import BeautifulSoup
@app.route('/')
def home():
return render_template('index.html') // app.py에서 html파일 불러오기
@app.route("/movie", methods=["POST"])
def movie_post():
url_receive = request.form['url_give']
comment_receive = request.form['comment_give']
star_receive = request.form['star_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')
ogimage = soup.select_one('meta[property="og:image"]')['content']
ogtitle = soup.select_one('meta[property="og:title"]')['content']
ogdesc = soup.select_one('meta[property="og:description"]')['content']
// meta태그 정보를 select_one으로 웹에서 가져옴
doc = {
'image':ogimage,
'title':ogtitle,
'desc':ogdesc,
'comment':comment_receive
}
db.movies.insert_one(doc) // 데이터를 딕셔너리 형태로 DB에 저장
return jsonify({'msg':'저장완료!'}) // 마지막으로 html posting함수에 msg 리턴
@app.route("/movie", methods=["GET"]) // 백엔드에서 프론트로 데이터 내려주기
def movie_get():
all_movies = list(db.movies.find({},{'_id':False})) // 모든데이터 뽑아오기
return jsonify({'result':all_movies}) //msg대신에 result에 all_movie데이터 리턴
if __name__ == '__main__':
app.run('0.0.0.0', port=5000, debug=True)
💻index.html 코드(프론트엔드- 스파르타 피디아 클라이언트)
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet"
integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js"
integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM"
crossorigin="anonymous"></script>
<title>스파르타 피디아</title>
<link href="https://fonts.googleapis.com/css2?family=Gowun+Dodum&display=swap" rel="stylesheet">
<style>
* {
font-family: 'Gowun Dodum', sans-serif;
}
.mytitle {
width: 100%;
height: 250px;
background-image: linear-gradient(0deg, rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0.5)), url('https://movie-phinf.pstatic.net/20210715_95/1626338192428gTnJl_JPEG/movie_image.jpg');
background-position: center;
background-size: cover;
color: white;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.mytitle>button {
width: 200px;
height: 50px;
background-color: transparent;
color: white;
border-radius: 50px;
border: 1px solid white;
margin-top: 10px;
}
.mytitle>button:hover {
border: 2px solid white;
}
.mycomment {
color: gray;
}
.mycards {
margin: 20px auto 0px auto;
width: 95%;
max-width: 1200px;
}
.mypost {
width: 95%;
max-width: 500px;
margin: 20px auto 0px auto;
padding: 20px;
box-shadow: 0px 0px 3px 0px gray;
display: none;
}
.mybtns {
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
margin-top: 20px;
}
.mybtns>button {
margin-right: 10px;
}
</style>
<script>
$(document).ready(function () { // 문서가 준비되면 listing함수 동작
listing();
});
function listing() { // 모든 데이터 결과 보여주기
fetch('/movie').then((res) => res.json()).then((data) => {
let rows = data['result'] //DB에 있던 데이터들을 리스트로 묶음
$('#cards-box').empty() // 반복문 돌기 전 비우기
rows.forEach((a)=>{
let comment = a['comment']
let title = a['title']
let desc = a['desc']
let image = a['image']
// rows에 담긴 result들을 a에 하나씩 담아서 돌림
a의 각 키값들을 let 변수에 담음
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>
</div>`
//웹에 붙여 줄 temp_html 만들고(어디에 들어갈지 html에서 확인)
$('#cards-box').append(temp_html)
//id값 지정 후 append로 temp_html을 웹에 붙여준다!
})
})
}
function posting() {
let url = $('#url').val() //변수 url에 id가 url인 요소의 vaule가져오기
let comment = $('#comment').val()
let star = $('#star').val()
let formData = new FormData(); // 새로운 Form 객체 형성
formData.append("url_give", url); //name과 value를 가진 Form 필드 추가
formData.append("comment_give", comment);
formData.append("star_give", star);
// /movie로 formData 생성(url,comment,star)해서 보냄
fetch('/movie', { method: "POST", body: formData }).then((res) => res.json()).then((data) => {
alert(data['msg']) // 백엔드에서 DB에 데이터 저장 후 msg alert
window.location.reload()
})
}
function open_box() {
$('#post-box').show()
}
function close_box() {
$('#post-box').hide()
}
</script>
</head>
<body>
<div class="mytitle">
<h1>내 생애 최고의 영화들</h1>
<button onclick="open_box()">영화 기록하기</button>
</div>
<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>
</div>
<div class="form-floating">
<textarea id="comment" class="form-control" placeholder="Leave a comment here"></textarea>
<label for="floatingTextarea2">코멘트</label>
</div>
<div class="mybtns">
<button onclick="posting()" type="button" class="btn btn-dark">기록하기</button>
<button onclick="close_box()" type="button" class="btn btn-outline-dark">닫기</button>
</div>
</div>
<div class="mycards">
<div class="row row-cols-1 row-cols-md-4 g-4" id="cards-box">
<div class="col">
<div class="card h-100">
<img src="https://movie-phinf.pstatic.net/20210728_221/1627440327667GyoYj_JPEG/movie_image.jpg"
class="card-img-top">
<div class="card-body">
<h5 class="card-title">영화 제목이 들어갑니다</h5>
<p class="card-text">여기에 영화에 대한 설명이 들어갑니다.</p>
<p>⭐⭐⭐</p>
<p class="mycomment">나의 한줄 평을 씁니다</p>
</div>
</div>
</div>
<div class="col">
<div class="card h-100">
<img src="https://movie-phinf.pstatic.net/20210728_221/1627440327667GyoYj_JPEG/movie_image.jpg"
class="card-img-top">
<div class="card-body">
<h5 class="card-title">영화 제목이 들어갑니다</h5>
<p class="card-text">여기에 영화에 대한 설명이 들어갑니다.</p>
<p>⭐⭐⭐</p>
<p class="mycomment">나의 한줄 평을 씁니다</p>
</div>
</div>
</div>
<div class="col">
<div class="card h-100">
<img src="https://movie-phinf.pstatic.net/20210728_221/1627440327667GyoYj_JPEG/movie_image.jpg"
class="card-img-top">
<div class="card-body">
<h5 class="card-title">영화 제목이 들어갑니다</h5>
<p class="card-text">여기에 영화에 대한 설명이 들어갑니다.</p>
<p>⭐⭐⭐</p>
<p class="mycomment">나의 한줄 평을 씁니다</p>
</div>
</div>
</div>
<div class="col">
<div class="card h-100">
<img src="https://movie-phinf.pstatic.net/20210728_221/1627440327667GyoYj_JPEG/movie_image.jpg"
class="card-img-top">
<div class="card-body">
<h5 class="card-title">영화 제목이 들어갑니다</h5>
<p class="card-text">여기에 영화에 대한 설명이 들어갑니다.</p>
<p>⭐⭐⭐</p>
<p class="mycomment">나의 한줄 평을 씁니다</p>
</div>
</div>
</div>
</div>
</div>
</body>
</html>
- val() = 값을 가져오거나 변경하는 메소드
- $('input').val(); //input의 value값을 가져온다.
- var fruit = $("#apple").val();
// 변수 fruit에 id가 apple인 요소의 value를 가져온다
'내일배움캠프 > 내일배움단' 카테고리의 다른 글
내일배움단 -개발일지 2주차 (3) (0) | 2023.03.08 |
---|---|
내일배움단 -개발일지 2주차 (2) (0) | 2023.03.08 |
내일배움단 -개발일지 2주차 (1) (0) | 2023.03.08 |
내일배움단 - 개발일지 1주차(3) (2) | 2023.03.08 |
내일배움단 - 개발일지 1주차(2) (0) | 2023.03.08 |