-
개발공부 13일차 [웹스크래핑(크롤링), DB]개인공부 2023. 2. 7. 11:53
라이브러리
import requests r = requests.get('http://spartacodingclub.shop/sparta_api/seoulair') rjson = r.json() rows = rjson['RealtimeCityAir']['row'] for a in rows: gu_name = a['MSRSTE_NM'] gu_mise = a['IDEX_MVL'] print(gu_name, gu_mise)
gu_name, gu_mise값만 추출해서 반복문으로 볼 수 있음
크롤링 : 웹에 접속해서 데이터를 솎아내어 가지고옴
오른쪽 하단에 ‘venv’:venv 로 잘 열려있는지 확인
잘 열려있다면 터미널에 (venv)가 있는지 확인
없다면 터미널 → 새터미널 눌러주면 생김
라이브러리를 가져올때 : 터미널에 pip install (가져올 라이브러리 이름) 치기
requests - 요청하다
beautifulsoup - 솎아내다
import requests from bs4 import BeautifulSoup 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.naver?sel=pnt&date=20210829',headers=headers) soup = BeautifulSoup(data.text, 'html.parser') #old_content > table > tbody > tr:nth-child(2) #old_content > table > tbody > tr:nth-child(3) #old_content > table > tbody > tr:nth-child(2) > td.title > div > a trs = soup.select('#old_content > table > tbody > tr') for tr in trs: a = tr.select_one('td.title > div > a') if a is not None: print(a.text)
1. 크롤링 할 페이지에서 가져올 글에 검사로 tr을 먼저 찾아
#old_content > table > tbody > tr:nth-child(2)
#old_content > table > tbody > tr:nth-child(3) \
이중 공통되는 #old_content > table > tbody > tr 공통되는 걸 변수trs에 찾는다.
(공통되는걸 찾을때는 tr에 우클릭으로 Copy → CopySelector로 가져올 수 있다)
2. trs를 반복문으로 불러온다.
3. tr안에서 내가 가져올
#old_content > table > tbody > tr:nth-child(2) > td.title > div > a
공통되는 td.title > div > a를 찾는다.
4. 찾은 td에 ——— 도 포함이 되어있어 None으로 표시되는데
if a is not None: 을 써서 None이 아닌것만 text로 불러온다.
응용하기
import requests from bs4 import BeautifulSoup 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.naver?sel=pnt&date=20210829',headers=headers) soup = BeautifulSoup(data.text, 'html.parser') #old_content > table > tbody > tr:nth-child(2) #old_content > table > tbody > tr:nth-child(3) #old_content > table > tbody > tr:nth-child(2) > td.title > div > a #old_content > table > tbody > tr:nth-child(2) > td:nth-child(1) > img #old_content > table > tbody > tr:nth-child(2) > td.point trs = soup.select('#old_content > table > tbody > tr') for tr in trs: a = tr.select_one('td.title > div > a') if a is not None: title = a.text rank = tr.select_one('td:nth-child(1) > img')['alt'] star = tr.select_one('td.point').text print(rank, title, star)
a는 이미 찾았기때문에 title 변수를 만들어 a.text로 넣어준다.
rank, star도 동일한 방식으로 가져오고 마지막에 원하는 순서로 찍으면 완성
⬇️결과값
------------------------------------------------------------------------------------------
데이터베이스 - DB
SQl - 이미 정해진 칸에 넣는거임.
이미 정해져 있어 사람이 틀릴 리 없음 / 후에 변하지 않는다는 가정으로 / 빨리 가져올 수 있음 (대기업같은 경우)
NoSQl (Not only SQL) - 정형화된 틀이 아님 / 데이터를 내 마음대로 저장할 수 있음
(스타트업이 주로 사용) 저장할 틀이 변경될일이 많을 경우
mongoDB Atlas - 클라우드
from pymongo import MongoClient client = MongoClient('mongodb+srv://sparta:test@cluster0.wpply3w.mongodb.net/?retryWrites=true&w=majority') db = client.dbsparta doc = { 'name':'영수', 'age':24 } db.users.insert_one(doc)
db.users.insert_one(doc) ← 여기에 users는 소그룹이름 이라고 생각해도 됨
pymongo
# 저장 - 예시 doc = {'name':'bobby','age':21} db.users.insert_one(doc) # 한 개 찾기 - 예시 user = db.users.find_one({'name':'bobby'}) # 여러개 찾기 - 예시 ( _id 값은 제외하고 출력) all_users = list(db.users.find({},{'_id':False})) #{'_id':False}를 사용하는 이유는 _id의 값을 출력하지 않기 위해서다. # 바꾸기 - 예시 db.users.update_one({'name':'bobby'},{'$set':{'age':19}}) # 지우기 - 예시 db.users.delete_one({'name':'bobby'})
mongoDB에 자료 넣는 방법 복습
from pymongo import MongoClient client = MongoClient('mongodb+srv://sparta:test@cluster0.wpply3w.mongodb.net/?retryWrites=true&w=majority') db = client.dbsparta trs = soup.select('#old_content > table > tbody > tr') for tr in trs: a = tr.select_one('td.title > div > a') if a is not None: title = a.text rank = tr.select_one('td:nth-child(1) > img')['alt'] star = tr.select_one('td.point').text doc = { 'title': title, 'rank' : rank, 'star' : star } db.movies.insert_one(doc)
- 기존 영화 목록에 상단에 몽고디비에 연결될 수 있도록 넣어준다.
- Dictionary를 만들어서 넣어줘야함 doc = {}
- 마지막으로 insert해주기 위해 movies라는 소그룹명을 만들고 넣어줌.
위 내용을 가지고 Quiz풀기
- 영화제목’가버나움’의 평점을 가져오기
movie = db.movies.find_one({'title':'가버나움'}) print(movie['star'])
2. ‘가버나움’의 평점과 같은 평점의 영화 제목들을 가져오기
movie = db.movies.find_one({'title':'가버나움'}) target_star = movie['star'] movies = list(db.movies.find({'star':target_star},{'_id':False})) for a in movies: print(a['title'])
- 변수 movie에서 가버나움의 star값을 target_star라는 변수라고 해놓는다.
- 변수 movies로 소그룹movies에 star값이 target_star이 동일한 것만 가지고 온다.
- 마지막으로 반복문으로 타이틀만 가지고온다.
3. ‘가버나움’의 영화의 평점을 0으로 만들기
db.movies.update_one({'title':'가버나움'},{'$set':{'star':0}})
숙제
import requests from bs4 import BeautifulSoup 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=M&rtm=N&ymd=20210701',headers=headers) soup = BeautifulSoup(data.text, 'html.parser') #body-content > div.newest-list > div > table > tbody > tr:nth-child(1) > td.info > a.title.ellipsis #body-content > div.newest-list > div > table > tbody > tr:nth-child(1) > td.number #body-content > div.newest-list > div > table > tbody > tr:nth-child(1) > td.info > a.artist.ellipsis trs = soup.select('#body-content > div.newest-list > div > table > tbody > tr') for tr in trs: a = tr.select_one('td.info > a.title.ellipsis') title = a.text.strip() rank = tr.select_one('td.number').text[0:2].strip() artist = tr.select_one('a.artist.ellipsis').text.strip() print(rank,title,artist)
text[0:2]는 텍스트에 2번째 글자 까지만 나오게 한다.
strip()은 글자의 공백이 없게 나오게 한다.
크롤링 강의를 처음봤을땐 어..?싶었고 일단 다 보고서 강의를 다시 멈추면서 하나하나 적어가면서 다시 보니깐 이해가 갔고 생각보다 재밌었다.
마지막 숙제에서는 진짜 구글링을 아직 할 줄 모르니까 제대로된 답도 안나오고 '그냥 강의에 답을 볼까..?' 싶었다가 꾹참았다.
시간은 좀 걸렸지만 스스로 하고 맞은걸 보니 넘나 뿌듯...하다..
'개인공부' 카테고리의 다른 글
개발공부 16일차[API연동 / Flask / 혼자서 다시 해보기!] (0) 2023.02.09 개발공부 15일차[API연동 / Flask/ 배포] (0) 2023.02.08 개발공부 14일차[API연동 / Flask] (0) 2023.02.07 개발공부 12일차 [JavaScript 복습, python] (0) 2023.02.05 개발공부 11일차 [Jabascript, JQuery, Fetch] (0) 2023.02.05