공부기록/웹개발

python 기초, 웹크롤링, DB

동석쿠 2021. 12. 31. 21:48

파이썬은 매우 직관적인 언어이고, 할 수 있는 것도 많다. 그런데, 개발자들도 모든 문법을 기억하기란 쉽지 않다고 한다. 그러므로 다른 언어들과 마찬가지로 모두 외우려고하지말고 기능을 이해하고 필요할 때 찾을 수 있도록 공부하려한다

 

파이썬의 기초문법으로 변수&기본연산, 자료형, 함수, 조건문, 반복문 등이 있다.

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

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

변수, 기본연산

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

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

숫자, 문자형

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

리스트형

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

딕셔너리형

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) = 106

함수의 응용

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

result = oddeven(20)
# result의 값은 True

조건문 if/else

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

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

print(count)

# 사과의 개수를 세어 보여줍니다. = 2

반복문

파이썬과 다른언어의 차이점이라면 다른곳에선 for문을 이용하는 것에 비해 비교적 간결하다

 

파이썬에서 패키지는 모듈(일종의 기능들 묶음)을 모아 놓은 단위다. 이런 패키지의 묶음을 라이브러리 라고 볼 수 있는데, 이러한 라이브러리를 이용하면 각종 기능들을 쉽게 사용할 수 있다.

 

대표적인 예로 requests라는 라이브러리를 이용하면 데이터를 골라낼때 비교적 간단하게 고를 수 있다.

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:
	if gu['IDEX_MVL'] > 100:
		print (gu['MSRSTE_NM'], gu['IDEX_MVL'])

위 코드는 미세먼지가 100이 초과하는 지역만 보여주도록 하는 코드다

 

웹 크롤링 혹은 웹 스크래핑은 웹 서버에 저장된 데이터를 가져오는 . 예를 들어, 빗썸 웹 사이트에서 코인들의 현재가를 가져오거나 네이버 금융 사이트로부터 일봉 데이터를 가져오는 행위를 일컫는다

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

https://movie.naver.com/movie/sdb/rank/rmovie.nhn?sel=pnt&date=20200303

bs4라는 라이브러리를 사용하여 쉽게 이용할 수 있는데 이 코드에선 네이버 영화페이지를 크롤링하여 a_tag라는 항목을 반복문을 이용해 아래 사진처럼 텍스트만 나열해 프린트한다

서버에 필수요소중 하나인 DB(데이터 베이스)는 눈으로 보이지 않는다. 유식한 말로, 그래픽인터페이스(GUI)를 제공하지 않는다고 표현 하는데, 이를 눈으로 보기 위해서 robo3T라는 프로그램을 이용할 수 있다.

 

Database에는 크게 두가지 종류가 있다.

RDBMS(SQL)

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

 

No-SQL

딕셔너리 형태로 데이터를 저장해두는 DB, 고로 데이터 하나 하나 마다 같은 값을 가질 필요가 없게 된다. 자유로운 형태의 데이터 적재에 유리한 대신, 일관성이 부족할 수 있다. (MongoDB)

 

이번엔 이 둘중 No-SQL의 하나인 MongoDB를 공부할 것이다./

MongoDB를 파이썬으로 이용하기 위해선 pymongo라는 라이브러리가 필요하다.

from pymongo import MongoClient           # pymongo를 임포트 하기(패키지 인스톨 먼저 해야겠죠?)
client = MongoClient('localhost', 27017)  # mongoDB는 27017 포트로 돌아갑니다.
db = client.dbsparta                      # 'dbsparta'라는 이름의 db를 만듭니다.

# MongoDB에 insert 하기

# 'users'라는 collection에 {'name':'bobby','age':21}를 넣습니다.
db.users.insert_one({'name':'bobby','age':21})
db.users.insert_one({'name':'kay','age':27})
db.users.insert_one({'name':'john','age':30})

위의 코드를 이용하여 DB에 연결하고 데이터를 넣으면 robo3T프로그램을 이용하여 실제로 DB에 저장된 것을 확인할 수 있다.

pymongo에선 크게 다섯 가지 기능이 제일 중요한데 각각 db에 저장, 한 개 찾기, 여러개 찾기, 바꾸기, 지우기다

# 저장 - 예시
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에 저장하고 db에서 원하는 항목을 찾는 것을 해보았다.

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:
    title = tr.select_one('td.info > a.title.ellipsis').text.strip()
    rank = tr.select_one('td.number').text[0:2].strip()
    artist = tr.select_one('td.info > a.artist.ellipsis').text
    print(rank, title, artist)

지니 웹사이트에서 크롤링을 하여 title(이름), rank(순위), artist(가수) 각각의 항목을 가져와 변수에 저장하고 print로 

보기좋게 정리하였다.