2023. 4. 8. 16:44ㆍ항해99
스파르타 코딩클럽 웹개발 종합반 수업내용을 정리한 것입니다.
1. 파이썬 다운로드 (Mac)
https://www.python.org/downloads/
다운로드 후 터미널에 python3 를 입력하면 확인 할 수 있다.
> 나가는 명령은 exit()
1) VSC 에 hello.py 파일 생성
2) 확장 > python 설치
3) 코드를 적고 실행해본다.
! 공홈에서 다운받은것이 문제인지 에러가 발생했다.
zsh: no such file or directory: usr/bin/python3
해결 : homebrew 로 설치하니 해결이 되었다.
brew install python3
2. Fetch 복습
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta
name="viewport"
content="width=device-width, initial-scale=1, shrink-to-fit=no"
/>
<link
href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css"
rel="stylesheet"
integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC"
crossorigin="anonymous"
/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script
src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js"
integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM"
crossorigin="anonymous"
></script>
<title>스파르타 피디아</title>
<link
href="https://fonts.googleapis.com/css2?family=Gowun+Dodum&display=swap"
rel="stylesheet"
/>
<style>
* {
font-family: "Gowun Dodum", sans-serif;
}
.mytitle {
width: 100%;
height: 250px;
background-image: linear-gradient(
0deg,
rgba(0, 0, 0, 0.5),
rgba(0, 0, 0, 0.5)
),
url("https://movie-phinf.pstatic.net/20210715_95/1626338192428gTnJl_JPEG/movie_image.jpg");
background-position: center;
background-size: cover;
color: white;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.mytitle > button {
width: 200px;
height: 50px;
background-color: transparent;
color: white;
border-radius: 50px;
border: 1px solid white;
margin-top: 10px;
}
.mytitle > button:hover {
border: 2px solid white;
}
.mycomment {
color: gray;
}
.mycards {
margin: 20px auto 0px auto;
width: 95%;
max-width: 1200px;
}
.mypost {
width: 95%;
max-width: 500px;
margin: 20px auto 0px auto;
padding: 20px;
box-shadow: 0px 0px 3px 0px gray;
}
.mybtns {
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
margin-top: 20px;
}
.mybtns > button {
margin-right: 10px;
}
</style>
<script>
$(document).ready(function () {
fetch("http://spartacodingclub.shop/sparta_api/weather/seoul")
.then((res) => res.json())
.then((data) => {
let seoulTemp = data["temp"];
$("#temp").text(seoulTemp);
});
fetch("http://spartacodingclub.shop/web/api/movie")
.then((res) => res.json())
.then((data) => {
let rows = data["movies"];
$("#cards").empty();
rows.forEach((a) => {
let title = a["title"];
let desc = a["desc"];
let comment = a["comment"];
let star = a["star"];
let image = a["image"];
let star_image = "⭐".repeat(star);
let temp_html = `<div class="col">
<div class="card h-100">
<img
src="${image}"
class="card-img-top"
alt="..."
/>
<div class="card-body">
<h5 class="card-title">${title}</h5>
<p class="card-text">${desc}</p>
<p>${star_image}</p>
<p class="mycomment">${comment}</p>
</div>
</div>
</div>`;
$("#cards").append(temp_html);
});
});
});
</script>
</head>
<body>
<div class="mytitle">
<h1>내 생애 최고의 영화들</h1>
<div>현재 서울의 날씨 : <span id="temp">20</span>도</div>
<button>영화 기록하기</button>
</div>
<div class="mypost">
<div class="form-floating mb-3">
<input
type="email"
class="form-control"
id="floatingInput"
placeholder="name@example.com"
/>
<label for="floatingInput">영화URL</label>
</div>
<div class="input-group mb-3">
<label class="input-group-text" for="inputGroupSelect01">별점</label>
<select class="form-select" id="inputGroupSelect01">
<option selected>-- 선택하기 --</option>
<option value="1">⭐</option>
<option value="2">⭐⭐</option>
<option value="3">⭐⭐⭐</option>
<option value="4">⭐⭐⭐⭐</option>
<option value="5">⭐⭐⭐⭐⭐</option>
</select>
</div>
<div class="form-floating">
<textarea
class="form-control"
placeholder="Leave a comment here"
id="floatingTextarea2"
style="height: 100px"
></textarea>
<label for="floatingTextarea2">코멘트</label>
</div>
<div class="mybtns">
<button type="button" class="btn btn-dark">기록하기</button>
<button type="button" class="btn btn-outline-dark">닫기</button>
</div>
</div>
<div class="mycards">
<div id="cards" class="row row-cols-1 row-cols-md-4 g-4">
<div class="col">
<div class="card h-100">
<img
src="https://movie-phinf.pstatic.net/20210728_221/1627440327667GyoYj_JPEG/movie_image.jpg"
class="card-img-top"
alt="..."
/>
<div class="card-body">
<h5 class="card-title">영화 제목이 들어갑니다</h5>
<p class="card-text">여기에 영화에 대한 설명이 들어갑니다.</p>
<p>⭐⭐⭐</p>
<p class="mycomment">나의 한줄 평을 씁니다</p>
</div>
</div>
</div>
<div class="col">
<div class="card h-100">
<img
src="https://movie-phinf.pstatic.net/20210728_221/1627440327667GyoYj_JPEG/movie_image.jpg"
class="card-img-top"
alt="..."
/>
<div class="card-body">
<h5 class="card-title">영화 제목이 들어갑니다</h5>
<p class="card-text">여기에 영화에 대한 설명이 들어갑니다.</p>
<p>⭐⭐⭐</p>
<p class="mycomment">나의 한줄 평을 씁니다</p>
</div>
</div>
</div>
<div class="col">
<div class="card h-100">
<img
src="https://movie-phinf.pstatic.net/20210728_221/1627440327667GyoYj_JPEG/movie_image.jpg"
class="card-img-top"
alt="..."
/>
<div class="card-body">
<h5 class="card-title">영화 제목이 들어갑니다</h5>
<p class="card-text">여기에 영화에 대한 설명이 들어갑니다.</p>
<p>⭐⭐⭐</p>
<p class="mycomment">나의 한줄 평을 씁니다</p>
</div>
</div>
</div>
<div class="col">
<div class="card h-100">
<img
src="https://movie-phinf.pstatic.net/20210728_221/1627440327667GyoYj_JPEG/movie_image.jpg"
class="card-img-top"
alt="..."
/>
<div class="card-body">
<h5 class="card-title">영화 제목이 들어갑니다</h5>
<p class="card-text">여기에 영화에 대한 설명이 들어갑니다.</p>
<p>⭐⭐⭐</p>
<p class="mycomment">나의 한줄 평을 씁니다</p>
</div>
</div>
</div>
</div>
</div>
</body>
</html>
3. 파이썬 기초
1) 변수
a = 2
b = 3
c = "대한"
d = "민국"
print(a+b) # 5
print(c+d) # 대한민국
2) 자료형
a = ['사과', '배', '감']
print(a[0]) # 사과
print(a[2]) # 감
3)dictionary
a = {'name' : '영수', 'age': 24}
print(a) # {'name': '영수', 'age': 24}
print(a['name']) # 영수
4) 함수
def hey():
print('헤이!') # tab 필수
def sum(a,b,c):
return a+b+c
result = sum(1,2,3)
hey() # 헤이!
print(result) # 6
5) 조건문
age = 25
if age > 20:
print('성인입니다')
else:
print('청소년입니다')
# 성인입니다
6) 반복문
ages = [5, 10, 13, 23, 25, 9]
for a in ages:
if a > 20:
print('성인입니다')
else:
print('청소년입니다')
# 청소년입니다
# 청소년입니다
# 청소년입니다
# 성인입니다
# 성인입니다
# 청소년입니다
4. 파이썬 패키지 설치하기 (Mac)
- 가상환경 : 라이브러리를 담아두는 폴더
- 아래를 실행하면 라이브러리를 담아둘 폴더가 생성된다.
python3 -m venv venv
- VSC 우측 밑에 버전을 클릭해서 venv 로 바꾼다.
pip install requests
- requests 는 단순한 HTTP 라이브러리이다.
- URL 에 쿼리 문자열을 수동으로 추가하거나 POST 데이터를 양식 인코딩할 필요가 없다.
아래 링크는 requests 패키지 문서이다.
https://requests.readthedocs.io/en/latest/
5. 패키지 사용
- JS 의 fetch 역할을 하는 것이 python 의 requests 이다.
import requests # requests 라이브러리 설치 필요
r = requests.get('http://spartacodingclub.shop/sparta_api/seoulair')
rjson = r.json()
rows = rjson['RealtimeCityAir']['row']
for a in rows:
gu_name = a['MSRSTE_NM']
gu_mise = a['IDEX_MVL']
print(gu_name, gu_mise)
6. 웹 스크래핑 기초
- 우선 beautifulsoup4 라이브러리가 필요하다.
pip install bs4
아래는 문서이다.
https://beautiful-soup-4.readthedocs.io/en/latest/
- HTML 및 XML 파일에서 데이터를 추출하기 위한 라이브러리이다.
1) 기본 세팅
import requests
from bs4 import BeautifulSoup
URL = "https://movie.daum.net/ranking/reservation"
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')
2) 크롤링을 할 때 필요한 두가지
- 크롤링 : 웹에 접속해서 데이터를 솎아내어 가지고 오는것
- 1. 접속 : requests
- 2. 솎아내기 : bs4
3) 크롤링
import requests
from bs4 import BeautifulSoup
URL = "https://movie.daum.net/ranking/reservation"
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')
a = soup.select_one('#mainContent > div > div.box_ranking > ol > li:nth-child(1) > div > div.thumb_item > div.poster_movie')
print(a)
print(a.text) # 텍스트를 가져옴
print(a['href']) # 속성을 가져옴
4) 웹 스크래핑 퀴즈
import requests
from bs4 import BeautifulSoup
URL = "https://movie.daum.net/ranking/reservation"
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')
# #mainContent > div > div.box_ranking > ol > li:nth-child(1)
# #mainContent > div > div.box_ranking > ol > li:nth-child(2)
lis = soup.select('#mainContent > div > div.box_ranking > ol > li')
# #mainContent > div > div.box_ranking > ol > li:nth-child(1) > div > div.thumb_cont > strong > a
# #mainContent > div > div.box_ranking > ol > li:nth-child(1) > div > div.thumb_item > div.poster_movie > span.rank_num
# #mainContent > div > div.box_ranking > ol > li:nth-child(1) > div > div.thumb_cont > span.txt_append > span:nth-child(1) > span
for li in lis:
title = li.select_one('div > div.thumb_cont > strong > a')
rank = li.select_one('div > div.thumb_item > div.poster_movie > span.rank_num')
star = li.select_one('div > div.thumb_cont > span.txt_append > span:nth-child(1) > span')
if title is not None:
print(rank.text , title.text, star.text)
7. DB
1) DB를 쓰는 이유 : 나중에 잘 찾기 위해서 , 잘 가지고 오기 위해서
2) SQL , NoSQL
- SQL: 정해진 칸에 데이터를 넣는 것 (엑셀과 유사)
- 사람이 실수할 일이 없다 ( 비즈니스가 잘 안바뀌는 곳에서 사용, 대기업 )
- 조금 더 빠르게 데이터를 가져 올 수 있다.
- NoSQL : 정해져있지 않다. 비즈니스가 자주 바뀌는 곳에서 사용, 스타트업
3) DB 실체
- 우리가 쓰는 프로그램 같은 것 ( 엑셀같이 )
- 요세는 컴퓨터에 데이터베이스를 설치하지 않고 클라우드를 사용한다.
8. mongoDB
1) 접속준비
- mongoDB 회원가입
- Build a Database 또는 Create 클릭
- 무료인 Shared 클릭
- Create Cluster 클릭
- 아이디 비밀번호 입력후 create user 클릭
- IP Addrass 0.0.0.0 입력후 Add Entry 클릭
- Finish and Close 클릭
2) 연결하기
- 파이썬과 mongoDB를 연결해야함
- mongoDB 를 조작하려면 두 개의 라이브러리가 필요하다
- pymongo
- dnspython
pip install dnspython
pip install pymongo
https://pymongo.readthedocs.io/en/stable/tutorial.html
pymongo 기본 코드
from pymongo import MongoClient
client = MongoClient('여기에 URL 입력') # mongoDB 주소
db = client.dbsparta
- 주소는 mongoDB 사이트에 Connect 클릭 > Connect your application 클릭
- DRIVER 를 python 으로 변경 > 버전 3.6 or later 로 변경 > 주소를 복사
- mongoDB는 딕셔너리를 넣어주면 된다.
from pymongo import MongoClient
import certifi
ca = certifi.where()
client = MongoClient('mongodb+srv://DB이름:비밀번호@cluster0.2xxwxhc.mongodb.net/?retryWrites=true&w=majority', tlsCAFile=ca)
db = client.dbsparta
doc = {
'name' : '영수',
'age' : 24
}
db.users.insert_one(doc)
- 실행 후 사이트에서 Browser Collections 클릭
3) 조작하기
현재데이터
4) 가져오기
from pymongo import MongoClient
import certifi
ca = certifi.where()
client = MongoClient('mongodb+srv://이름:비밀번호@cluster0.2xxwxhc.mongodb.net/?retryWrites=true&w=majority', tlsCAFile=ca)
db = client.dbsparta
all_users = list(db.users.find({},{'_id':False}))
for a in all_users:
print(a)
# 데이터를 모두 가져옴
from pymongo import MongoClient
import certifi
ca = certifi.where()
client = MongoClient('mongodb+srv://이름:비밀번호@cluster0.2xxwxhc.mongodb.net/?retryWrites=true&w=majority', tlsCAFile=ca)
db = client.dbsparta
user = db.users.find_one({})
print(user)
# 데이터를 하나만 가져옴
5) 수정하기
from pymongo import MongoClient
import certifi
ca = certifi.where()
client = MongoClient('mongodb+srv://이름:비밀번호@cluster0.2xxwxhc.mongodb.net/?retryWrites=true&w=majority', tlsCAFile=ca)
db = client.dbsparta
db.users.update_one({'name':'영수'},{'$set':{'age':19}})
6) 삭제하기
from pymongo import MongoClient
import certifi
ca = certifi.where()
client = MongoClient('mongodb+srv://이름:비밀번호@cluster0.2xxwxhc.mongodb.net/?retryWrites=true&w=majority', tlsCAFile=ca)
db = client.dbsparta
db.users.delete_one({'name':'영수'})
7) 요약
from pymongo import MongoClient
import certifi
ca = certifi.where()
client = MongoClient('mongodb+srv://이름:비밀번호@cluster0.2xxwxhc.mongodb.net/?retryWrites=true&w=majority', tlsCAFile=ca)
db = client.dbsparta
# 저장 - 예시
doc = {'name':'bobby','age':21}
db.users.insert_one(doc)
# 한 개 찾기 - 예시
user = db.users.find_one({'name':'bobby'})
# 여러개 찾기 - 예시 ( _id 값은 제외하고 출력)
all_users = list(db.users.find({},{'_id':False}))
# 바꾸기 - 예시
db.users.update_one({'name':'bobby'},{'$set':{'age':19}})
# 지우기 - 예시
db.users.delete_one({'name':'bobby'})
9. 스크래핑 결과 저장
before hello.py
import requests
from bs4 import BeautifulSoup
URL = "https://movie.daum.net/ranking/reservation"
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')
# #mainContent > div > div.box_ranking > ol > li:nth-child(1)
# #mainContent > div > div.box_ranking > ol > li:nth-child(2)
lis = soup.select('#mainContent > div > div.box_ranking > ol > li')
# #mainContent > div > div.box_ranking > ol > li:nth-child(1) > div > div.thumb_cont > strong > a
# #mainContent > div > div.box_ranking > ol > li:nth-child(1) > div > div.thumb_item > div.poster_movie > span.rank_num
# #mainContent > div > div.box_ranking > ol > li:nth-child(1) > div > div.thumb_cont > span.txt_append > span:nth-child(1) > span
for li in lis:
title = li.select_one('div > div.thumb_cont > strong > a')
rank = li.select_one('div > div.thumb_item > div.poster_movie > span.rank_num')
star = li.select_one('div > div.thumb_cont > span.txt_append > span:nth-child(1) > span')
if title is not None:
print(rank.text , title.text, star.text)
after hello.py
from pymongo import MongoClient
import certifi
ca = certifi.where()
client = MongoClient('mongodb+srv://이름:비밀번호@cluster0.2xxwxhc.mongodb.net/?retryWrites=true&w=majority', tlsCAFile=ca)
db = client.dbsparta
import requests
from bs4 import BeautifulSoup
URL = "https://movie.daum.net/ranking/reservation"
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')
# #mainContent > div > div.box_ranking > ol > li:nth-child(1)
# #mainContent > div > div.box_ranking > ol > li:nth-child(2)
lis = soup.select('#mainContent > div > div.box_ranking > ol > li')
# #mainContent > div > div.box_ranking > ol > li:nth-child(1) > div > div.thumb_cont > strong > a
# #mainContent > div > div.box_ranking > ol > li:nth-child(1) > div > div.thumb_item > div.poster_movie > span.rank_num
# #mainContent > div > div.box_ranking > ol > li:nth-child(1) > div > div.thumb_cont > span.txt_append > span:nth-child(1) > span
for li in lis:
a = li.select_one('div > div.thumb_cont > strong > a')
if a is not None:
title = a.text
rank = li.select_one('div > div.thumb_item > div.poster_movie > span.rank_num').text
star = li.select_one('div > div.thumb_cont > span.txt_append > span:nth-child(1) > span').text
doc = {
'title': title,
'rank' : rank,
'star' : star,
}
db.movies.insert_one(doc)
- 주의 코드를 여러번 실행하면 여러번 DB 에 들어간다.
Quiz
from pymongo import MongoClient
import certifi
ca = certifi.where()
client = MongoClient('mongodb+srv://이름:비밀번호@cluster0.2xxwxhc.mongodb.net/?retryWrites=true&w=majority', tlsCAFile=ca)
db = client.dbsparta
# 오토라는 남자 의 평점을 가져와보자
movie = db.movies.find_one({'title':'오토라는 남자'})
print(movie['star'])
# 오토라는 남자 와 같은 평점의 영화들을 가져와보자 , 나의 답
target_star = movie['star']
all_movie = list(db.movies.find({},{'_id':False}))
for a in all_movie:
if target_star == a['star']:
print(a['title'])
# 오토라는 남자 와 같은 평점의 영화들을 가져와보자 , 강사님 답
target_star = movie['star']
movies = list(db.movies.find({'star':target_star},{'_id':False}))
for a in movies:
print(a['title'])
# 오토라는 남자 의 영화 평점을 0으로 만들기
db.movies.update_one({'title':'오토라는 남자'},{'$set':{'star':0}})
10. 숙제 : 지니 뮤직의 1 ~ 50 위 곡을 스크래핑하기
- 순위 / 곡 제목 / 가수
- 앞에서 두 글ㅈ만 끊기 text[0:2]
- 곡 제목 깔끔하게 하기, 파이썬 내장함수 strip() 이용
- strip 함수는 인자가 없을시 공백을 없애준다.
import requests
from bs4 import BeautifulSoup
URL = "https://www.genie.co.kr/chart/top200?ditc=M&rtm=N&ymd=20230101"
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')
# #body-content > div.newest-list > div > table > tbody > tr:nth-child(1)
trs = soup.select('#body-content > div.newest-list > div > table > tbody > tr')
# #body-content > div.newest-list > div > table > tbody > tr:nth-child(1) > td.number
# #body-content > div.newest-list > div > table > tbody > tr:nth-child(1) > td.info > a.title.ellipsis
# #body-content > div.newest-list > div > table > tbody > tr:nth-child(1) > td.info > a.artist.ellipsis
for tr in trs:
rank = tr.select_one('td.number').text[0:2].strip()
title = tr.select_one('td.info > a.title.ellipsis').text.strip()
artist = tr.select_one('td.info > a.artist.ellipsis').text
print(rank, title, artist)
3주차 소감
관심있었던 파이썬을 배운다는것이 재밌었다. 문법이 보기 쉬웠고 처음해본 스크래핑도 흘미를 많이 느끼게 하였다.
이번주차에서 더 좋았던 것은 드디어 오류를 만났다. 두가지 오류를 만나 해결하며 성장한 느낌이 들었던 강의였다.
'항해99' 카테고리의 다른 글
엑셀보다 쉬운 SQL 1주차 (0) | 2023.06.01 |
---|---|
웹개발 종합반 5주차 (0) | 2023.04.09 |
웹개발 종합반 4주차 (0) | 2023.04.08 |
웹개발 종합반 2주차 (0) | 2023.04.08 |
웹개발 종합반 1주차 (0) | 2023.04.08 |