스파르타 왕초보 3주차

파이썬이라는 언어를 통해 컴퓨터한테 서버 역할을 해줘라고 명령을 내린다.

[복습]

나홀로메모장 API

로딩 후 바로실행 코드

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

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

Ajax 기본 골격

$.ajax({
    type: "GET",
    url: "http://spartacodingclub.shop/post",
    data: {},
    success: function (response) {
      console.log(response)
    }
})

데이터를 하나씩 출력하기

let rows = response['articles']
            for (let i = 0; i < rows.length; i++) {
              let comment = rows[i]['comment']
              let desc = rows[i]['desc']
              let image = rows[i]['image']
              let title = rows[i]['title']
              let url = rows[i]['url']

HTML을 만들어 붙이기

let temp_html = `<div class="card">
 		     <img class="card-img-top"
    			  src="${image}"
                  	  alt="Card image cap">
  		     <div class="card-body">
  			  <a 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)

먼저 있던 카드 지워주기

$(document).ready(function () {
    $('#cards-box').empty();
    listing();
});

[파이썬]

파이썬을 설치했다는 것은 파이썬 번역팩을 설치했다고 생각하면 된다.

✔ 변수

a = 3
b = 2
print(a+b)  //5출력
first_name = 'HH'
num = 2
print(first_name+num)  //에러

print(first_name+num) //에러 위치
TypeError: can only concatenate str (not "int") to str //에러에 대한 설명
=> 파이썬에서는 문자와 숫자를 더하면 에러가 난다.

  • 에러를 고치기 위해 2를 문자열로 만들어준다.
    => num = '2' 또는 num = str(2)

✔ 리스트

a_list = ['사과','배','감']

print(a_list[0]) //사과 출력
a_list = ['사과','배','감']
a_list.append('수박')

print(a_list) //['사과','배','감','수박'] 출력

✔ 딕셔너리

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

print(a_dict['age'])  //27 출력
a_dict = {'name':'bob','age':27}
a_dict['height'] = 178

print(a_dict)  //{'name':'bob','age':27,'height':178} 출력

✔ 함수

프로그래밍에서 함수는 변수를 받든 안 받는 정해진 동작을 수행

  • 자바스크립트에서는 중괄호를 사용했는데 파이썬에는 안 사용한다.
def sum(num1,num2):
    return num1+num2

result = sum(2,3)

print(result)  //5 출력

✔ 조건문

age= 25

if age > 20:
    print('성인입니다')
else:
    print('청소년입니다')
    
//성인입니다 출력
def is_adult(age):  # is_adult라는 age라는 변수를 받는 함수를 만든다.
    if age > 20:
        print('성인입니다')
    else:
        print('청소년입니다')

is_adult(30)
is_adult(15)

//성인입니다, 청소년입니다 출력

✔ 반복문

리스트 예제

fruits = ['사과','배','배','감','수박','귤','딸기','사과','배','수박']

for fruit in fruits:  #fruits를 하나씩 돌면서 그걸 빼가지고 변수(fruit)에 넣고
    print(fruit)      #변수를 내용물에 넣어 출력
    //사과,,,,수박,,딸기,사과,,수박 출력
fruits = ['사과','배','배','감','수박','귤','딸기','사과','배','수박']

count = 0
for fruit in fruits:
    if fruit == '사과':
        count += 1

print(count) //2 출력

딕셔너리 예제

people = [{'name': 'bob', 'age': 20}, 
          {'name': 'carry', 'age': 38},
          {'name': 'john', 'age': 7},
          {'name': 'smith', 'age': 17},
          {'name': 'ben', 'age': 27}]
          
print(person)
people = [{'name': 'bob', 'age': 20}, 
          {'name': 'carry', 'age': 38},
          {'name': 'john', 'age': 7},
          {'name': 'smith', 'age': 17},
          {'name': 'ben', 'age': 27}]

for person in people:
    print(person['name'],person['age'])
    
 //bob 20, carry 28, john 7, smith 17, ben 27 출력
people = [{'name': 'bob', 'age': 20}, 
          {'name': 'carry', 'age': 38},
          {'name': 'john', 'age': 7},
          {'name': 'smith', 'age': 17},
          {'name': 'ben', 'age': 27}]

for person in people:
    if person['age'] < 20:
        print(person)
        
  //{'name': 'john', 'age': 7}
    {'name': 'smith', 'age': 17} 출력

▶ 파이썬 패키지

파이썬은 라이브러리가 굉장히 방대한 걸로 유명하다.
패키지는 사람들이 만들어놓은 라이브러리
가상환경(virtual environment) : 라이브러리를 담아두는 폴더

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

r = requests.get('http://openapi.seoul.go.kr:8088/6d4d776b466c656533356a4b4b5872/json/RealtimeCityAir/1/99')
rjson = r.json()

print(rjson['RealtimeCityAir']['row'][0]['MSRSTE_NM'])

//중구 출력

반복문 사용

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

r = requests.get('http://openapi.seoul.go.kr:8088/6d4d776b466c656533356a4b4b5872/json/RealtimeCityAir/1/99')
rjson = r.json()

gus = rjson['RealtimeCityAir']['row']

for gu in gus:
    gu_name = gu['MSRSTE_NM']
    gu_mise = gu['IDEX_MVL']
    print(gu_name,gu_mise)
    
//중구 52.0, ~~~, 강동구 51.0 출력

if문 사용

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

r = requests.get('http://openapi.seoul.go.kr:8088/6d4d776b466c656533356a4b4b5872/json/RealtimeCityAir/1/99')
rjson = r.json()

gus = rjson['RealtimeCityAir']['row']

for gu in gus:
    gu_name = gu['MSRSTE_NM']
    gu_mise = gu['IDEX_MVL']
    if (gu_mise > 100) :
        print(gu_name, gu_mise)
        
//미세먼지가 100을 넘는 곳만 출력

[웹스크래핑]

네이버영화페이지

크롤링 기본 세팅

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.nhn?sel=pnt&date=20200303',headers=headers)
# headers는 코드단에서 요청했을 때 기본적인 요청을 막아두는 사이들이 많다.
# 그래서 브라우저에서 엔터친 것 마냥 효과를 내주는 것이다.

soup = BeautifulSoup(data.text, 'html.parser')
# 데이터로 요청 후 BeautifulSoup 형태로 솎아내는 것이다.

# 코딩 시작

크롤링 시 requests로 요청하고 BeautifulSoup(bs4)로 원하는 정보를 속아낸다.

  • 태그 안 텍스트를 찍을 때 : 태그.text
  • 태그 안 속성을 찍을 때 : 태그['속성']

✔ select_one (하나)

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.nhn?sel=pnt&date=20200303',headers=headers)

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

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

print(title.text)
//그린 북, 가버나움, ~~~ 등 출력

print(title['href'])
//  /movie/bi/mi/basic.naver?code=171539 출력

✔ select (여러개)

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.nhn?sel=pnt&date=20200303',headers=headers)

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

# #old_content > table > tbody > tr:nth-child(2)
# #old_content > table > tbody > tr:nth-child(3)
# =>  겹치는 부분인 #old_content > table > tbody > tr만 가져오기

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

for tr in trs:
    print(tr)
    
//해당 코드들 출력			
    <tr>
       <td class="ac"><img src="https://ssl.pstatic.net/imgmovie/2007/img/common/bullet_r_r01.gif" alt="01" width="14" height="13"></td>
       <td class="title">
        <div class="tit5">
        <a href="/movie/bi/mi/basic.naver?code=171539" title="그린 북">그린 북</a>
        </div>
       </td>
    <!-- 평점순일 때 평점 추가하기  -->
       <td><div class="point_type_2"><div class="mask" style="width:96.00000381469727%"><img src="https://ssl.pstatic.net/imgmovie/2007/img/common/point_type_2_bg_on.gif" width="79" height="14" alt=""></div></div></td>
       <td class="point">9.60</td>
       <td class="ac"><a href="/movie/point/af/list.naver?st=mcode&amp;sword=171539" class="txt_link">평점주기</a></td>
    <!----------------------------------------->  
       <td class="ac"><img src="https://ssl.pstatic.net/imgmovie/2007/img/common/icon_na_1.gif" alt="na" width="7" height="10" class="arrow"></td>
       <td class="range ac">0</td>
    </tr>
  • tr안에서 title 찾기
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.nhn?sel=pnt&date=20200303',headers=headers)

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

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

# #old_content > table > tbody > tr:nth-child(2) > td.title > div > a
# => 중복 제외 나머지 td.title > div > a로 title 가져오기
for tr in trs:
    a_tag = tr.select_one('td.title > div > a')
    print(a_tag)

//None
<a href="/movie/bi/mi/basic.naver?code=171539" title="그린 북">그린 북</a> 등 출력

=> 출력된 none은 아래 이미지에서 선을 나타내고 있다.
여기서 위 코드에 print(a_tag.text)하게 되면 에러가 뜨게 된다.
none에 .text하지말라는 의미!

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.nhn?sel=pnt&date=20200303',headers=headers)

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

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

for tr in trs:
    a_tag = tr.select_one('td.title > div > a')
    if a_tag is not None:
        print(a_tag)

//none을 제외하고 출력됨
<a href="/movie/bi/mi/basic.naver?code=171539" title="그린 북">그린 북</a>
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.nhn?sel=pnt&date=20200303',headers=headers)

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

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

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

//그린 북, 가버나움, ~~~ 등 출력

▶ Q.크롤링 연습

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.nhn?sel=pnt&date=20200303',headers=headers)

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


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

for tr in trs:
    a_tag = tr.select_one('td.title > div > a')
    if a_tag is not None:
    # #old_content > table > tbody > tr:nth-child(2) > td:nth-child(1) > img
        rank = tr.select_one('td:nth-child(1) > img')['alt']
        title = a_tag.text
    # #old_content > table > tbody > tr:nth-child(2) > td.point    
        star = tr.select_one('td.point').text
        print(rank,title,star)

//01 그린 북 9.60, 02 가버나움 9.59 등 출력

[DB]

MongoDB는 데이터베이스로 컴퓨터에는 돌아가고 있지만 눈에는 보이지 않는 것이다.
Robo3T는 MongoDB의 데이터를 볼 수 있도록 하는 것이다.

데이터베이스를 쓰는 이유는 데이터를 잘 갖다 쓰려고 사용하는 것이다.

RDBMS(SQL)
행/열의 생김새가 정해진 엑셀에 데이터를 저장하는 것과 가깝다.
데이터 만 개가 적재된 상태에서, 갑자기 중간에 열을 하나 더하는 것은 여럽다.
정형화되어있는 만큼, 데이터의 일관성이나 분석에 용이하다.
ex) MS-SQL, My-SQL 등

No-SQL
딕셔너리 형태의 DB
자유로운 형태의 데이터 적재에 유리하지만 일관성이 부족할 수 있다.
ex) MongoDB

▶ pymongo

pymongo는 MongoDB를 조작하기 위한 라이브러리이다.

pymongo 기본 코드

from pymongo import MongoClient
client = MongoClient('localhost', 27017)  #내 컴퓨터에 돌아가고 있는 MongoDB에 접속
db = client.dbsparta  #dbsparta라는 DB 이름으로 접속

# 코딩 시작

✔ insert (저장)

doc = {'name':'bobby','age':21}  #딕셔너리 하나를 만듦
db.users.insert_one(doc)  #딕셔너리를 db 안에 users라는 collection에 insert해라

Robo3T에서 확인하면 추가가 된 것을 알 수 있다.
계속 insert할 경우 아래로 계속 추가가 된다.

✔ find (여러개 찾기)

same_ages = list(db.users.find({'age':21},{'_id':False}))
print(same_ages)

//[{'name': 'bobby', 'age': 21}, {'name': 'jane', 'age': 21}] 출력


# 리스트 안에 딕셔너리 값이 있는대로 출력이 되었으니 따로따로 출력해보자!
same_ages = list(db.users. find({'age':21},{'_id':False}))

for person in same_ages:
    print(person)

//{'name': 'bobby', 'age': 21}
{'name': 'jane', 'age': 21} 출력

조건없이 모든 document를 find 해라

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

for person in same_ages:
    print(person)

//{'name': 'bobby', 'age': 21}
{'name': 'John', 'age': 27}
{'name': 'smith', 'age': 30}
{'name': 'jane', 'age': 21} 출력

✔ find_one (한 개 찾기)

user = db.users.find_one({'name':'bobby'})  #name이 bobby인 애의 정보만 가지고 와라
print(user)

//{'_id': ObjectId('610cf38dadc8ef7e5f910951'), 'name': 'bobby', 'age': 21} 출력


#id값은 빼고 가져올 때
user = db.users.find_one({'name':'bobby'},{'_id':False})
print(user)

//{'name': 'bobby', 'age': 21} 출력


#그 중 나이만 출력하고 싶다면!
user = db.users.find_one({'name':'bobby'},{'_id':False})
print(user['age'])

//21 출력

✔ update_one (바꾸기)

db.users.update_one({'name':'bobby'},{'$set':{'age':19}})  #name이 bobby인 애를 가져와서 age를 19로 바꿔라


#update_many도 있음. 이걸 쓰면 name이 bobby인 애를 모두 찾아서 age를 19로 바꾸게 됨
하지만, 한번에 다 바꾸는 것이기 때문에 위험해서 잘 사용안함

✔ delete_one (지우기)

db.users.delete_one({'name':'bobby'})  #name이 bobby인 애를 찾아서 delete해라


#delete_many도 있지만 update_many와 같은 이유로 사용안함

!pymongo 코드 한눈에 보기!

# 저장 - 예시
doc = {'name':'bobby','age':21}
db.users.insert_one(doc)

# 한 개 찾기 - 예시
user = db.users.find_one({'name':'bobby'})

# 여러개 찾기 - 예시 ( _id 값은 제외하고 출력)
same_ages = list(db.users.find({'age':21},{'_id':False}))

# 바꾸기 - 예시
db.users.update_one({'name':'bobby'},{'$set':{'age':19}})

# 지우기 - 예시
db.users.delete_one({'name':'bobby'})

[크롤링 결과를 DB에 저장]

import requests
from bs4 import BeautifulSoup

#DB를 사용하기 위해 pymongo 임포트 코드 가져오기
from pymongo import MongoClient  
client = MongoClient('localhost', 27017)
db = client.dbsparta

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.nhn?sel=pnt&date=20200303',headers=headers)

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


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

for tr in trs:
    a_tag = tr.select_one('td.title > div > a')
    if a_tag is not None:
        rank = tr.select_one('td:nth-child(1) > img')['alt']
        title = a_tag.text
        star = tr.select_one('td.point').text
     # insert하기
        doc = {
            'rank':rank,
            'title':title,
            'star':star
        }
        db.movies.insert_one(doc)

▶ Quiz_웹스크래핑 결과 이용

1) 영화제목 '매트릭스'의 평점 가져오기

from pymongo import MongoClient
client = MongoClient('localhost', 27017)
db = client.dbsparta

movie = db.movies.find_one({'title':'매트릭스'})
print(movie['star'])

//9.39 출력

2) '매트릭스'의 평점과 같은 평점 영화 제목들 가져오기

from pymongo import MongoClient
client = MongoClient('localhost', 27017)
db = client.dbsparta

movie = db.movies.find_one({'title':'매트릭스'})
movie_star = movie['star']

movie_A = list(db.movies.find({'star':movie_star}))

for movie_name in movie_A:
    print(movie_name['title'])
    
//인생은 아름다워
  매트릭스
  라이언 일병 구하기
  사운드 오브 뮤직
  헬프
  포레스트 검프
  안녕 베일리
  글래디에이터 출력

3) '매트릭스' 영화의 평점을 0으로 만들기

from pymongo import MongoClient
client = MongoClient('localhost', 27017)
db = client.dbsparta

db.movies.update_one({'title':'매트릭스'},{'$set':{'star':0}})

[Q.숙제]

지니 차트_2020년4월3일
지니뮤직 사이트를 이용하여 순위/곡제목/가수를 스크래핑하기

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=D&ymd=20200403&hh=23&rtm=N&pg=1',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()
    singer = tr.select_one('td.info > a.artist.ellipsis').text.strip()

    print(rank,title,singer)

문자열 여백 없애기 .strip()
문자열 자르기 함수 이용하기 text[0:2]

좋은 웹페이지 즐겨찾기