스파르타코딩클럽 웹프로그래밍 공부 4주차 개발일지 기록
서버 기초 (Flask)
# 콜랩에서는 가상환경에서 실행되니 본 컴퓨터의 로컬서버는 안만들어진다. 파이썬 프로그램으로 하자.
from flask import Flask
app = Flask(__name__)
@app.route('/') # '/mypage'같이 경로지정 가능
def home():
return 'This is Home!'
if __name__ == '__main__':
app.run('0.0.0.0',port=5000,debug=True) #http://localhost:5000
# 브라우저에서 http://localhost:5000/ 쳐보면 결과나옴 (콜랩에서는 안됨)
# Flask 서버를 만들 때, 항상, 프로젝트 폴더 안에,
# ㄴstatic 폴더 (이미지, css파일을 넣어둡니다)
# ㄴtemplates 폴더 (html파일을 넣어둡니다)
# ㄴapp.py 파일
# html파일로 적용시키기
from flask import Flask, render_template # render_template추가
app = Flask(__name__)
@app.route('/')
def home():
return render_template('index.html') #template폴더안에 있는 index.html파일을 브라우저 페이지로 불러옴
if __name__ == '__main__':
app.run('0.0.0.0',port=5000,debug=True)
# API설정 (GET)의 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> <!--J쿼리 설정-->
<script>
function hey() { // 기존과 다르게 함수로 API불러오기 설정
$.ajax({ //API불러오기 (GET요청) 시작
type: "GET",
url: "/test?title_give=봄날은간다", // test 폴더에 title_give 항목의 봄날의간다 데이터를 보낸(?)다는 뜻
data: {},
success: function (response) {
console.log(response)
}
}) //API불러오기 (GET요청) 끝
}
</script>
</head>
<body>
<button onclick="hey()">hey함수실행</button>
</body>
</html>
# API설정 (POST)의 index.html 파일내용
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script>
function hey() {
$.ajax({ // POST형식의 API 연결
type: "POST",
url: "/test",
data: {title_give: '봄날은간다'}, // 보낼 데이터
success: function (response) {
console.log(response)
}
})
}
</script>
</head>
<body>
<button onclick="hey()">hey함수실행</button>
</body>
</html>
# API설정 (GET)(POST)
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']) # API(GET요청)코드 시작 #/test GET방식
def test_get():
title_receive = request.args.get('title_give') # title_give이름으로 받아와서 변수선언
print(title_receive)
return jsonify({'result':'success', 'msg': '이 요청은 GET!'}) # API(GET요청)코드 끝
@app.route('/test', methods=['POST']) # POST는 이쪽으로 적용
def test_post():
title_receive = request.form['title_give']
print(title_receive)
return jsonify({'result':'success', 'msg': '이 요청은 POST!'}) // 딱 이안의 값이 index.html의 response값으로 들어감\
// 배열값이니 response['msg']를 불러오면 이 요청은 POST! 이것만 뜸
if __name__ == '__main__':
app.run('0.0.0.0',port=5000,debug=True)
화성땅 구매페이지 형식으로 실습 첫번째
# 준비
1. Pycham에서 sparta\projects\mars에 새 프로젝트 만들기
2. static 폴더, templates 폴더, app.py 파이썬파일, index.html(★templates폴더안에★) 만들어두기
3. 설정 > 프로젝트:mars > python 인터프리터 > +클릭 > flask, pymongo, dnspython 각각 설치
4. mongoDB 사이트 켜놓기
# 사이트 작동과정
1. 이름, 주소, 평수(선택) 을 적고 "주문하기" 버튼을 누르면 DB에 저장 (저장이 완료되면서 "주문완료"라고 메세지 뜨기)
2. 1번에서 입력한 이름, 주소, 평수 정보를 아래 추가해서 나오게하기
# 작동방식
1. API 만들고 사용하기 - 이름, 주소, 평수 저장하기(Create → POST)
- 요청 정보 : URL= /orders, 요청 방식 = POST
- 클라(ajax) → 서버(flask) : name, address, size
- 서버(flask) → 클라(ajax) : 메시지를 보냄 (주문 완료!)
2. API 만들고 사용하기 - 저장된 주문을 화면에 보여주기(Read → GET)
- 요청 정보 : URL= /orders, 요청 방식 = GET
- 클라(ajax) → 서버(flask) : (없음)
- 서버(flask) → 클라(ajax) : 전체 주문을 보내주기
# app.py
from flask import Flask, render_template, request, jsonify # [flask서버] 라이브러리 설정
app = Flask(__name__)
from pymongo import MongoClient # [mangoDB] 라이브러리 설정
client = MongoClient('mongodb+srv://test:sparta@cluster0.ulohwc9.mongodb.net/Cluster0?retryWrites=true&w=majority')
db = client.dbsparta
@app.route('/') # [flask서버] html관련 기본1 (연결)
def home():
return render_template('index.html')
@app.route("/mars", methods=["POST"]) # [flask서버] html관련 기본2 (POST)
def mars_post():
name_receive = request.form['name_give'] # [flask서버] 3개값 가져오기 (key값이 name_give로 들어온 값을 name_receive라는 변수에 넣음)
address_receive = request.form['address_give'] # 즉, index.html의 값인 name이 여기 app.py에선 name_receive 변수에 넣음
size_receive = request.form['size_give']
doc = { # [mangoDB] DB에 넣기위한 배열변수 설정
'name': name_receive, # app.py에서의 변수인 name_receive을 값으로 넣음
'address': address_receive,
'size': size_receive
}
db.orders.insert_one(doc) # [mangoDB] DB에 데이터1개 추가 (mangoDB에서의 orders 폴더에 추가)
return jsonify({'msg': '주문 완료!'}) # [flask서버] POST처리 끝 메세지
@app.route("/mars", methods=["GET"]) # [flask서버] html관련 기본3 (GET)
def mars_get():
orders_list = list(db.orders.find({},{'_id':False})) # [mangoDB] orders폴더의 여러 전체값을 배열변수로 넣음
return jsonify({'orders':orders_list}) # [flask서버] GET처리 끝 (order라는 key값에 orders_list의 value값을 넣어 보낸다)
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 http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet"
integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM"
crossorigin="anonymous"></script>
<link href="https://fonts.googleapis.com/css2?family=Gowun+Batang:wght@400;700&display=swap" rel="stylesheet">
<title>선착순 공동구매</title>
<style>
* {
font-family: 'Gowun Batang', serif;
color: white;
}
body {
background-image: linear-gradient(0deg, rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0.5)), url('https://cdn.aitimes.com/news/photo/202010/132592_129694_3139.jpg');
background-position: center;
background-size: cover;
}
h1 {
font-weight: bold;
}
.order {
width: 500px;
margin: 60px auto 0px auto;
padding-bottom: 60px;
}
.mybtn {
width: 100%;
}
.order > table {
margin: 40px 0;
font-size: 18px;
}
option {
color: black;
}
</style>
<script>
$(document).ready(function () { // 페이지 열때 show_order() 함수 실행
show_order();
});
function show_order() { // [flask서버] html관련 기본3 (GET)
$('#order-box').empty() // [jQuery] 업데이트를 위해 기존것 지우기
$.ajax({ // [flask서버] GET설정
type: 'GET',
url: '/mars',
data: {},
success: function (response) {
let rows = response['orders'] // [flask서버] 서버에서 GET으로 보낸 값중 key값이 orders로 온 값을 rows에 넣는다
for (let i = 0; i < rows.length; i++) { // [JS] 서버에서 온 값은 전체리스트를 하나의 배열값으로 왔으니 for문으로 풀어야한다.
let name = rows[i]['name']
let address = rows[i]['address']
let size = rows[i]['size']
// [jQuery] html추가하기 기능
let temp_html = `
<tr>
<td>${name}</td>
<td>${address}</td>
<td>${size}</td>
</tr>
`
$('#order-box').append(temp_html)
}
}
});
}
function save_order() { // [flask서버] html관련 기본2 (POST)
let name = $('#name').val() // [jQuery] 변수값 3개 선언
let address = $('#address').val()
let size = $('#size').val()
$.ajax({ // [flask서버] POST설정
type: 'POST',
url: '/mars',
data: {name_give: name, address_give: address, size_give: size}, //key값, value값 3개다 설정 (key값:name_give, value값:name)
success: function (response) {
alert(response['msg'])
window.location.reload() // 새로고침 해주기 기능
}
});
}
</script>
</head>
<body>
<div class="mask"></div>
<div class="order">
<h1>화성에 땅 사놓기!</h1>
<h3>가격: 평 당 500원</h3>
<p>
화성에 땅을 사둘 수 있다고?<br/>
앞으로 백년 간 오지 않을 기회. 화성에서 즐기는 노후!
</p>
<div class="order-info">
<div class="input-group mb-3">
<span class="input-group-text">이름</span>
<input id="name" type="text" class="form-control"> <!--name값 입력-->
</div>
<div class="input-group mb-3">
<span class="input-group-text">주소</span>
<input id="address" type="text" class="form-control"> <!--address값 입력-->
</div>
<div class="input-group mb-3">
<label class="input-group-text" for="size">평수</label>
<select class="form-select" id="size"> <!--size값 입력-->
<option selected>-- 주문 평수 --</option>
<option value="10평">10평</option>
<option value="20평">20평</option>
<option value="30평">30평</option>
<option value="40평">40평</option>
<option value="50평">50평</option>
</select>
</div>
<button onclick="save_order()" type="button" class="btn btn-warning mybtn">주문하기</button>
<!--save_order 함수로 실행-->
</div>
<table class="table">
<thead>
<tr>
<th scope="col">이름</th>
<th scope="col">주소</th>
<th scope="col">평수</th>
</tr>
</thead>
<tbody id="order-box"> <!--html추가 부분 order-box 설정-->
</tbody>
</table>
</div>
</body>
</html>
최애 영화 기록페이지로 실습 두번째
# 준비
1. Pycham에서 sparta\projects\mars에 새 프로젝트 만들기
2. static 폴더, templates 폴더, app.py 파이썬파일, index.html(templates폴더안에) 만들어두기
3. 설정 > 프로젝트:mars > python 인터프리터 > +클릭 > flask, pymongo, dnspython 각각 설치
4. 설정 > 프로젝트:mars > python 인터프리터 > +클릭 > requests, bs4 각각 설치 # 크롤링관련 라이브러리
5. mongoDB 사이트 켜놓기
# 사이트 작동과정
1. 영화URL, 별점(선택), 코멘트를 적고 "기록하기" 버튼을 누르면 DB에 저장
2. 1번에서 입력한 정보3개 아래 카드형식으로 추가해서 나오게하기
3. 2번의 영화URL정보는 그대로 나오지않고 네이버영화에서 영화포스터, 영화제목, 영화줄거리가 자동으로 대신 나오게하기 # 크롤링 기능추가
# 작동방식
1. API 만들고 사용하기 - 영화URL, 별점, 코멘트 저장하기(Create → POST)
- 요청 정보 : URL= /movies2, 요청 방식 = POST
- 클라(ajax) → 서버(flask) : url, star, comment
- 서버(flask) 크롤링 : image, title, desc, star, comment
- 서버(flask) → 클라(ajax) : 메시지를 보냄 (저장 완료!)
2. API 만들고 사용하기 - 저장된 주문을 화면에 보여주기(Read → GET)
- 요청 정보 : URL= /movies2, 요청 방식 = GET
- 클라(ajax) → 서버(flask) : (없음)
- 서버(flask) → 클라(ajax) : 전체 주문을 보내주기
3. URL만으로 주요 내용 값 크롤링하기
- meta tag 가져오기 (meta tag는 카카오톡에 URL 넣으면 자동으로 뜨는 이미지,제목,설명 등으로 넣은 대표정보)
# app.py
from flask import Flask, render_template, request, jsonify
app = Flask(__name__)
from pymongo import MongoClient
client = MongoClient('mongodb+srv://test:sparta@cluster0.ulohwc9.mongodb.net/Cluster0?retryWrites=true&w=majority')
db = client.dbsparta
import requests # [파이썬 크롤링] 관련 라이브러리 불러오기
from bs4 import BeautifulSoup
@app.route('/')
def home():
return render_template('index.html')
@app.route("/movie", methods=["POST"])
def movie_post():
url_receive = request.form['url_give']
star_receive = request.form['star_give']
comment_receive = request.form['comment_give']
# [파이썬 크롤링] 시작
# [파이썬 크롤링] 기본 설정 3줄
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')
# 기존 Copy Sector가 아닌 Tag의 항목으로 크롤링하는 다른 방식
og_image = soup.select_one('meta[property="og:image"]') # meta태그에 항목이 property="og:image"인 태그값을 og_image에 넣어라
# og_image의 값은 <meta property="og:image" content="이미지URL">
og_title = soup.select_one('meta[property="og:title"]')
og_description = soup.select_one('meta[property="og:description"]')
image = og_image['content'] # <meta property="og:image" content="이미지URL">의 content항목의 값만 image에 넣어라
title = og_title['content']
description = og_description['content']
# [파이썬 크롤링] 끝
doc = {
'image': image,
'title': title,
'desc': description,
'star': star_receive,
'comment': comment_receive
}
db.movies2.insert_one(doc)
return jsonify({'msg': '저장 완료!'})
@app.route("/movie", methods=["GET"])
def movie_get():
movies_list = list(db.movies2.find({}, {'_id': False}))
return jsonify({'movies': movies_list})
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">
integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM"
crossorigin="anonymous"></script>
<title>스파르타 피디아</title>
<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();
});
function listing() {
$('#cards-box').empty()
$.ajax({
type: 'GET',
url: '/movie',
data: {},
success: function (response) {
let rows = response['movies']
for (let i = 0; i < rows.length; i++) {
let image = rows[i]['image']
let title = rows[i]['title']
let desc = rows[i]['desc']
let star = rows[i]['star']
let comment = rows[i]['comment']
let star_image = '⭐'.repeat(star) // [jQuery] 별표시로 바꾸기
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)
}
}
})
}
function posting() {
let url = $('#url').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()
}
});
}
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="input-group mb-3">
<label class="input-group-text" for="inputGroupSelect01">별점</label>
<select class="form-select" id="star">
<option selected>-- 선택하기 --</option>
<option value="1">⭐</option>
<option value="2">⭐⭐</option>
<option value="3">⭐⭐⭐</option>
<option value="4">⭐⭐⭐⭐</option>
<option value="5">⭐⭐⭐⭐⭐</option>
</select>
</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>
</div>
</body>
</html>
'개발일지' 카테고리의 다른 글
파이썬 데이터분석 4주차 정리 (주식 그래프 백테스팅) (0) | 2022.12.19 |
---|---|
웹프로그래밍 - 파이썬 API다루기, 크롤링, DB처리 3주차 정리 (0) | 2022.12.19 |
파이썬 데이터분석 3주차 정리 (OpenDart의 API다루기) (0) | 2022.12.18 |
웹프로그래밍 - jQuer, Ajax 기초 2주차 정리 (0) | 2022.12.17 |
웹프로그래밍 - HTML/CSS/자바스크립트 기초 1주차 정리 (0) | 2022.12.15 |