웹 개발 일지_server

56812 단어 webweb

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();
                    }
                })
            }
  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():
    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':'저장완료'})
  1. 클라이언트 만들기

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();
                    }
                })
            }
  1. 완성 확인하기


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"]);
                    }
                })
            }
  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=['GET'])
def read_reviews():
    reviews = list(db.bookreview.find({}, {'_id': False}))
    return jsonify({'all_reviews': reviews})
  1. 클라이언트 만들기

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)
                        }
                    }
                })
            }
  1. 완성 확인하기

나홀로 메모장 코드 분석

기본설정

  • 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>

  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():
    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':'저장 완료'})
  1. 클라이언트 만들기

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()
                    }
                })
            }
  1. 완성 확인하기


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"]);
                    }
                })
            }
  1. 서버부터 만들기

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})
  1. 클라이언트 만들기

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)
                        }
                    }
                })
            }
  1. 완성 확인하기

무비스타 코드 분석

기본설정

  • 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>

좋은 웹페이지 즐겨찾기