오늘은 앞서 정리했던 글들의 데이터를 DB에 저장하는 과정을 리뷰할 차례다.
그전에 가장 먼저 정리해야할 것은 CRUD라는 개념!
라고 한다면, 대부분의 소프트웨어가 가지고 있는 데이터 처리 기능들을 묶어서 말하는데 크루드라고도 하고 씨알유디라고도 한다더라. 그럼 이게 무슨 뜻인가하면 아래와 같다.
대표적인게 인스타그램이나 페이스북과 같은 SNS를 생각하면 쉽다. 피드를 생성하고 피드를 읽고 피드를 수정하고 피드를 삭제하는 기능이 하나에 다 들어있는.
그럼 이제 우리 클래스에서 데이터를 다루기 위해 사용하는 툴은 무엇인가. mongoDB, robo3T다. 여기서도 내 노트북은 문제가 많았는데, 이게 이전에 개발환경 세팅하면서 생긴 디렉토리 설정 문제인지 뭔지 모르겠다....튜터님도 모르겠다고 하셨다.....이럴수록 더 맥북이 땡긴다 ㅠ....
robo3T는 크게 어려운 개념이 없다. 그냥 우리가 DB를 편히 볼 수 있도롤 GUI를 제공해주는 툴이라고 보면 된다.
그럼 mongoDB란 무엇인가?를 알아보자.
DB 그러니까 데이터베이스(database)라고 하는 것에는 크게 두 종류 SQL과 NoSQL이 있다.(아니면..알려주세요 ㅎㅎ)
우리가 쓸 mongoDB의 경우에는 NoSQL이다. 앞서 기술한 것처럼 딕셔너리 형태로 데이터를 저장한다는 부분이 정말 중요한 포인트다. 그럼 mongoDB에서 데이터를 생성하려면 어떻게 해야할까?
from pymongo import MongoClient #pymongo 임포트해주기 client = MongoClient('localhost', 27017) #포트 설정 db = client.dbsparta #데이터 베이스 생성해주기
db생성까지는 명령문들을 복사해서 사용하면 된다. 여기서 이제 users라는 collection에 데이터를 생성해줄텐데 python에서 딕셔너리를 생성해주던 것처럼 생성하면 된다.
그리고 나머지 기능을 CRUD 차례대로 살펴보자면
insert_one이라는 명령문을 통해서 딕셔너리 형태로 데이터 생성이 가능하다.
# Create(생성) user1 = {'name': '론', 'age': 40} user2 = {'name': '해리', 'age': 40} db.users.insert_one(user1) db.users.insert_one(user2) 혹은 db.users.insert_one({'name': '덤블도어', 'age': 116}) db.users.insert_one({'name': '맥고나걸', 'age': 85})
find(혹은 find_one)이라는 명령문을 통해 데이터 조회가 가능하다. 추가로 "id"값을 제외하고 출력하고 싶다면 "_id":False 혹은 "_id":0 이라는 조건을 추가해주면 된다.
# Read(조회) - 한 개 값만 user = db.users.find_one({'name': '론'}) # Read(조회) - 여러 값 ( _id 값은 제외하고 출력) same_ages = list(db.users.find({'age': 40}, {'_id': False}))
update_one(혹은 update_many)라는 명령문을 통해 데이터 업데이트가 가능하다. 바꾸고자 하는 데이터를 앞에 두고 뒤에 "$set"뒤에 바꾸고자 하는 값을 입력해 주면 된다.
# Update(업데이트) - 여러 값 db.people.update_many({'age': 40}, { '$set': {'age': 70}}) # Update(업데이트) - 하나 값 db.users.update_one({'name': '론'}, {'$set': {'age': 116}})
DELETE(혹은 DELETE_ONE)을 통해 데이터 삭제가 가능하다.
# Delete(삭제) db.users.delete_one({'name': '론'})
그럼 이렇게 배운 pymongo를 어디에 사용이 가능하냐? 우리가 앞서 배웠던 웹스크래핑(크롤링)에서 사용이 가능하다. 앞선 시간에 영화평점을 조회하거나 야구팀의 순위분석(승률)을 진행했는데 그 아래에 코드 몇줄을 추가하면 데이터를 db에 저장하거나 조회해서 변경이 가능하다.
백문이 불여일타. 쳐보자. 쳐보면 된다.
import requests from bs4 import BeautifulSoup from pymongo import MongoClient # pymongo를 임포트 하기 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=20200716', headers=headers) soup = BeautifulSoup(data.text, 'html.parser') movies = soup.select('#old_content > table > tbody > tr') for movie in movies: 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'] title = a_tag.text star = movie.select_one('td.point').text print(rank, title, star)
지난번에 작성했던 영화평점 크롤링 코드인데, 추가된건 pymongo 환경뿐이다.
그럼 여기서 코드를 추가해서 db에 데이터들을 저장하고 조회하고 업데이트까지 해보자.
우선 영화 순위에 있는 '월E'와 평점이 같은 영화들의 제목을 가져와보자.
이건 CREATE& READ & UPDATE라고 보면 되겠지?
doc = { 'rank': rank, 'title': title, 'star': star } db.movies.insert_one(doc) target_movie = db.movies.find_one({'title': '월-E'}) target_star = target_movie['star'] movies = list(db.movies.find({'star': target_star})) db.movies.update_many({'star': target_star}, {'$set': {'star': '0'}})
우선 이전에 크롤링을 통해 조회된 값들을 우선 doc에 딕셔너리 형태로 저장해주고, 그것들을 모두 "movies"라는 콜렉션에 insert_one(doc)명령문을 통해 저장해준다.(CREATE)
find_one명령문을 통해 '월E'라는 제목을 가진 영화의 데이터를 조회, 다시 영화의 평점인 'star'로 '월E'의 평점(target_star)을 설정해준다. 그리고 이 조건으로 find명령어를 통해 똑같은 평점('start)를 가진 영화들의 리스트를 모두 가져온다. movies라는 리스트 안으로 (READ)
그러면 변경해야할 목표가 정해졌다!(='target_start') 우리는 update_many 명령문을 통해 movies라는 리스트 안에 들어있는 영화 중 'target_start'와 똑같은 값을 가진 영화들의 평점을 '$set'을 통해 0점으로 만들어준다 . (UPDATE)
이걸로 오늘의 과정은 끝이 난다. 그런데 마지막에 궁금한게....음....이미 '월E'와 같은 점수를 LIST로 만들어 주었는데 update_many를 실행할 때 굳이 'start'에 'target_star'라는 조건을 넣어야하는가? 라는 의문이 생겼다. 이거는 나중에 물어봐야지 (혹시 이 글을 읽으시는 분이 계시다면 알려주시면 감사하겠습니다 ㅠ)
하루하루 밀리다보니 3주차 리뷰가 이제야 끝났다.
이미 4주차도 진행했는데 이번주는 주말이 오기전에 4주차 리뷰를 끝내야지!!!