아무것도 모르고 시작하는 코딩

웹 스크래핑 후 몽고DB에 저장하기 | 아무것도 모르고 시작하는 코딩

ZNOS 2020. 9. 28. 11:45
반응형

지난 포스팅에서 웹스크레핑을 하는 방법을 연습했었다

2020/09/18 - [아무것도 모르고 시작하는 코딩] - 파이썬 웹 스크래핑(a.k.a 크롤링 in Korea) - 정보를 긁어오자(feat. BS4, beautifulSoup | 아무것도 모르고 시작하는 코딩

 

파이썬 웹 스크래핑(a.k.a 크롤링 in Korea) - 정보를 긁어오자(feat. BS4, beautifulSoup | 아무것도 모르고

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

znos.tistory.com

 

이번엔 스크래핑한 결과를 몽고DB에 저장하는 방법에 대해서 알아보자

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

client = MongoClient('localhost', 27017)  # mongoDB는 27017 포트로 돌아갑니다.
db = client.dbsparta    # 'dbsparta'라는 이름의 db를 사용합니다. 'dbsparta' 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=20200716', headers=headers)

# HTML을 BeautifulSoup이라는 라이브러리를 활용해 검색하기 용이한 상태로 만듦
# soup이라는 변수에 "파싱 용이해진 html"이 담긴 상태가 됨
# 이제 코딩을 통해 필요한 부분을 추출하면 된다.
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를 찍어본다.
        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)

우선 여기까지가 지난시간에 했었던 웹스크래핑 코드이다. 여기서 print를 하지 말고 insert를 할 것이다.
print 부분을 #을 넣어 주석처리 하고 아래 코드를 붙여넣자.

 if a_tag is not None:
        # a의 text를 찍어본다.
        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에는 숫자처럼 생긴 문자열 형태로 저장됩니다.
        }
        db.movies.insert_one(doc)

 

doc = { 'rank': rank, 'title': title, 'star': star }   →   doc는 딕셔너리 형태이며 'rank'라는 키값은 movie.select_one('td:nth-child(1) > img')['alt'] 의 rank 값이다.('title', 'star'도 마찬가지)

db.movies.insert_one(doc)   →   db에 movies라는 하위폴더를 만들고 doc를 삽입해라

 

 

저장이 잘 됐는지 확인하기 위해서 윈도우키+R을 눌러 cmd를 실행시키고 mongod를 입력하여 mongoDB에 연결하자

robo3T를 실행시키면 dbsparta에 collections 안에 movies 항목이 생기고 데이터가 저장된 것을 확인할 수 있다.

 

 

월-E의 평점과 같은 평점의 영화제목들 가져오기

스크래핑한 결과에서 필요한 정보를 필터링 할 수도 있다.

from pymongo import MongoClient

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

target_movie = db.movies.find_one({'title': '월-E'})
target_star = target_movie['star']

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

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

target_movie = db.movies.find_one({'title': '월-E'})  →   db에 movies에 제목이 월-E인 것을 찾아 target_movie라고 하자

target_star = target_movie['star']  →   target_movie에서 'star'값을 target_star라고 하자(월-E의 평점이다)

movies = list(db.movies.find({'star': target_star}))  →  db에 movies에 'star'값이 target_star값과 같은 값을 리스트화 한 것을 movies라고 하자

for movie in movies:
print(movie['title'])
 
→  반복문을 이용하여 movies에 title값을 모두 출력해라

결과 값

 

 

끝.

반응형