본문 바로가기
알아두면쓸데있는신기한잡학사전/고군분투흔적들

[Web] DB - MongoDB, pymongo

by 대범하게 2022. 8. 22.
반응형

DB의 종류

Database는 크게 두 가지 종류로 나뉜다.

- RDBMS(SQL) 행/열의 생김새가 정해진 엑셀에 데이터를 저장하는 것과 유사하다.

데이터 50만개가 적재된 상태에서, 갑자기 중간에 열을 하나 더하기는 어렵지만, 정형화되어있는 만큼 데이터가 일관적이고 분석에 용이하다. MS-SQL, My-SQL등이 여기 속한다.

 

- NoSQL 딕셔너리 형태로 데이터를 저장해두는 DB이다.

데이터 하나하나마다 같은 필드 값들을 가질 필요가 없어 자유로운 형태의 데이터 적재에 유리한 대신, 일관성이 부족할 수 있다. MongoDB가 이에 속한다. 


MongoDB

=> MongoDB는 다양한 플랫폼에서 사용할 수 있는 NoSQL 타입의 데이터베이스 프로그램으로,

JSON과 비슷한 형태로 자료를 정리한다.

 

- MongoDB의 자료는 각각의 딕셔너리인 도큐먼트가 모여 컬렉션, 컬렉션이 모여 DB가 되는 형태이다.

- 이전에 크롤링한 영화 정보를 예로 들면, 제목/순위/별점이 있는 각 영화 정보 도큐먼트이고, 이것들을 모인 컬렉션 크롤릴 용 DB에 저장할 수 있다.

- 만약에 네이버 기사 제목을 크롤링했다면 그 결과는 같은 DB에 다른 컬렉션으로 저장할 수 있을 것이다.

 

Mongo 설치(윈도우)

C 드라이브에, data라는 폴더를 만들고, 그 안에 db라는 폴더를 만든다. => 위치가 될 것이다.

 

Robo 3T 설치 및 세팅

Robo 3T MongoDB를 그래픽으로 볼 수 있게 도와주는 GUI(Graphic User Interface)이다.

- 다운로드: https://robomongo.org/download

- Download Robo 3T를 받아 설치한다. ( => Studio 3T가 아니다!)

- Robo 3T를 실행하고, MongoDB Connections라는 같은 창이 나오면 Create 버튼을 누른 후 아래와 같이 설정해준다. Name은 아무것이나 상관없다.

- save를 눌러 연결 정보를 저장하고 connect를 눌러 연결한다.

 

설치 참고 => 몽고디비 GUI 개발/관리도구 Studio 3T 설치(Robo 3T)[https://joytk.tistory.com/75]


pymongo로 mongoDB 조작하기

pymongo 라이브러리의 역할

MS Excel를 파이썬으로 조작하려면 그에 맞는 특별한 라이브러리(openpyxl)가 필요한 것처럼, 

MongoDB라는 프로그램을 조작하기 위해 특별한 라이브러리 pymongo가 필요하다.

 

Python으로 MongoDB 이용하기 [https://wooiljeong.github.io/python/mongodb-01/]

 

pymongo 설치

pip install pymongo

 

DB연결 - MongoClient

MongoDB에 연결하는 두가지 방법

첫 번째 방법은 MongoClient의 값으로 MongoDB 서버 URL를 파라미터로 입력하는 것

두 번째 방법은 MongoDB 서버의 호스트와 포트 각각의 값을 파라미터로 입력하는 것

from pymongo import MongoClient           # pymongo를 임포트 하기(패키지 인스톨 먼저 해야겠죠?)

# 방법 2 - HOST, PORT
client = MongoClient('localhost', 27017)  # mongoDB는 27017 포트로 돌아갑니다.
db = client.dbsparta                      # 'dbsparta'라는 이름의 db를 만듭니다.
 

[pymongo로 mongoDB 조작하기]

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})

# MongoDB에서 데이터 모두 보기
all_users = list(db.users.find({}))

# 참고) MongoDB에서 특정 조건의 데이터 모두 보기
same_ages = list(db.user.find({'age':21}))

print(all_users[0])         # 0번째 결과값을 보기
print(all_users[0]['name']) # 0번째 결과값의 'name'을 보기

for user in all_users:  # 반복문을 돌며 모든 결과값을 보기
    print(user)

# //////////////////////////////////////////////////////////
# 특정 결과 값을 뽑아보기

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

# 그 중 특정 키 값을 빼고 보기
user = db.users.find_one({'name':'bobby'},{'_id':False})
print(user)


# //////////////////////////////////////////////////////////
# 수정하기

# 생김새
db.people.update_many(찾을조건,{ '$set': 어떻게바꿀지 })

# 예시 - 오타가 많으니 이 줄을 복사해서 씁시다!
db.users.update_one({'name':'bobby'},{'$set':{'age':19}})

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


# //////////////////////////////////////////////////////////
# 삭제하기
db.users.delete_one({'name':'bobby'})

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

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에 저장하기

https://bo5mi.tistory.com/80

 

[Project] 웹 스크래핑

웹 스크래핑이란 : 웹 스크래핑(web scraping)은 웹 페이지에서 우리가 원하는 부분의 데이터를 수집해오는 것을 뜻한다. - 한국에서는 같은 작업을 크롤링 crawling이라는 용어로 혼용해서 쓰는 경우

bo5mi.tistory.com

 

1. 웹스크래핑(순위, 제목, 별점)  코드

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:
        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 태그 사이의 텍스트를 가져오기
        print(rank,title,star)
        
# 태그 안의 텍스트를 찍고 싶을 땐 -> 태그.text
# 태그 안의 속성을 찍고 싶을 땐 -> 태그['속성']

 

2. 위 코드에서 import 줄들 아래에 pymongo 기본 세팅 코드를 붙여넣기

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

 

3. 각 영화마다 도큐먼트 만들어 하나씩 insert 하기

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

 

4. Robo 3T에서 새로고침을 하고 dbjungle DB, movies 컬렉션 안에 영화 정보가 쌓인 것을 확인할 수 있다.

 

[전체적인 코드]

# 웹스크래핑 + DB 연동
import requests
from bs4 import BeautifulSoup

# 웹스크래핑 결과를 DB에 저장하기
from pymongo import MongoClient          # pymongo를 임포트 하기
client = MongoClient('localhost', 27017) # mongoDB는 27017 포트로 돌아갑니다.
db = client.dbjungle                     # 'dbjungle'이라는 이름의 db를 만듭니다.


# 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:
        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 태그 사이의 텍스트를 가져오기
        print(rank,title,star)
        doc = {
            'rank': rank,
            'title': title,
            'star': star
        }
        db.movies.insert_one(doc)

find, update 연습하기

# - 위의 코드는 실행할 때마다 50개의 영화정보가 계속 쌓일 것이므로,
#  다른 파이썬 파일을 새로 하나 만들어 find, update를 연습해보겠습니다.

# pymongo 기본 코드
from pymongo import MongoClient
client = MongoClient('localhost', 27017)
db = client.dbjungle

# Q1. 영화제목 '매트릭스'의 평점을 가져오기
target_movie = db.movies.find_one({'title': '매트릭스'})
target_start = target_movie['star']
print(target_start)

# Q2. '매트릭스'의 평점과 같은 평점의 영화 제목들을 가져오기
movies = list(db.movies.find({'star':target_start}))

for movie in movies:
    print(movie['title'])

# Q3. 매트릭스 영화의 평점을 0으로 만들기
change_rank = db.movies.update_one({'title':'매트릭스'}, {'$set':{'star':'0'}})

 

반응형