수업 목표
1. Flask 프레임워크를 활용해서 API를 만들 수 있다.
2. '마이 페이보릿 무비스타'를 완성한다.
3. EC2에 내 프로젝트를 올리고, 자랑한다!
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 콜렉션에 저장합니다.
# 'insert_all' 함수에서 같은 이름으로 사용하게 위해 url을 변수로 지정
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()
app.py
@app.route('/api/list', methods=['GET'])
def show_stars():
sample_receive = request.args.get('sample_give')
print(sample_receive)
return jsonify({'msg': 'list 연결되었습니다!'})
index.html
$(document).ready(function () {
// 새로고침하고 'list 연결되었습니다!' 가 alert 창에 나오면 연결 성공
showStar();
});
function showStar() {
$.ajax({
type: 'GET',
url: '/api/list?sample_give=샘플데이터',
data: {},
success: function (response) {
alert(response['msg']);
}
});
}
@app.route('/api/list', methods=['GET'])
def show_stars():
stars = list(db.mystar.find({}, {'_id': False}).sort("like", -1))
# .sort() : like 값을 역순으로 정렬하라는 함수
return jsonify({'stars': stars})
function showStar() {
$.ajax({
type: 'GET',
url: '/api/list',
data: {},
success: function (response) {
let stars = response['stars']
for (let i = 0; i <stars.length; i++) {
let img_url = stars[i]['img_url']
let like = stars[i]['like']
let name = stars[i]['name']
let recent = stars[i]['recent']
let url = stars[i]['url']
// 배우 소개박스 코드에 DB로부터 받아온 데이터를 대입
let temp_html = `<div class="card" id="star_media">
<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="#"token interpolation">${name}')" class="card-footer-item has-text-info">
위로!<span class="icon"><i class="fas fa-thumbs-up"></i></span>
</a>
<a href="#"token interpolation">${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)
}
}
});
}
app.py
@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': '좋아요 완료!'})
index.html
function likeStar(name) {
$.ajax({
type: 'POST',
url: '/api/like',
data: {name_give:name},
success: function (response) {
alert(response['msg']);
window.location.reload()
}
});
}
@app.route('/api/like', methods=['POST'])
def like_star():
name_receive = request.form['name_give']
# 좋아요를 누른 영화배우를 DB에서 가져온다.
target_star = db.mystar.find_one({'name': name_receive})
# 현재 좋아요 수를 가져온다.
current_like = target_star['like']
# 현재 좋아요 수에 +1을 해준다.
new_like = current_like + 1
# 추가한 좋아요 수를 DB에 업데이트한다.
db.mystar.update_one({'name': name_receive}, {'$set': {'like': new_like}})
return jsonify({'msg': '좋아요 완료!'})
// temp_html에 포함된 좋아요, 삭제하기 버튼 코드 , DB에서 가져온 name값을 변수로 받는다.
<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>
⁞
function likeStar(name) {
$.ajax({
type: 'POST',
url: '/api/like',
// name 변수에 들어온 값을 name_give 라는 이름으로 서버에 전송 , 전송이 잘 되면(success) 서버로부터 return 값을 response 이름으로 받아와 함수 실행
data: {name_give:name},
// 서버에서 제대로 데이터를 받았다면 success 실행, 서버로부터 return 값을 response 이름으로 받아와 함수 실행
success: function (response) {
alert(response['msg']); // 메세지값 alert
window.location.reload(); // 페이지 리로드
}
});
}
app.py
@app.route('/api/delete', methods=['POST'])
def delete_star():
sample_receive = request.form['sample_give']
print(sample_receive)
return jsonify({'msg': 'delete 연결되었습니다!'})
index.html
function deleteStar(name) {
$.ajax({
type: 'POST',
url: '/api/delete',
data: {sample_give:'샘플데이터'},
success: function (response) {
alert(response['msg']);
}
});
}
@app.route('/api/delete', methods=['POST'])
def delete_star():
# 브라우저에서 보내준 데이터(post방식은 data 딕셔너리에 입력)를 받아와 변수에 담는다
name_receive = request.form['name_give']
# DB에 저장
db.mystar.delete_one({'name': name_receive})
# 위 과정이 완료되면 return값 전송
return jsonify({'msg': '삭제되었습니다!!'})
// temp_html에 포함된 좋아요, 삭제하기 버튼 코드 , DB에서 가져온 name값을 변수로 받는다.
<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>
⁞
function deleteStar(name) {
$.ajax({
type: 'POST',
url: '/api/delete',
data: {name_give:name},
success: function (response) {
alert(response['msg']);
window.location.reload()
}
});
}
EC2서버란?
: Amazon Elastic Compute Cloud(Amazon EC2)의 약자로 Amazon Web Services(AWS) 클라우드에서 확장 가능 컴퓨팅 용량을 제공하는 것을 의미
EC2를 구매하면 가상 컴퓨팅 기술을 통해 원격 서버를 사용할 수 있다.(구매절차 생략)
ssh -i 받은키페어를끌어다놓기 ubuntu@AWS에적힌내아이피
예) 아래와 비슷한 생김새!
ssh -i /path/my-key-pair.pem ubuntu@13.125.250.20
ls: 내 위치의 모든 파일을 보여준다.
pwd: 내 위치(폴더의 경로)를 알려준다.
mkdir: 내 위치 아래에 폴더를 하나 만든다.
cd [갈 곳]: 나를 [갈 곳] 폴더로 이동시킨다.
cd .. : 나를 상위 폴더로 이동시킨다.
cp -r [복사할 것] [붙여넣기 할 것]: 복사 붙여넣기
rm -rf [지울 것]: 지우기
sudo [실행 할 명령어]: 명령어를 관리자 권한으로 실행한다.
sudo su: 관리가 권한으로 들어간다. (나올때는 exit으로 나옴)
# 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 : http 기본 포트인 80포트로 요청이 들어오면 5000포트로 자동으로 넘겨주는 개념
# 'IP주소:5000'에서 ':5000'을 생략시키기 위한 작업
sudo iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j REDIRECT --to-port 5000
# MongoDB - install : MongoDB를 원격 서버에 설치
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 : MongoDB 실행
sudo service mongod start
sleep 7
netstat -tnlp
# MongoDB set user, set conf file : mongoDB 접속 계정 생성하기
# admin으로 계정 변경 및 계정 생성(ID,PW : test)하기
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 패키지 설치 : app.py 실행을 위해 필수적
pip install flask
# 기존 명령어 : localhost로 접속
client = MongoClient('localhost', 27017)
# 수정한 명령어 : 원격 서버로 접속
# 아이디 : test , 비밀번호 : test
client = MongoClient('mongodb://아이디:비밀번호@localhost', 27017)
# 설치하기
pip install pymongo
app.py
실행 python app.py
http://내AWS아이피:5000/
내가 SSH 접속을 끊었을 때 다른 사람이 내가 만든 사이트에 접속할 수 없다면 제대로 된 웹 서비스 런칭이라 볼 수 없다. 이를 해결하기 위한 방법이 nohup 설정을 하는 것이다.
nohup 설정 명령어
# 아래의 명령어로 실행하면 된다
nohup python app.py &
# 아래 명령어로 미리 pid 값(프로세스 번호)을 본다
ps -ef | grep 'app.py'
# 아래 명령어로 특정 프로세스를 죽인다
# pid값 : 5자리 숫자조합 중 앞에 두가지 값
kill -9 [pid값]
nohup python app.py &
// head 태그 안에 아래 태그를 추가, content 값을 원하는 대로 수정
// img 파일은 static 폴더 안에 저장(800X400 사이즈)
<meta property="og:title" content="나만의 쇼핑몰" />
<meta property="og:description" content="맛있는 사과사세요~~🍎" />
<meta property="og:image" content="{{ url_for('static', filename='ogimage.png') }}" />
링크 : http://kimcno3.shop/