-
웹개발 종합반 4주차 배운내용스파르타코딩클럽/[내일배움단]웹개발 종합반 2022. 6. 15. 15:24
01. 4주차 오늘 배울 것
02. Flask시작하기 - 서버만들기
1) Flask 패키지 설치하고 시작!
2) Flask 기초: 기본 실행
3) Flask 기초: URL 나눠보기
from flask import Flask app = Flask(__name__) @app.route('/') def home(): return 'This is Home!' @app.route('/mypage') def mypage(): return 'This is My Page!' if __name__ == '__main__': app.run('0.0.0.0',port=5000,debug=True)
03. Flask시작하기 - HTML파일 주기
4) Flask 기초: 기본 폴더구조 - 항상 이렇게 세팅하고 시작!
5) Flask 기초: HTML 파일 불러오기
- 간단한 index.html 파일을 templates 안에 만들기
- html 파일 불러오기
from flask import Flask, render_template app = Flask(__name__) ## URL 별로 함수명이 같거나, ## route('/') 등의 주소가 같으면 안됩니다. @app.route('/') def home(): return render_template('index.html') if __name__ == '__main__': app.run('0.0.0.0', port=5000, debug=True)
04. Flask시작하기 - 본격 API 만들기
6) 들어가기 전에: GET, POST 요청타입 - 리마인드
7) GET, POST 요청에서 클라이언트의 데이터를 받는 방법
- 예를 들어, 클라이언트에서 서버에 title_give란 키 값으로 데이터를 들고왔다고 생각합시다. (주민등록번호 라는 키 값으로 850120- .. 을 가져온 것과 같은 의미)
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!'})
GET 요청 확인 Ajax코드
더보기$.ajax({ type: "GET", url: "/test?title_give=봄날은간다", data: {}, success: function(response){ console.log(response) } })
POST 요청 API코드
더보기@app.route('/test', methods=['POST']) def test_post(): title_receive = request.form['title_give'] print(title_receive) return jsonify({'result':'success', 'msg': '이 요청은 POST!'})
POST 요청 확인 Ajax코드
더보기$.ajax({ type: "POST", url: "/test", data: { title_give:'봄날은간다' }, success: function(response){ console.log(response) } })
05. [모두의책리뷰] - 프로젝트 세팅
8) 프로젝트 설정 - flask 폴더 구조 만들기
06. [모두의책리뷰] - POST 연습(리뷰 저장)
9) API 만들고 사용하기 - 제목, 저자, 리뷰 정보 저장하기(Create → POST)
1. 클라이언트와 서버 확인하기
- 여기서는 적혀 있는 쌍으로 되어있는 서버-클라이언트 코드를 확인하고 갈게요.
- 분홍 형광펜 부분이 서로 어떻게 매칭되는지 확인해보세요!
서버 코드
더보기## API 역할을 하는 부분 @app.route('/review', methods=['POST']) def write_review(): # 1. 클라이언트가 준 title, author, review 가져오기. # 2. DB에 정보 삽입하기 # 3. 성공 여부 & 성공 메시지 반환하기 return jsonify({'result': 'success', 'msg': '리뷰가 성공적으로 작성되었습니다.'})
클라이언트 코드
더보기function makeReview() { // 1. 제목, 저자, 리뷰 내용을 가져옵니다. // 2. 제목, 저자, 리뷰 중 하나라도 입력하지 않았을 경우 alert를 띄웁니다. // 3. POST /review 에 저장을 요청합니다. $.ajax({ type: "POST", url: "/review", data: { }, success: function (response) { if (response["result"] == "success") { alert(response["msg"] ); window.location.reload(); } } }) }
2. 서버부터 만들기
@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': '리뷰가 성공적으로 작성되었습니다.'})
3. 클라이언트 만들기
function makeReview() { // 화면에 입력어 있는 제목, 저자, 리뷰 내용을 가져옵니다. 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(); } }) }
4. 완성 확인하기
07. [모두의책리뷰] - GET 연습(리뷰 보여주기)
10) API 만들고 사용하기 - 저장된 리뷰를 화면에 보여주기(Read → GET)
1. 클라이언트와 서버 확인하기
- 여기서는 미리 적혀 있는 쌍으로 되어있는 서버-클라이언트 코드를 확인하고 갈게요.
- 분홍 형광펜 부분이 서로 어떻게 매칭되는지 확인해보세요!
서버 코드
더보기@app.route('/review', methods=['GET']) def read_reviews(): sample_receive = request.args.get('sample_give') print(sample_receive) return jsonify({'msg': '이 요청은 GET!'})
클라이언트 코드
더보기function showReview() { // 서버의 데이터를 받아오기 $.ajax({ type: "GET", url: "/review?sample_give=샘플데이터", data: {}, success: function (response) { alert(response["msg"]); } }) }
2. 서버부터 만들기
@app.route('/review', methods=['GET']) def read_reviews(): # 1. DB에서 리뷰 정보 모두 가져오기 reviews = list(db.bookreview.find({}, {'_id': False})) # 2. 성공 여부 & 리뷰 목록 반환하기 return jsonify({'all_reviews': reviews})
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) } } }) }
4. 완성 확인하기
11) 전체 완성 코드
서버 코드
더보기from flask import Flask, render_template, jsonify, request app = Flask(__name__) from pymongo import MongoClient client = MongoClient('localhost', 27017) db = client.dbsparta ## HTML을 주는 부분 @app.route('/') def home(): return render_template('index.html') ## 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': '저장 완료!'}) @app.route('/review', methods=['GET']) def read_reviews(): reviews = list(db.bookreview.find({}, {'_id': False})) return jsonify({'all_reviews': reviews}) if __name__ == '__main__': app.run('0.0.0.0', port=5000, debug=True)
클라이언트 코드
더보기<!DOCTYPE html> <html lang="ko"> <head> <!-- Webpage Title --> <title>모두의 책리뷰 | 스파르타코딩클럽</title> <!-- Required meta tags --> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <!-- Bootstrap CSS --> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous"> <!-- JS --> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous"></script> <!-- 구글폰트 --> <link href="https://fonts.googleapis.com/css?family=Do+Hyeon&display=swap" rel="stylesheet"> <script type="text/javascript"> $(document).ready(function () { showReview(); }); 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(); } }) } 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) } } }) } </script> <style type="text/css"> * { font-family: "Do Hyeon", sans-serif; } h1, h5 { display: inline; } .info { margin-top: 20px; margin-bottom: 20px; } .review { text-align: center; } .reviews { margin-top: 100px; } </style> </head> <body> <div class="container" style="max-width: 600px;"> <img src="https://image.freepik.com/free-vector/large-bookcase-with-books-library-book-shelf-interior_92863-357.jpg" class="img-fluid" alt="Responsive image"> <div class="info"> <h1>읽은 책에 대해 말씀해주세요.</h1> <p>다른 사람을 위해 리뷰를 남겨주세요! 다 같이 좋은 책을 읽는다면 다 함께 행복해질 수 있지 않을까요?</p> <div class="input-group mb-3"> <div class="input-group-prepend"> <span class="input-group-text">제목</span> </div> <input type="text" class="form-control" id="title"> </div> <div class="input-group mb-3"> <div class="input-group-prepend"> <span class="input-group-text">저자</span> </div> <input type="text" class="form-control" id="author"> </div> <div class="input-group mb-3"> <div class="input-group-prepend"> <span class="input-group-text">리뷰</span> </div> <textarea class="form-control" id="bookReview" cols="30" rows="5" placeholder="140자까지 입력할 수 있습니다."></textarea> </div> <div class="review"> <button onclick="makeReview()" type="button" class="btn btn-primary">리뷰 작성하기</button> </div> </div> <div class="reviews"> <table class="table"> <thead> <tr> <th scope="col">제목</th> <th scope="col">저자</th> <th scope="col">리뷰</th> </tr> </thead> <tbody id="reviews-box"> </tbody> </table> </div> </div> </body> </html>
08. [나홀로메모장] - API 설계하기
12) 프로젝트 설계 - 만들 API 설계
09. [나홀로메모장] - 조각 기능 구현해보기
13) 프로젝트 준비 - URL 에서 페이지 정보 가져오기(meta태그 스크래핑)
meta 태그에 대해 알아보기
- (링크)에 접속한 뒤 크롬 개발자 도구를 이용해 HTML의 생김새를 살펴볼까요?
- 메타 태그는, <head></head> 부분에 들어가는, 눈으로 보이는 것(body) 외에 사이트의 속성을 설명해주는 태그들입니다.
- 예) 구글 검색 시 표시 될 설명문, 사이트 제목, 카톡 공유 시 표시 될 이미지 등
- 우리는 그 중 og:image / og:title / og:description 을 크롤링 할 예정입니다.
meta 태그 스크래핑 하기
- 연습을 위해 meta_prac.py 파일을 만들어봅니다. 기본 준비를 합니다.
크롤링 기본 코드
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_one을 이용해 meta tag를 먼저 가져와봅니다.
og_image = soup.select_one('meta[property="og:image"]') og_title = soup.select_one('meta[property="og:title"]') og_description = soup.select_one('meta[property="og:description"]') print(og_image) print(og_title) print(og_description)
- 가져온 meta tag의 content를 가져와봅시다.
url_image = og_image['content'] url_title = og_title['content'] url_description = og_description['content'] print(url_image) print(url_title) print(url_description)
10. [나홀로메모장] - POST 연습(메모하기)
14) API 만들고 사용하기 - 포스팅API (Create → POST)
1) 클라이언트와 서버 연결 확인하기
- 여기서는 미리 적혀 있는 쌍으로 되어있는 서버-클라이언트 코드를 확인하고 갈게요.
- 분홍 형광펜 부분이 서로 어떻게 매칭되는지 확인해보세요!
서버 코드
@app.route('/memo', methods=['POST']) def post_articles(): sample_receive = request.form['sample_give'] print(sample_receive) return jsonify({'msg': 'POST 연결되었습니다!'})
클라이언트 코드
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>
2) 서버부터 만들기
@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':'저장이 완료되었습니다!'})
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() } }) }
4) 완성 확인하기
11. [나홀로메모장] - GET 연습(보여주기)
15) API 만들고 사용하기 - 리스팅 API (Read → GET)
1) 클라이언트와 서버 연결 확인하기
- 여기서는 미리 적혀 있는 쌍으로 되어있는 서버-클라이언트 코드를 확인하고 갈게요.
- 분홍 형광펜 부분이 서로 어떻게 매칭되는지 확인해보세요!
서버코드
더보기@app.route('/memo', methods=['GET']) def read_articles(): # 1. 모든 document 찾기 & _id 값은 출력에서 제외하기 # 2. articles라는 키 값으로 영화정보 내려주기 return jsonify({'result':'success', 'msg':'GET 연결되었습니다!'})
클라이언트 코드
더보기function showArticles() { $.ajax({ type: "GET", url: "/memo", data: {}, success: function (response) { if (response["result"] == "success") { alert(response["msg"]); } } }) }
2) 서버부터 만들기
@app.route('/memo', methods=['GET']) def listing(): articles = list(db.articles.find({}, {'_id': False})) return jsonify({'all_articles':articles})
3) 클라이언트 만들기
function showArticles() { $.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) } } }) }
4) 완성 확인하기
16) 전체 완성 코드
클라이언트 코드
더보기<!Doctype html> <html lang="ko"> <head> <!-- Required meta tags --> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <!-- Bootstrap CSS --> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous"> <!-- JS --> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous"></script> <!-- 구글폰트 --> <link href="https://fonts.googleapis.com/css?family=Stylish&display=swap" rel="stylesheet"> <title>스파르타코딩클럽 | 나홀로 메모장</title> <!-- style --> <style type="text/css"> * { font-family: "Stylish", sans-serif; } .wrap { width: 900px; margin: auto; } .comment { color: blue; font-weight: bold; } #post-box { width: 500px; margin: 20px auto; padding: 50px; border: black solid; border-radius: 5px; } </style> <script> $(document).ready(function () { showArticles(); }); function openClose() { if ($("#post-box").css("display") == "block") { $("#post-box").hide(); $("#btn-post-box").text("포스팅 박스 열기"); } else { $("#post-box").show(); $("#btn-post-box").text("포스팅 박스 닫기"); } } 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() } }) } function showArticles() { $.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) } } }) } </script> </head> <body> <div class="wrap"> <div class="jumbotron"> <h1 class="display-4">나홀로 링크 메모장!</h1> <p class="lead">중요한 링크를 저장해두고, 나중에 볼 수 있는 공간입니다</p> <hr class="my-4"> <p class="lead"> <button onclick="openClose()" id="btn-post-box" type="button" class="btn btn-primary">포스팅 박스 열기 </button> </p> </div> <div id="post-box" class="form-post" style="display:none"> <div> <div class="form-group"> <label for="post-url">아티클 URL</label> <input id="post-url" class="form-control" placeholder=""> </div> <div class="form-group"> <label for="post-comment">간단 코멘트</label> <textarea id="post-comment" class="form-control" rows="2"></textarea> </div> <button type="button" class="btn btn-primary" onclick="postArticle()">기사저장</button> </div> </div> <div id="cards-box" class="card-columns"> </div> </div> </body> </html>
서버 코드
더보기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.dbsparta ## HTML을 주는 부분 @app.route('/') def home(): return render_template('index.html') @app.route('/memo', methods=['GET']) def listing(): articles = list(db.articles.find({}, {'_id': False})) return jsonify({'all_articles':articles}) ## API 역할을 하는 부분 @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':'저장이 완료되었습니다!'}) if __name__ == '__main__': app.run('0.0.0.0',port=5000,debug=True)
'스파르타코딩클럽 > [내일배움단]웹개발 종합반' 카테고리의 다른 글
5주차 마무리 (0) 2022.06.18 웹개발 종합반 3주차 배운내용 (0) 2022.06.04 웹개발 종합반 2주차 배운내용 (0) 2022.05.26 웹개발 종합반 1주차 배운내용 (0) 2022.05.20