두 단어를 같이 크롤링이라고 부르기도 하지만 엄밀히 말하자면 두 기술은 차이점이 있습니다.
이번에 저는 음악 차트를 가져오는 웹 스크래핑을 해보겠습니다.
먼저 스크래핑을 위한 파이썬 패키지를 설치합니다.
pip install requests
pip install bs4
스크래핑을 위한 기본 세팅입니다.
python 파일이 하나 생성하고 작성해 주세요. (.py 파일)
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://www.genie.co.kr/chart/top200?ditc=D&ymd=20210713&hh=23&rtm=N&pg=1',headers=headers)
# HTML을 BeautifulSoup이라는 라이브러리를 활용해 검색하기 용이한 상태로 만듦
# soup이라는 변수에 "파싱 용이해진 html"이 담긴 상태가 됨
# 이제 코딩을 통해 필요한 부분을 추출하면 된다.
soup = BeautifulSoup(data.text, 'html.parser')
#############################
# (입맛에 맞게 코딩)
#############################
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://www.genie.co.kr/chart/top200?ditc=D&ymd=20210714&hh=23&rtm=N&pg=1',headers=headers)
# HTML을 BeautifulSoup이라는 라이브러리를 활용해 검색하기 용이한 상태로 만듦
soup = BeautifulSoup(data.text, 'html.parser')
# select를 이용해서, tr들을 불러오기
# BeautifulSoup의 select함수를 사용해 가져오고 싶은 부분을 가져올 수 있습니다.
trs = soup.select('#body-content > div.newest-list > div > table > tbody > tr')
# 반복문으로 tr출력하기
for tr in trs:
a_tag = tr.select_one('td.info > a.title.ellipsis')
if a_tag is not None:
# 깔끔하게 출력하기 위해 strip()을 통해 양쪽 공백을 없애줍니다.
rank = tr.select_one('td.number').text[0:2].strip()
title = a_tag.text.strip()
artist = tr.select_one('td.info > a.artist.ellipsis').text
print(rank, title, artist)
#body-content > div.newest-list > div > table > tbody > tr
이런 식으로 선택자가 복사가 됩니다.beautifulsoup 내 select에 미리 정의된 다른 방법도 있습니다.
# 선택자를 사용하는 방법 (copy selector)
soup.select('태그명')
soup.select('.클래스명')
soup.select('#아이디명')
soup.select('상위태그명 > 하위태그명 > 하위태그명')
soup.select('상위태그명.클래스명 > 하위태그명.클래스명')
# 태그와 속성값으로 찾는 방법
soup.select('태그명[속성="값"]')
# 한 개만 가져오고 싶은 경우
soup.select_one('위와 동일')
깔끔하게 차트가 출력되는 것을 볼 수 있습니다.
이제는 스크래핑 결과를 데이터베이스에 저장할 수 있어야겠죠?
MongoDB는 No-SQL의 대표적인 데이터베이스입니다.
MongoDB를 설치합니다.
MongoDB가 잘 작동하는지 확인합니다.
크롬 창에 localhost:27017 이라고 쳤을 때, 아래와 같은 화면이 나오면 mongoDB가 돌아가고 있는 것입니다.
DB내부 내용을 쉽게 보기 위해서 robo 3T를 설치하셔도 좋습니다.
MongoDB를 조작하려면 pymongo라는 라이브러리가 필요합니다.
pip install pymongo
pymongo도 기본 코드가 있습니다. 이 코드를 기본으로 작성하고 시작합니다.
from pymongo import MongoClient
client = MongoClient('localhost', 27017)
db = client.dbsparta
# 코딩 시작
pymongo에서는 저장하고, 찾고, 바꾸고, 지우고 하는 네 가지 기능만 알면 됩니다.
# 저장 - 예시
# name은 bobby, age는 21로 users에 저장합니다.
doc = {'name':'bobby','age':21}
db.users.insert_one(doc)
# 한 개 찾기 - 예시
# users에서 name이 booby인 것을 찾습니다.
user = db.users.find_one({'name':'bobby'})
# 여러개 찾기 - 예시 ( _id 값은 제외하고 출력)
# users에서 age가 21인 것을 모두 찾습니다.
same_ages = list(db.users.find({'age':21},{'_id':False}))
# 바꾸기 - 예시
# users에서 name이 bobby인 것의 age를 19로 바꿉니다.
db.users.update_one({'name':'bobby'},{'$set':{'age':19}})
# 지우기 - 예시
# users에서 name이 bobby인 것을 삭제합니다.
db.users.delete_one({'name':'bobby'})
데이터베이스 부분을 추가한 코드입니다.
import requests
from bs4 import BeautifulSoup
from pymongo import MongoClient # pymongo를 임포트
client = MongoClient('localhost', 27017) # mongoDB는 27017 포트로 돌아갑니다.
db = client.dbsparta # 'dbsparta'라는 이름의 db를 만듭니다.
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=20210714&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:
a_tag = tr.select_one('td.info > a.title.ellipsis')
if a_tag is not None:
rank = tr.select_one('td.number').text[0:2].strip()
title = a_tag.text.strip()
artist = tr.select_one('td.info > a.artist.ellipsis').text
doc = { # 도큐먼트 만들기
'rank':rank,
'title':title,
'artist':artist
}
print(rank, title, artist)
db.trs.insert_one(doc) # 위에서 만든 도큐먼트를 db에 넣어줍니다.
robo 3T에서 데이터베이스에 잘 저장된 것을 볼 수 있습니다.
이 글은 스파르타코딩클럽을 참고로 작성했습니다.