본문 바로가기

개발일지

[스파르타코딩클럽] 웹개발 종합반 3주차

로딩 후 바로 실행

$(document).ready(function () {
    listing();
});

function listing() {
    console.log('화면 로딩 후 잘 실행되었습니다');
}

로딩 후 listing()함수가 바로 실행됨.

 

let star_image = '⭐'.repeat(star)

.repeat(star)는 star만큼 반복하라는 의미의 내장함수.

 

 

스파르타피디아 API 복습

function listing() {
    $('#cards-box').empty()
    $.ajax({
        type: "GET",
        url: "http://spartacodingclub.shop/web/api/movie",
        data: {},
        success: function (response) {
            let rows = response['movies']
            for (let i = 0; i < rows.length; i++) {
                let title = rows[i]['title']
                let desc = rows[i]['desc']
                let image = rows[i]['image']
                let star = rows[i]['star']
                let comment = rows[i]['comment']

                let star_image = '⭐'.repeat(star)

                let temp_html = `<div class="col">
                                    <div class="card">
                                        <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-box').append(temp_html)
            }
        }
    })
}

제목, 내용, 코멘트, 별, 이미지를 각각 대입하고

temp_html을 이용하여 cards-box라는 아이디에 append한다.

 

 


가상환경 : 라이브러리를 모아두는 곳

virtual environment -> venv

라이브러리, 패키지가 담기는 공간

 

 

import requests # requests 라이브러리 설치 필요

 

requests라는 라이브러리를 불러옴.

라이브러리마다 정리된 방식이 다르기 때문에 찾아봐야함.

 

r = requests.get('http://spartacodingclub.shop/sparta_api/seoulair')
rjson = r.json()

requests 라이브러리의 방식대로 씀.

 

 


네이버 영화 제목 크롤링

1. html을 요청해서 가져오기 -> requests를 이용

2. 제목을 쉽게 찾기 -> beautifulsoup

 

import requests
from bs4 import BeautifulSoup

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/rmovie.naver?sel=pnt&date=20210829',headers=headers)

soup = BeautifulSoup(data.text, 'html.parser')

# 코딩 시작

크롤링 기본 세팅.

필요한 라이브러리를 import

 

 

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/rmovie.naver?sel=pnt&date=20210829',headers=headers)

hearders : 코드에서 콜을 날리는 게 아닌, 브라우저(사람)에서 콜을 날린 것처럼 해주기 위해 쓰임.

data 끝에 쓰임

 

Beautifulsoup 사용하기

영화 제목 검사 누른 후 selector 복사.

 

title = soup.select_one('#old_content > table > tbody > tr:nth-child(2) > td.title > div > a')
print(title)

soup.select_one -> 하나만 선택할 것이므로 select_one

영화 제목 태그가 출력됨.

 

print(title.text)

.text를 하면 영화 제목만 출력됨.

 

print(title['href'])

href만 출력됨.

 

여러 개를 선택할 때 -> select

 

#old_content > table > tbody > tr:nth-child(3) > td.title > div > a
#old_content > table > tbody > tr:nth-child(4) > td.title > div > a

movies = soup.select('#old_content > table > tbody > tr')

.select()하고 공통되는 부분까지 입력함.

 

print(movies)

리스트 형태로 출력.

<tr></tr> 하나의 묶음이 잡힌 것임.

 

for movie in movies :
    a = movie.select_one('td.title > div > a')
    print(a)

 

a태그를 잡고 하나하나를 다시 select함.

이 때, 이미 가져온 부분의 뒷 부분인 td.title > div > a 입력

 

None이 출력되는 것은 가로선을 의미하므로

for movie in movies :
    a = movie.select_one('td.title > div > a')
    if a is not None :
        print(a.text)

a가 None이 아닐 때, 영화의 제목만을 출력

 

 

영화 순위, 제목, 별점 크롤링

for movie in movies :
    a = movie.select_one('td.title > div > a')
    if a is not None :
        title = a.text
        rank = movie.select_one('td:nth-child(1) > img')['alt']
        star = movie.select_one('td.point').text
        print(rank, title, star)

selector 복사 -> 공통되는 부분 제외하고 select_one으로 가져오기.

['alt'] -> 랭킹 순위만 가져옴

.text -> 별점만 가져옴

 


DB 개괄

DB를 왜 쓰는 걸까?

데이터를 index로 잘 정렬하기 위해

 

 

DB의 종류

SQL -> 정리된 표 안에 채움

정형화된 데이터만 받을 수 있으므로 체계적이지만 스타트업처럼 데이터의 변동이 큰 경우 비효율적임.

 

NoSQL(Not only SQL) -> 정리된 칸이 없고 들어오는 대로 채움

비정형화된 데이터이므로 그때마다 유연하게 대처할 수 있음.

 

DB : 데이터를 잘 쌓아서 잘 가져올 수 있도록 만들어진 프로그램

 

몽고DB Cluster0에 데이터 넣기!

몽고DB - Cluster0 -> dbsparta -> user 에 데이터 삽입

from pymongo import MongoClient
client = MongoClient('mongodb+srv://test:sparta@cluster0.z1d16er.mongodb.net/?retryWrites=true&w=majority')
db = client.dbsparta

doc = {
    'name' : 'bob',
    'age' : 27
}

db.users.insert_one(doc)

user라는 콜렉션에 데이터가 삽입된다.

 

 


db.users.insert_one({'name' : 'bobby', 'age' : 27})
db.users.insert_one({'name' : 'john', 'age' : 20})
db.users.insert_one({'name' : 'ann', 'age' : 20})

DB에 데이터 넣기 (통상적으로는 doc라는 변수를 만들어서 그 doc를 삽입함)

 

all_users = list(db.users.find({},{'_id':False}))

for user in all_users :
    print(user)

<출력>

{'name': 'bob', 'age': 27}
{'name': 'bobby', 'age': 27}
{'name': 'john', 'age': 20}
{'name': 'ann', 'age': 20}

 

.find()로 조건과 함께 데이터 검색해서 뽑아오기.

{'_id':False}라는 조건은 _id를 제외하고 뽑아오겠다는 의미

 

 

user = db.users.find_one({'name' : 'bobby'})
print(user['age'])

.find_one을 통해 데이터를 하나만 가져옴.

bobby의 나이만 가져오는 코드

 

 

db.users.update_one({'name':'bobby'},{'$set':{'age':19}})

update_one을 통해 데이터를 수정함.

 -> bobby의 나이를 19로 수정

{1}, {2}에서 1이라는 조건에 해당되는 데이터를 2로 수정함.

 

 

db.users.delete_one({'name' : 'bobby'})

name이 bobby인 데이터를 삭제함.

 

 

 

요약!

# 저장 - 예시
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'})

 

 

DB에 영화 크롤링하기

from pymongo import MongoClient
client = MongoClient('mongodb+srv://test:sparta@cluster0.z1d16er.mongodb.net/?retryWrites=true&w=majority')
db = client.dbsparta
for movie in movies :
    a = movie.select_one('td.title > div > a')
    if a is not None :
        title = a.text
        rank = movie.select_one('td:nth-child(1) > img')['alt']
        star = movie.select_one('td.point').text

        doc = {
            'title' : title,
            'rank' : rank,
            'star' : star
        }
        db.movies.insert_one(doc)

 

 

가버나움의 평점과 같은 평점의 영화 제목들 가져오기

from pymongo import MongoClient
client = MongoClient('mongodb+srv://test:sparta@cluster0.z1d16er.mongodb.net/?retryWrites=true&w=majority')
db = client.dbsparta

movie = db.movies.find_one({'title' : '가버나움'})
star = movie['star']

all_movies = list(db.movies.find({'star' : star},{'_id':False}))


for m in all_movies :
    print(m['title'])

 

 

가버나움의 평점을 0으로 만들기

주의 문자열 '0'으로 수정해야함.

 

db.movies.update_one({'title':'가버나움'},{'$set':{'star':'0'}})

 


지니뮤직 크롤링하기

#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(2) > td.number

 

1등, 2등 랭킹을 검사하여 selector 복사를 하면 공통되는 부분이 tr까지임을 알 수 있음.

랭킹은 순위 상승까지 같이 나옴.

 

import requests
from bs4 import BeautifulSoup

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://www.genie.co.kr/chart/top200?ditc=M&rtm=N&ymd=20210701',headers=headers)

soup = BeautifulSoup(data.text, 'html.parser')

trs = soup.select('#body-content > div.newest-list > div > table > tbody > tr')

for tr in trs :
    rank = tr.select_one('td.number')
    print(rank.text[0:2].strip())

 

rank.text[0:2].strip에서 [0:2]는 앞에서 두 글자만 끊는다는 의미.

.strip()은 양쪽 여백을 제거해주는 함수

 

 

import requests
from bs4 import BeautifulSoup

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://www.genie.co.kr/chart/top200?ditc=M&rtm=N&ymd=20210701',headers=headers)

soup = BeautifulSoup(data.text, 'html.parser')

trs = soup.select('#body-content > div.newest-list > div > table > tbody > tr')

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)

숙제 답안 코드