웹 개발 일지_server
server
- 컴퓨터에서 실행중인 하나의 프로그램이라고 생각하기
- 보통은 자신의 컴퓨터에 서버를 만들고, 다시 브라우저를 통해 접속하는 환경을 로컬개발환경이라고 한다.
- 특정 컴퓨터를 사서 해당 컴퓨터에 파일을 올려놓는 것
Flask시작하기
-
server의 FrameWork인 Flask설치하기
-
pip install flask
or pycharm interpreter이용
-
FlaskFrameWork패키지
남이 짜둔 규칙이나 틀 안에서 구성하는 것 -
시작코드
5000번 port를 사용할 수 없어서 5001번 port를 사용함.
macOS Monterey는 port:5000에서 실행되는 AirPlay 수신기를 도입했다.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=5001,debug=True)
-
페이지 추가
from flask import Flask app = Flask(__name__) @app.route('/') def home(): return '나의 첫 서버!' @app.route('/myPage') def myPage(): return 'myPage입니다.' if __name__ == '__main__': app.run('0.0.0.0',port=5001,debug=True)
폴더 구조
-
static - CSS나 image를 담는 곳
-
templates - Page를 담는곳
-
랜더링
from flask import Flask, render_template app = Flask(__name__) @app.route('/') def home(): return render_template('index.html')
API 만들기
- client의 요청을 받기위한 창구
- GET, POST 등의 방식이 있다.
- request, jsonify를 import하여 사용.
GET
<데이터 조회>
데이터 전달 : URL뒤에 물음표를 붙여 key = value로 전달
ex) google.com?q=북극곰
- API
from flask import Flask, render_template, request, jsonify app = Flask(__name__) @app.route('/test', methods=['GET']) def test_get(): title_receive = request.args.get('title_give') print(title_receive) return jsonify({'result':'success', 'msg': '이 요청은 GET!'})
- Client
$.ajax({ type: "GET", url: "/test?title_give=봄날은간다", data: {}, success: function(response){ console.log(response) } })
- GET타입으로 서버에 요청한다.
- /test로 요청된 title_give = 봄날은간다
- API에서 request.args.get('title_give')로 데이터 조회
- 잘 못 조회할 시 이는 Client Error
- API에서는 print(title_receive)를 통해 console에 '봄날은간다' 출력
- Client에서는 API의 return문을 response로 받아서 console에 출력
POST
<데이터를 수정>
데이터 전달 : 바로 보이지 않는 HTML body에 key:value형태로 전달
- API
from flask import Flask, render_template, request, jsonify app = Flask(__name__) @app.route('/test', methods=['POST']) def test_post(): title_receive = request.form['title_give'] print(title_receive) return jsonify({'result':'success', 'msg': '이 요청은 POST!'})
- Client
$.ajax({ type: "POST", url: "/test", data: { title_give:'봄날은간다' }, success: function(response){ console.log(response) } })
- POST타입으로 서버에 요청한다.
- /test로 data: {title_give : '봄날은간다'}를 전송
- API에서 request.form['title_give']로 데이터 조회
- 잘 못 조회할 시 이는 Server Error
- API에서는 print(title_receive)를 통해 console에 '봄날은간다' 출력
- Client에서는 API의 return문을 response로 받아서 console에 출력
모두의 책리뷰 코드 분석
기본설정
- Flask패키지 (server구현)
- pymongo설치 (DB구현)
- 리뷰저장
데이터를 생성 및 수정해야하므로 (CREAT->POST) - 리뷰열람
데이터를 열람하므로 (READ->GET)
Post 순서
1. 클라이언트와 서버 확인하기
Server
from flask import Flask, render_template, jsonify, request app = Flask(__name__) from pymongo import MongoClient client = MongoClient('localhost', 27017) db = client.practice ## API 역할을 하는 부분 @app.route('/review', methods=['POST']) def write_review(): sample_receive = request.form['sample_give'] print(sample_receive) return jsonify({'msg': '이 요청은 POST!'})
Client
function makeReview() { $.ajax({ type: "POST", url: "/review", data: {sample_give:'샘플데이터'}, success: function (response) { alert(response["msg"]); window.location.reload(); } }) }
- 서버부터 만들기
Server
from flask import Flask, render_template, jsonify, request app = Flask(__name__) from pymongo import MongoClient client = MongoClient('localhost', 27017) db = client.practice ## API 역할을 하는 부분 @app.route('/review', methods=['POST']) def write_review(): title_receive = request.form['title_give'] author_receive = request.form['author_give'] review_receive = request.form['review_give'] doc = { 'title' : title_receive, 'author' : author_receive, 'review' : review_receive, } db.bookreview.insert_one(doc) return jsonify({'msg':'저장완료'})
- 클라이언트 만들기
Client
function makeReview() { let title = $('#title').val() let author = $('#author').val() let review = $('#bookReview').val() $.ajax({ type: "POST", url: "/review", data: {title_give:title, author_give:author, review_give:review}, success: function (response) { alert(response["msg"]); window.location.reload(); } }) }
- 완성 확인하기
GET 순서
1. 클라이언트와 서버 확인하기
Server
from flask import Flask, render_template, jsonify, request app = Flask(__name__) from pymongo import MongoClient client = MongoClient('localhost', 27017) db = client.dbsparta ## API 역할을 하는 부분 @app.route('/review', methods=['GET']) def read_reviews(): sample_receive = request.args.get('sample_give') print(sample_receive) return jsonify({'msg': '이 요청은 GET!'})
Client
// 로딩되자마자 실행되는 함수 $(document).ready(function () { showReview(); }); function showReview() { $.ajax({ type: "GET", url: "/review?sample_give=샘플데이터", data: {}, success: function (response) { alert(response["msg"]); } }) }
- 서버부터 만들기
Server
from flask import Flask, render_template, jsonify, request app = Flask(__name__) from pymongo import MongoClient client = MongoClient('localhost', 27017) db = client.practice ## API 역할을 하는 부분 @app.route('/review', methods=['GET']) def read_reviews(): reviews = list(db.bookreview.find({}, {'_id': False})) return jsonify({'all_reviews': reviews})
- 클라이언트 만들기
Client
// 로딩되자마자 실행되는 함수 $(document).ready(function () { showReview(); }); function showReview() { $.ajax({ type: "GET", //client가 가져가야할 데이터가 없다. 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) } } }) }
- 완성 확인하기
나홀로 메모장 코드 분석
기본설정
- Flask패키지 (server구현)
- pymongo설치 (DB구현)
- requests, bs4 (크롤링)
포스팅 API 설계(POST)
- URL과 코멘트를 SERVER에 보내고 저장해야한다.
- 저장되어 있는 데이터(이미지, 제목, 요약, 코멘트, link)를 보여주어야 한다.
요청 정보
- 요청 URL =
/memo
, 요청 방식 = POST- 요청 데이터 = URL(url_give), 코멘트(comment_give)
서버가 제공할 기능
- URL의 meta태그 정보를 바탕으로 제목, 설명, 이미지URL스크래핑
- (제목, 설명, URL, 이미지URL, 코멘트) 정보를 모두 DB에 저장
응답 데이터
- API가 정상적으로 작동하는지 Client에게 알려주기 위해 성고메세지 보내기
- (JSON형식) 'result'='success'
리스팅 API 설계(GET)
- 사용자로부터 데이터를 받아올 필요가 없음
- 저장되어 있는 데이터만 보면 됨.
- 로딩 직후 바로 보여주어야 함.
요청 정보
- 요청 URL =
/memo
, 요청 방식 = GET- 요청 데이터 : 없음
서버가 제공할 기능
- DB에 저장되어 있는 모든(제목, 설명, URL, 이미지URL, 코멘트)정보를 가져오기
응답 데이터
- Article(기사)들의 정보(제목, 설명, URL, 이미지URL, 코멘트)를 사용하여 카드 만들어서 붙이기
- (JSON형식)'articles':아티클 정보
조각기능 구현하기
- URL에서 페이지 정보 가져오기 (meta태그 스크래핑)
- meta태그는
<head>~</head>
안에 들어있는 눈으로 보이는것(<body>~</body>
외에 사이트의 속성을 설명해주는 태그(정보)
ex) 구글 검색 시 표시 될 설명문, 사이트 제목, 카톡 공유 시 표시 될 이미지 등..
그 중 og:image/og:title/og:description을 크롤링할 예정
조각 가져오기
import requests from bs4 import BeautifulSoup #영화 해적 url = 'https://movie.naver.com/movie/bi/mi/basic.naver?code=194204' 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를 먼저 가져와보겠습니다. #print(soup) #해당 페이지에서 검사를 통해 Copy.selector title = soup.select_one('head > meta:nth-child(9)') #찾아오지 못한다.. 이유 파이썬에서 받아오는 html과 페이지에서 제공하는 html의 태그 순서가 서로 다르기 때문에.. print(title)
import requests from bs4 import BeautifulSoup #영화 해적 url = 'https://movie.naver.com/movie/bi/mi/basic.naver?code=194204' 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를 먼저 가져와보겠습니다. #print(soup) #딕셔너리 형태로 가져온다. not .text 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)
Post API 순서
1. 클라이언트와 서버 확인하기
Server
from flask import Flask, render_template, jsonify, request app = Flask(__name__) import requests from bs4 import BeautifulSoup from pymongo import MongoClient client = MongoClient('localhost', 27017) db = client.practice ## API 역할을 하는 부분 @app.route('/memo', methods=['POST']) def saving(): sample_receive = request.form['sample_give'] print(sample_receive) return jsonify({'msg':'POST 연결되었습니다!'})
Client
function postArticle() { $.ajax({ type: "POST", url: "/memo", data: {sample_give:'샘플데이터'}, success: function (response) { // 성공하면 alert(response["msg"]); } }) }
<button type="button" class="btn btn-primary" onclick="postArticle()">기사저장</button>
- 서버부터 만들기
Server
from flask import Flask, render_template, jsonify, request app = Flask(__name__) import requests from bs4 import BeautifulSoup from pymongo import MongoClient client = MongoClient('localhost', 27017) db = client.practice ## API 역할을 하는 부분 @app.route('/memo', methods=['POST']) def saving(): url_receive = request.form['url_give'] comment_receive = request.form['comment_give'] # 영화 해적 #url = url_receive 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') # 여기에 코딩을 해서 meta tag를 먼저 가져와보겠습니다. # print(soup) 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, 'comment':comment_receive, } db.articles.insert_one(doc) return jsonify({'msg':'저장 완료'})
- 클라이언트 만들기
Client
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() } }) }
- 완성 확인하기
GET 순서
1. 클라이언트와 서버 확인하기
Server
from flask import Flask, render_template, jsonify, request app = Flask(__name__) import requests from bs4 import BeautifulSoup from pymongo import MongoClient client = MongoClient('localhost', 27017) db = client.practice ## API 역할을 하는 부분 @app.route('/memo', methods=['GET']) def listing(): sample_receive = request.args.get('sample_give') print(sample_receive) return jsonify({'msg':'GET 연결되었습니다!'})
Client
$(document).ready(function () { showArticles(); }); function showArticles() { $.ajax({ type: "GET", url: "/memo?sample_give=샘플데이터", data: {}, success: function (response) { alert(response["msg"]); } }) }
- 서버부터 만들기
Server
import requests from bs4 import BeautifulSoup from pymongo import MongoClient client = MongoClient('localhost', 27017) db = client.practice ## API 역할을 하는 부분 @app.route('/memo', methods=['GET']) def listing(): articles = list(db.articles.find({},{'_id':False})) return jsonify({'all_articles':articles})
- 클라이언트 만들기
Client
$(document).ready(function () { showArticles(); }); function showArticles() { $.ajax({ type: "GET", //요청으로 줄 데이터가 없다. url: "/memo", data: {}, success: function (response) { let articles = response['all_articles'] //console.log(articles) for(let i=0; i<articles.length; i++){ let title = articles[i]['title'] let image = articles[i]['image'] let desc = articles[i]['desc'] let comment = articles[i]['comment'] let url = articles[i]['url'] // console.log(title,image,desc,comment,url) 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) } } }) }
- 완성 확인하기
무비스타 코드 분석
기본설정
- Flask패키지 (server구현)
- pymongo설치 (DB구현)
- requests, bs4 (크롤링)
포스팅 API 설계(POST)
- 저장되어 있는 데이터(이름, 이미지, 최신작, 링크, like)를 보여주어야 한다.
- 좋아요를 누르면 해당 좋아요를 반영한다
- 삭제를 누르면 해당 데이터를 삭제해야한다.
- 사용자에게 따로 입력받을 데이터 필요없음
요청 정보
- 요청 URL =
/api/like
, 요청 방식 = POST- 요청 URL = '/api/delete', 요청 방식 = POST
- 요청 데이터 = 없음.
서버가 제공할 기능
- 좋아요 버튼을 누르면 DB에 반영
- 삭제 버튼을 누르면 DB에 반영
응답 데이터
- API가 정상적으로 작동하는지 Client에게 알려주기 위해 성고메세지 보내기
- (JSON형식) 'result'='success'
리스팅 API 설계(GET)
- 사용자로부터 데이터를 받아올 필요가 없음
- 저장되어 있는 데이터만 보면 됨.
- 로딩 직후 바로 보여주어야 함.
요청 정보
- 요청 URL =
/api/list
, 요청 방식 = GET- 요청 데이터 : 없음
서버가 제공할 기능
- DB에 저장되어 있는 모든(이름, 이미지url, 최근작, URL, like)정보를 가져오기
응답 데이터
- 배우들의 정보(이름, 이미지url, 최근작, URL, like)를 사용하여 like순서로 카드 만들어서 붙이기
- (JSON형식)'articles': 아티클 정보
조각기능 구현하기
- 크롤링 코드
import requests
from bs4 import BeautifulSoup
from pymongo import MongoClient
client = MongoClient('localhost', 27017)
db = client.practice
# DB에 저장할 영화인들의 출처 url을 가져옵니다.
def get_urls():
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('https://movie.naver.com/movie/sdb/rank/rpeople.naver', headers=headers)
soup = BeautifulSoup(data.text, 'html.parser')
trs = soup.select('#old_content > table > tbody > tr')
urls = []
for tr in trs:
a = tr.select_one('td.title > a')
if a is not None:
base_url = 'https://movie.naver.com/'
url = base_url + a['href']
urls.append(url)
return urls
# 출처 url로부터 영화인들의 사진, 이름, 최근작 정보를 가져오고 mystar 콜렉션에 저장합니다.
def insert_star(url):
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')
name = soup.select_one('#content > div.article > div.mv_info_area > div.mv_info.character > h3 > a').text
img_url = soup.select_one('#content > div.article > div.mv_info_area > div.poster > img')['src']
recent_work = soup.select_one(
'#content > div.article > div.mv_info_area > div.mv_info.character > dl > dd > a:nth-child(1)').text
doc = {
'name': name,
'img_url': img_url,
'recent': recent_work,
'url': url,
'like': 0
}
db.mystar.insert_one(doc)
print('완료!', name)
# 기존 mystar 콜렉션을 삭제하고, 출처 url들을 가져온 후, 크롤링하여 DB에 저장합니다.
def insert_all():
db.mystar.drop() # mystar 콜렉션을 모두 지워줍니다.
urls = get_urls()
for url in urls:
insert_star(url)
### 실행하기
insert_all()
Post API 순서
1. 클라이언트와 서버 확인하기
Server
from pymongo import MongoClient from flask import Flask, render_template, jsonify, request app = Flask(__name__) client = MongoClient('localhost', 27017) db = client.practice @app.route('/api/like', methods=['POST']) def like_star(): name_receive = request.form['name_give'] target_star = db.mystar.find_one({'name':name_receive}) new_like = target_star['like'] + 1 db.mystar.update_one({'name':name_receive},{'$set':{'like': new_like}}) return jsonify({'msg': 'like!'}) @app.route('/api/delete', methods=['POST']) def delete_star(): name_receive = request.form['name_give'] db.mystar.delete_one({'name':name_receive}) return jsonify({'msg': '삭제완료!'})
Client
function likeStar(name) { $.ajax({ type: 'POST', url: '/api/like', data: {name_give:name}, success: function (response) { alert(response['msg']); window.location.reload() } }); } function deleteStar(name) { $.ajax({ type: 'POST', url: '/api/delete', data: {name_give:name}, success: function (response) { alert(response['msg']); window.location.reload() } }); }
GET 순서
1. 클라이언트와 서버 확인하기
Server
from pymongo import MongoClient from flask import Flask, render_template, jsonify, request app = Flask(__name__) client = MongoClient('localhost', 27017) db = client.practice # API 역할을 하는 부분 @app.route('/api/list', methods=['GET']) def show_stars(): movie_stars = list(db.mystar.find({},{'_id':False}).sort('like',-1)) return jsonify({'movie_stars': movie_stars})
Client
<script> $(document).ready(function () { showStar(); }); function showStar() { $.ajax({ type: 'GET', url: '/api/list', data: {}, success: function (response) { let mystars = response['movie_stars'] for(let i=0; i<mystars.length; i++){ let name = mystars[i]['name'] let img = mystars[i]['img_url'] let recent = mystars[i]['recent'] let url = mystars[i]['url'] let like = mystars[i]['like'] let temp_html = `<div class="card"> <div class="card-content"> <div class="media"> <div class="media-left"> <figure class="image is-48x48"> <img src="${img}" alt="Placeholder image" /> </figure> </div> <div class="media-content"> <a href="${url}" target="_blank" class="star-name title is-4">${name} (좋아요: ${like})</a> <p class="subtitle is-6">${recent}</p> </div> </div> </div> <footer class="card-footer"> <a href="#" onclick="likeStar('${name}')" class="card-footer-item has-text-info"> 위로! <span class="icon"> <i class="fas fa-thumbs-up"></i> </span> </a> <a href="#" onclick="deleteStar('${name}')" class="card-footer-item has-text-danger"> 삭제 <span class="icon"> <i class="fas fa-ban"></i> </span> </a> </footer> </div>` $('#star-box').append(temp_html) } } }); } </script>
Author And Source
이 문제에 관하여(웹 개발 일지_server), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@yoon_s_whan/웹-개발-일지server저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)