[웹개발] 파이썬 & mongoDB

2022. 12. 28. 11:44자격증(다다익선)/웹개발(HTML,Javascript)

728x90

https://chanytv.tistory.com/140

 

[웹개발] 개발 전 프로그램 설치 및 HTML,CSS 기초

[웹개발] 개발 전 프로그램 설치 필수로 설치해야할 프로그램이 몇 가지 있다. 과목 진행 중에 사용하는 프로그램이다 보니 나 또한 이 프로그램을 쓰지만 무료로 제공되는 프로그램도 많다고

chanytv.tistory.com

https://chanytv.tistory.com/141

 

[웹개발] 부트스트랩 & 폰트 / Javascript 기초

https://chanytv.tistory.com/140 [웹개발] 개발 전 프로그램 설치 및 HTML,CSS 기초 [웹개발] 개발 전 프로그램 설치 필수로 설치해야할 프로그램이 몇 가지 있다. 과목 진행 중에 사용하는 프로그램이다 보

chanytv.tistory.com

https://chanytv.tistory.com/144

 

[웹개발] jQuery & Ajax

https://chanytv.tistory.com/140 [웹개발] 개발 전 프로그램 설치 및 HTML,CSS 기초 [웹개발] 개발 전 프로그램 설치 필수로 설치해야할 프로그램이 몇 가지 있다. 과목 진행 중에 사용하는 프로그램이다 보

chanytv.tistory.com

[웹개발] 파이썬 & mongoDB


파이썬

 

3주차는 파이썬이다. 다행히 다른 강의에서 파이썬는 이미 공부 중이라 3주차는 쉽게 넘어갈 듯하다.

단지 다른 강의에서 파이썬은 colab에서 쓰고 있고 여기선 파이참 프로그램에서 구동을 해야 한다는 약간의 차이가 있다.

 

역시나 시작은 환경 구성이다. 파이썬 홈페이지에서 PC환경에 맞는 파이썬 버전을 받아 설치하면 된다.

이후 파이참 프로그램에서 몇 가지 설정을 해주면 된다.

 

복습을 한다는 생각으로 기초부터 한 번 다시 정리를 해보자.

 

# 변수 & 기본연산

a = 3      # 3을 a에 넣는다
b = a      # a를 b에 넣는다
a = a + 1  # a+1을 다시 a에 넣는다

num1 = a*b # a*b의 값을 num1이라는 변수에 넣는다
num2 = 99 # 99의 값을 num2이라는 변수에 넣는다

# 변수의 이름은 마음대로 지을 수 있음!
# 진짜 "마음대로" 짓는 게 좋을까? var1, var2 이렇게?

# 숫자, 문자형

name = 'bob' # 변수에는 문자열이 들어갈 수도 있고,
num = 12 # 숫자가 들어갈 수도 있고,

is_number = True # True 또는 False -> "Boolean"형이 들어갈 수도 있습니다.

#########
# 그리고 List, Dictionary 도 들어갈 수도 있죠. 그게 뭔지는 아래에서!

# 리스트 형 (Javascript의 배열형과 동일)

a_list = []
a_list.append(1)     # 리스트에 값을 넣는다
a_list.append([2,3]) # 리스트에 [2,3]이라는 리스트를 다시 넣는다

# a_list의 값은? [1,[2,3]]
# a_list[0]의 값은? 1
# a_list[1]의 값은? [2,3]
# a_list[1][0]의 값은? 2

# Dictionary 형 (Javascript의 dictionary형과 동일)

a_dict = {}
a_dict = {'name':'bob','age':21}
a_dict['height'] = 178

# a_dict의 값은? {'name':'bob','age':21, 'height':178}
# a_dict['name']의 값은? 'bob'
# a_dict['age']의 값은? 21
# a_dict['height']의 값은? 178

# Dictionary 형과 List형의 조합

people = [{'name':'bob','age':20},{'name':'carry','age':38}]

# people[0]['name']의 값은? 'bob'
# people[1]['name']의 값은? 'carry'

person = {'name':'john','age':7}
people.append(person)

# people의 값은? [{'name':'bob','age':20},{'name':'carry','age':38},{'name':'john','age':7}]
# people[2]['name']의 값은? 'john'

다른 강의에서 배워서 그런지 확실히 쉽게 이해가 된다. 역시 반복 학습만큼 학습효율을 높이는 건 없는 듯하다.ㅋ

아래는 많이 사용하는 기초 함수들이다.

# 함수의 정의 - 이름은 마음대로 정할 수 있음!

# 수학문제에서
f(x) = 2*x+3
y = f(2)
y의 값은? 7

# 참고: 자바스크립트에서는
function f(x) {
	return 2*x+3
}

# 파이썬에서
def f(x):
	return 2*x+3

y = f(2)
y의 값은? 7

# 함수의 응용

def sum_all(a,b,c):
	return a+b+c

def mul(a,b):
	return a*b

result = sum_all(1,2,3) + mul(10,10)

# result라는 변수의 값은?
# (1+2+3) + (10*10) = 6 + 100 = 106

# 조건문 - if / else 로 구성!

def oddeven(num):  # oddeven이라는 이름의 함수를 정의한다. num을 변수로 받는다.
	if num % 2 == 0: # num을 2로 나눈 나머지가 0이면
		 return True   # True (참)을 반환한다.
	else:            # 아니면,
		 return False  # False (거짓)을 반환한다.

result = oddeven(20)
# result의 값은 무엇일까요?
# 풀이를 하잠녀 20을 2로 나눈 나머지가 0이면 True 아니면 False를 반환한다. 즉 답은 True.

def is_adult(age):
	if age > 20:
		print('성인입니다')    # 조건이 참이면 성인입니다를 출력
	else:
		print('청소년이에요')  # 조건이 거짓이면 청소년이에요를 출력

is_adult(30)
# 무엇이 출력될까요?

30이 20보다 크면 '성인입니다' 아니면 '청소년입니다' 반환. 즉 답은 '성인입니다'.

# 반복문

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

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

print(count)

# 사과의 갯수를 세어 보여줍니다.

def count_fruits(target):
	count = 0
	for fruit in fruits:
		if fruit == target:
			count += 1
	return count

subak_count = count_fruits('수박')
print(subak_count) #수박의 갯수

gam_count = count_fruits('감')
print(gam_count) #감의 갯수

# 반복문과 조건문 응용

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'])


# 이번엔, 반복문과 조건문을 응용한 함수를 만들어봅시다.
# 이름을 받으면, age를 리턴해주는 함수
def get_age(myname):
    for person in people:
        if person['name'] == myname:
            return person['age']
    return '해당하는 이름이 없습니다'


print(get_age('bob')) #20
print(get_age('kay')) #해당하는 이름이 없습니다

기초를 다졌으니 이제 파이썬 패키지들을 설치하여 코딩에 활용해 주면 된다.

정말 많이 사용하는 패키지로는 'Requests'가 있다. 'colab'과는 다르게 '파이참'은 설정에서 패키지 설치를 해줘야 한다.

사용하는 프로그램마다 설치에는 조금씩 차이가 있는 듯하나 불러오는 것 동일하다.

 

그 외에도 많이 사용하는 패키지로는 'beautifulsoup4'가 있다. 줄여서 bs4는 크롤링을 하는데 필수적인 패키지니 의무적으로 설치를 해야 한다. 불러오는 방법은 아래와 같다.

import requests
from bs4 import BeautifulSoup

 간단한 예제로 'requests'를 알아보면

import requests
r = requests.get('http://spartacodingclub.shop/sparta_api/seoulair')
# 해당 주소를 get 한다.
rjson = r.json()
# get한 주소를 json에 담는다.

여기까지만 실행하면 해당주소에 있는 서울시 미세먼지 값을 불러올 수 있게 된다.

데이터를 불러오는데만 성공했다면 나머진 정렬 및 정리다.

# 모든 구의 IDEX_MVL 값

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

for gu in gus:
	print(gu['MSRSTE_NM'], gu['IDEX_MVL'])
    
# IDEX_MVL 값이 60 미만인 구만 찍어주자!

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

for gu in gus:
	if gu['IDEX_MVL'] < 60:
		print (gu['MSRSTE_NM'], gu['IDEX_MVL'])

이제 해볼 건 진정한 크롤링이다. 역시나 세팅이 먼저다.

import requests
from bs4 import BeautifulSoup

# 타겟 URL을 읽어서 HTML를 받아오고,
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)

# HTML을 BeautifulSoup이라는 라이브러리를 활용해 검색하기 용이한 상태로 만듦
# soup이라는 변수에 "파싱 용이해진 html"이 담긴 상태가 됨
# 이제 코딩을 통해 필요한 부분을 추출하면 된다.
soup = BeautifulSoup(data.text, 'html.parser')

#############################
# (입맛에 맞게 코딩)
#############################

위 세팅값은 크롤링을 하는 기본 설정값이다. 다른 사이트에서도 사용이 가능하니 외울 필요 없다. 이제 값을 정리해야 하는데 단순한 페이지라도 막상 불러오면 겁나게 뭣이 복잡하다. 그래서 어느 정도 필요한 부분을 정리할 필요가 있는데 이때 사용하는 게 'bs4'의 'select'라는 기능이다.

 

사용 방법은 아래와 같다.

import requests
from bs4 import BeautifulSoup

# URL을 읽어서 HTML를 받아오고,
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)

# HTML을 BeautifulSoup이라는 라이브러리를 활용해 검색하기 용이한 상태로 만듦
soup = BeautifulSoup(data.text, 'html.parser')

# select를 이용해서, tr들을 불러오기
movies = soup.select('#old_content > table > tbody > tr')

# movies (tr들) 의 반복문을 돌리기
for movie in movies:
    # movie 안에 a 가 있으면,
    a_tag = movie.select_one('td.title > div > a')
    if a_tag is not None:
        # a의 text를 찍어본다.
        print (a_tag.text)
        
# beautifulsoup 내 select에 미리 정의된 다른 방법을 알아봅니다

# 선택자를 사용하는 방법 (copy selector)
soup.select('태그명')
soup.select('.클래스명')
soup.select('#아이디명')

soup.select('상위태그명 > 하위태그명 > 하위태그명')
soup.select('상위태그명.클래스명 > 하위태그명.클래스명')

# 태그와 속성값으로 찾는 방법
soup.select('태그명[속성="값"]')

# 한 개만 가져오고 싶은 경우
soup.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.naver?sel=pnt&date=20210829',headers=headers)

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

#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')

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)

mongoDB

 

DB 뜻 그대로 'Database' 웹상의 PC 뭐 클라우드 정도 생각하면 된다.

DB를 지원해주는 회사는 겁나 많지만 유료인 경우도 있고 무료이더라도 용량이나 기능이 제한적인 경우가 많다. 몽고도 마찬가지다. 꼭 몽고가 아니어도 상관없지만 이 번 강의에서 몽고로 진행을 하는 듯하여 나 역시 몽고로 진행을 했다.

 

마찬가지로 '파이참'에서 'mongoDB'를 사용하기 위해서는 환경 구성을 먼저 해야 한다.

설정에서 'pymongo'랑 'dnspython'을 설치해줘야 한다. 더불어 mongoDB에서도 환경설정을 해줘야 한다.

내가 사용하는 드라이버랑 버전이 맞지 않으면 정상적으로 작동을 안 하게 된다.

 

pymongo를 사용하는 방법은 아래와 같다.

from pymongo import MongoClient
client = MongoClient('여기에 URL 입력')
db = client.dbsparta

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

db.users.insert_one(doc)

# pymongo 코드 요약

# 저장 - 예시
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를 넣고 불러오는 방법을 알았으니 이제 위에서 완성했던 코딩에 합쳐주기만 하면 네이버 영화 순위를 DB에 넣을 수 있게 된다. 이제 위에서 배운 방법으로 정보를 불러오고 수정하고 삭제도 가능하다.

import requests
from bs4 import BeautifulSoup

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

# URL을 읽어서 HTML를 받아오고,
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)

# HTML을 BeautifulSoup이라는 라이브러리를 활용해 검색하기 용이한 상태로 만듦
soup = BeautifulSoup(data.text, 'html.parser')

# select를 이용해서, tr들을 불러오기
movies = soup.select('#old_content > table > tbody > tr')

# movies (tr들) 의 반복문을 돌리기
for movie in movies:
    # movie 안에 a 가 있으면,
    a_tag = movie.select_one('td.title > div > a')
    if a_tag is not None:
        rank = movie.select_one('td:nth-child(1) > img')['alt'] # img 태그의 alt 속성값을 가져오기
        title = a_tag.text                                      # a 태그 사이의 텍스트를 가져오기
        star = movie.select_one('td.point').text                # td 태그 사이의 텍스트를 가져오기
        doc = {
            'rank': rank,
            'title': title,
            'star': star
        }
        db.movies.insert_one(doc)
        
# 영화제목 '가버나움'의 평점을 가져오기
target_movie = db.movies.find_one({'title':'가버나움'})
print(target_movie['star'])

# '가버나움'의 평점과 같은 평점의 영화 제목들을 가져오기
target_movie = db.movies.find_one({'title':'가버나움'})
target_star = target_movie['star']

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

for movie in movies:
    print(movie['title'])
    
# '가버나움' 영화의 평점을 0으로 만들기
db.movies.update_one({'title':'가버나움'},{'$set':{'star':'0'}})

숙제를 하면서 'strip'에 대해 배웠는데 아래 링크에서 확인해 보자.

https://wikidocs.net/33017

 

strip()_ 문자열 및 공백 제거

### 선행과 후행 문자가 제거된 문자열의 복사본을 돌려줍니다. chars 인자는 제거할 문자 집합을 지정하는 문자열입니다. 생략되거나 None 이라면, chars 인자의 기본값…

wikidocs.net

 

728x90