Limetime's TimeLine
article thumbnail
Published 2021. 7. 7. 17:39
웹개발 종합반 5주차. Web
반응형

1. 핵심 : 웹 페이지를 AWS로 가상서버 빌려서 인터넷에 배포하기.

1.0.1. 1. 네이버 영화 페이지에서 배우들을 크롤링해서 좋아요를 눌러 순위를 매겨보자!

 ⓐ 네이버 영화 페이지에서 배우들을 긁어와서 DB에 쌓기.

<python />
import requests from bs4 import BeautifulSoup from pymongo import MongoClient client = MongoClient('localhost', 27017) db = client.dbsparta # 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.nhn', 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()

mongoDB의 mystar collection에 크롤링한 데이터가 쌓임.

 

1.0.2. 2. AWS에서 빌린 EC2 서버 세팅. (Ubuntu 18.04 LTS)

<shell />
# UTC to KST 시스템 시간을 한국 시간대로 설정 sudo ln -sf /usr/share/zoneinfo/Asia/Seoul /etc/localtime # python3 -> python python3 명령어를 python으로도 사용할 수 있게 설정 sudo update-alternatives --install /usr/bin/python python /usr/bin/python3 10 # pip3 -> pip 파이썬 패키지 설치를 위한 pip3를 pip로도 가능하게. sudo apt-get update sudo apt-get install -y python3-pip pip3 --version sudo update-alternatives --install /usr/bin/pip pip /usr/bin/pip3 1 # port forwarding 5000번 포트에 요청이 들어오면 80번으로 가게 포트 포워딩 sudo iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j REDIRECT --to-port 5000 # MongoDB - install wget -qO - https://www.mongodb.org/static/pgp/server-4.4.asc | sudo apt-key add - echo "deb [ arch=amd64,arm64 ] https://repo.mongodb.org/apt/ubuntu bionic/mongodb-org/4.4 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-4.4.list sudo apt-get update sudo apt-get install -y mongodb-org sudo mkdir -p /data/db # MongoDB - run sudo service mongod start sleep 7 netstat -tnlp # MongoDB set user, set conf file mongo admin --eval 'db.createUser({user: "test", pwd: "test", roles:["root"]});' sudo sh -c 'echo "security:\n authorization: enabled" >> /etc/mongod.conf' sudo sed -i "s,\\(^[[:blank:]]*bindIp:\\) .*,\\1 0.0.0.0," /etc/mongod.conf sudo service mongod stop sudo service mongod start sleep 5 netstat -tnlp # flask 패키지 설치, pymongo 패키지 설치 pip install flask pip install pymongo

 

1.0.3. 3. AWS에서 5000번 포트 열기. (flask 서버를 위한~)

  • EC2 서버(=가상의 내 컴퓨터)에서 포트를 따로 설정하는 것 외에도, AWS EC2에서도 자체적으로 포트를 열고/닫을 수 있게 관리를 하고 있습니다.
  • → 그래서 AWS EC2 Security Group에서 인바운드 요청 포트를 열어줘야 합니다.
  • 일단, EC2 관리 콘솔로 들어갑니다. 그리고 보안그룹(영문: Security Group)을 눌러 들어갑니다. 여기선 launch-wizard-1 이라고 쓰여 있네요
  • 해당 보안그룹을 클릭합니다.
  • Edit inbound rules를 선택합니다.
  • 세 가지 포트를 추가해봅니다.
  • → 80포트: HTTP 접속을 위한 기본포트
  • → 5000포트 : flask 기본 포트
  • → 27017포트: 외부에서 mongoDB 접속을 하기위한 포트

1.0.4. 4. 서버에 올리기.

<index.html>

<html />
<!DOCTYPE html> <html lang="ko"> <head> <meta charset="UTF-8"/> <meta name="viewport" content="width=device-width, initial-scale=1.0"/> <title>마이 페이보릿 무비스타 | 프론트-백엔드 연결 마지막 예제!</title> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bulma@0.8.0/css/bulma.min.css"/> <script defer src="https://use.fontawesome.com/releases/v5.3.1/js/all.js"></script> <style> .center { text-align: center; } .star-list { width: 500px; margin: 20px auto 0 auto; } .star-name { display: inline-block; } .star-name:hover { text-decoration: underline; } .card { margin-bottom: 15px; } </style> <script> $(document).ready(function () { showStar(); }); function showStar() { $.ajax({ type: 'GET', url: '/api/list?sample_give=샘플데이터', data: {}, success: function (response) { let mystars = response['movie_stars'] for (let i = 0; i < mystars.length; i++) { let name = mystars[i]['name'] let img_url = 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_url}" 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) } } }); } 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() } }); } </script> </head> <body> <section class="hero is-warning"> <div class="hero-body"> <div class="container center"> <h1 class="title"> 마이 페이보릿 무비스타😆 </h1> <h2 class="subtitle"> 순위를 매겨봅시다 </h2> </div> </div> </section> <div class="star-list" id="star-box"> </div> </body> </html>

<app.py>

<python />
from pymongo import MongoClient from flask import Flask, render_template, jsonify, request app = Flask(__name__) client = MongoClient('localhost', 27017) db = client.dbsparta # HTML 화면 보여주기 @app.route('/') def home(): return render_template('index.html') # API 역할을 하는 부분 @app.route('/api/list', methods=['GET']) def show_stars(): movie_star = list(db.mystar.find({}, {'_id': False}).sort('like', -1)) return jsonify({'movie_stars': movie_star}) @app.route('/api/like', methods=['POST']) def like_star(): name_receive = request.form['name_give'] target_star = db.mystar.find_one({'name': name_receive}) current_like = target_star['like'] new_like = current_like + 1 db.mystar.update_one({'name': name_receive}, {'$set': {'like': new_like}}) return jsonify({'msg': '좋아요 완료!'}) @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': '삭제 완료!'}) if __name__ == '__main__': app.run('0.0.0.0', port=5000, debug=True)

 

<shell />
# 계속 서버가 백그라운드로 실행되게 하기. nohup python app.py & ## 서버 종료 - 강제종료 ps -ef | grep 'app.py' kill -9 [pid값]

 

1.0.5. 5. og 태그

<html />
<meta property="og:title" content="내 사이트의 제목" /> <meta property="og:description" content="보고 있는 페이지의 내용 요약" /> <meta property="og:image" content="{{ url_for('static', filename='ogimage.png') }}" />
반응형
profile

Limetime's TimeLine

@Limetime

포스팅이 좋았다면 "공감❤️" 또는 "구독👍🏻" 해주세요!