wisePocket

[Python][Database] 웹 크롤링 데이터를 DB에 넣기(Create) Insert_one 본문

Python&Flask Tutorials, AWS EB/3rd WEEK Python, Crawling, MongoDB

[Python][Database] 웹 크롤링 데이터를 DB에 넣기(Create) Insert_one

ohnyong 2023. 7. 6. 17:16

requests, beautifulsoup 라이브러리를 활용하여 웹 페이지의 원하는 정보를 크롤링 했었다.

https://ohnyong.tistory.com/32

 

[Python] 파이썬 크롤링 with BeautifulSoup(bs4) - 2

History venv로 파이썬을 연습하고 있는 폴더의 가상 환경 구축을 완료 requests 라이브러리를 사용 BeautifulSoup 라이브러리 설치 및 사용 영화 예매 순위 사이트에서 제목 가져오기 크롤링 연습 완료 Ti

ohnyong.tistory.com

 

0. 위 크롤링 실습 링크의 요약

웹 크롤링의 필수 코드는 다음과 같다.

import requests
from bs4 import BeautifulSoup

URL = "https://movie.daum.net/ranking/reservation"
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)
soup = BeautifulSoup(data.text, 'html.parser')

URL을 원하는 URL로 변경하면 된다.

 

이후 beautifulsoup 라이브러리를 활용해서 원하는 정보만 가져오게 세팅한다.

# 내가 원하는 값이 있었던 li:nth-child(1)가 아니라 li까지 스코프를 지정하자
titles = soup.select('#mainContent > div > div.box_ranking > ol > li')
print(titles)

# 리스트 중에 반복문으로 
# li 코드 내용 중에 클래스가 a class="link_txt"로 되어있는 태그부분만 가져오자
for li in titles:
    rank = li.select_one('.rank_num').text
    title = li.select_one('.link_txt').text.strip()
    rate = li.select_one('.txt_grade').text.replace(',','')
    
#그 중에 텍스트만 가져오자 -> 위 변수에서 .text로 추출하는 것으로 변경함
print(rank, title, rate)

여기까지 진행되면 rank, title, rate 각 변수에 웹에서 크롤링한 데이터를 담게 된다.

  • rank = 랭킹 순위
  • title = 영화 제목
  • rate = 평점

이 내용까지가 전 실습의 요약이다.


 

웹 페이지를 크롤링하여 console창에서 데이터를 확인하는 것이 이전 실습이었다면

이번에는 데이터를 DB와 연동시켜 저장, 읽기, 수정, 삭제 (CRUD)하는 것이 목적이다.

 

 

1. 크롤링을 구현한 부분에 DB 연결 추가

위 웹 크롤링 실습 코드에

데이터베이스 연결을 위한 db연결을 위해 pymongo 패키지 라이브러리를 추가해준다.

 

# Python과 DB를 연결하는 코드(공통)
# MongoDB를 사용할 준비가 되었다.
from pymongo import MongoClient
import certifi
ca = certifi.where()
client = MongoClient('mongodb+srv://ohnyong:test@cluster0.lu7mz8j.mongodb.net/?retryWrites=true&w=majority',tlsCAFile=ca)
db = client.dbsparta

이러면 웹 크롤링, 데이터 변수에 저장 + db연결준비

가 완료되었다.

2. DB 연결 이후 DB에 변수에 담아둔 크롤링 데이터를 추가 

MongoDB로 데이터(Document{Field})를 저장(insert)하기 위해서는 다음과 같은 스크립트로 수행한다.

    # INSERT_ONE
    # 저장 - 예시
    # doc = {'name':'bobby','age':21}
    # db.col.insert_one(doc)

document에 {key1:value1, key2:value2}와 같이 필드값을 넣어서

insert_one이라는 메서드를 통해 col이라는 collection에 넣는다.

이를 실습에서 받은 영화 관련 데이터로 적용하면

# 연결된 DB로 doc 도큐먼트 내용을 삽입 insert 하자.
doc = {
    'rank':rank,
    'title':title,
    'rate':rate
}
db.movies.insert_one(doc)

doc이라는 명칭으로 document를 생성하는데

그 안에는 rank, title, rate라는 field로 구분된다.

field마다 웹에서 크롤링한 데이터 rank, title, rate 변수가 들어간다.

이렇게 doc에 저장된 내용이 insert_one이라는 메서드를 통해

MongoDB로 연결된 db내 movies라는 collection에 삽입 들어가게 된다.

 

전체 코드

import requests
from bs4 import BeautifulSoup

# Python과 DB를 연결하는 코드(공통)
# MongoDB를 사용할 준비가 되었다.
from pymongo import MongoClient
import certifi
ca = certifi.where()
client = MongoClient('mongodb+srv://ohnyong:test@cluster0.lu7mz8j.mongodb.net/?retryWrites=true&w=majority',tlsCAFile=ca)
db = client.dbsparta

# 웹 크롤링 결과를 DB에 저장하자

# 다음은 웹 크롤링 구현 부분이다.
URL = "https://movie.daum.net/ranking/reservation"
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)
soup = BeautifulSoup(data.text, 'html.parser')

# 위 링크 페이지의 전체 HTML이 아웃풋 된다
# print(soup)

# BeautifulSoup 라이브러리는 엄청 많은 HTML 코드 중에 우리가 원하는 특정 부분 을 빠르고 쉽게 필터링 해주는 라이브러리이다.
# Title 데이터가 포함된 코드를 가져와보자
title = soup.select_one('#mainContent > div > div.box_ranking > ol > li:nth-child(1) > div > div.thumb_cont > strong > a')
print(title)
# 그 중에서 텍스트만
# print(title.text)
# 혹시나 그 중에서 속성만 가져오고 싶은 경우
# ( ['xxx'] -> dictionary 직접관계없다 bs개발자가 만든 문법이다.)
# print(title['href'])


# 내가원하는 데이터들이 리스트로 나열되어 있었다.
# 1개가 아니라 li를 포함한 전체 리스트들을 가져와보자
# 내가 원하는 값이 있었던 li:nth-child(1)가 아니라 li까지 스코프를 지정하자
titles = soup.select('#mainContent > div > div.box_ranking > ol > li')
# print(titles)

# 리스트 중에 반복문으로 
# li 코드 내용 중에 클래스가 a class="link_txt"로 되어있는 태그부분만 가져오자
for li in titles:
    rank = li.select_one('.rank_num').text
    title = li.select_one('.link_txt').text.strip()
    rate = li.select_one('.txt_grade').text.replace(',','')
    
    ######## 이번 실습에서는 가져온것을 저장하자로 변경되었다. ########
    # INSERT_ONE
    # 저장 - 예시
    # doc = {'name':'bobby','age':21}
    # db.users.insert_one(doc)

	# 연결된 DB로 doc 도큐먼트 내용을 삽입 insert 하자.
	doc = {
        'rank':rank,
        'title':title,
        'rate':rate
	}
	db.movies.insert_one(doc)
    # 탭 위치 조심

 

다음과 같이 해당 코드들이 모두 담긴 python 파일을 실행하면 웹 크롤링 + DB 연결 -> DB insert문 수행

이 실행 된 것을 확인 할 수 있다.

Atlas에서 연결된 나의 MongoDB에 데이터가 추가된 것을 확인 할 수 있다.

 

#Python에서는 줄바꿈(탭)을 잘 맞춰야 한다.

위 코드에서 데이터가 반복문을 돌지않고 1개만 삽입되어서 의문을 가졌는데 #doc = { ... } 부분이

그 위의 for 반복문과 같은열에 있었다.

for 내부로 doc 부분을 옮기니 정상적으로 반복문의 내용을 수행 했다.


 

해당 스터디는 아래 깃을 통해 업데이트 되고 있습니다.

https://github.com/yzpocket/Sparta99training

 

GitHub - yzpocket/Sparta99training

Contribute to yzpocket/Sparta99training development by creating an account on GitHub.

github.com