3-1 / 3주차 오늘 배울것
python 설치, git-bash 설치
파이썬, 크롤링, mongoDB
크롤링 이란?
크롤링(crawling) 혹은 스크레이핑(scraping)은 웹 페이지를 그대로 가져와서 거기서 데이터를 추출해 내는 행위다.
3-2 / 2주차 복습
$(document).ready(function () {
listing();
});
//화면이 로딩되면 바로 호출
function listing() {
$('#cards-box').empty()
//ajax콜
$.ajax({
type: "GET",
url: "http://spartacodingclub.shop/web/api/movie",
data: {},
success: function (response) {
let rows = response['movies']
for (let i = 0; i < rows.length; i++){
let title = rows[i]['title']
let image = rows[i]['image']
let star = rows[i]['star']
let desc = rows[i]['desc']
let comment = rows[i]['comment']
let stars = `⭐`.repeat(star) // 문자 반복 함수
let temp_html = `<div class="col">
<div class="card h-100">
<img src="${image}"
class="card-img-top" alt="...">
<div class="card-body">
<h5 class="card-title">${title}</h5>
<p class="card-text">${desc}</p>
<p>${stars}</p>
<p class="mycomment">${comment}</p>
</div>
</div>
</div>`
$('#cards-box').append(temp_html)
}
}
})
}
3-3 / 파이썬 시작하기
폴더 설정해서 새 프로젝트 생성 - hello sparta 출력
3-4 / 파이썬 기초공부
파이썬 기본 연산, 리스트, 딕셔너리, 함수
def sum(a,b):
print('더하자')
return a+b
# def = definition의 약자
result = sum(1,2)
print(result)
# 결과:
# 더하자
# 3
파이썬에서는 들여쓰기가 중요
def is_adult(age):
if age > 20:
print('성인입니다.')
else:
print('청소년입니다')
is_adult(25)
# 성인입니다
파이썬이 좀 더 직관적인 문법이라는 걸 알 수 있는게 반복문에서
fruits = ['사과','배','배','감','수박','귤','딸기','사과','배','수박']
count = 0
for fruit in fruits :
if fruit == '사과' :
count += 1
print(count)
# 2
people = [{'name': 'bob', 'age': 20},
{'name': 'carry', 'age': 38},
{'name': 'john', 'age': 7},
{'name': 'smith', 'age': 17},
{'name': 'ben', 'age': 27}]
for person in people :
if person['age'] > 20 :
print(person['name'])
# carry
# ben
3-5 / 파이썬 패키지 설치하기
크롤링을 하려면 남들이 만들어 놓은 라이브러리를 사용해야함 이 라이브러리를 파이썬에서는 패키지라 일컫는다
이 패키지를 어떻게 다운받고 설치하는 지 알아보자
1. 파이썬에서 가상 환경(virtual environment) 이란? - 프로젝트별로 패키지들을 담을 공구함
예시)
내 컴퓨터에 프로젝트 2개를 만들어 아래와 같이 사용 중이라 내 컴퓨터에 A B C D E 패키지가 설치되어 있다고 하자
| 프로젝트 A | A | B | C | ||
| 프로젝트 B | B | C | D | E |
아래처럼 프로젝트 하나를 이전 버전의 패키지로 사용해야하는 상황이 온다면 프로젝트 B의 B 패키지마저 내려야 하는 난감한 상황이 벌어지지 않도록 파이썬에서는 프로젝트 '별'로 따로 패키지를 담을 수 있게 해놨는데
| 프로젝트 A | A | B' | C | ||
| 프로젝트 B | B | C | D | E |
그것이 바로 가상환경 (virtual environment) 이를 줄여 venv 라고 한다.
프로젝트 생성시 자동으로 생성되는 그 폴더가 바로 그것! 패키지가 이곳에 저장된다.
| 가상환경(virtual environment)은 같은 시스템에서 실행되는 다른 파이썬 응용 프로그램들의 동작에 영향을 주지 않기 위해, 파이썬 배포 패키지들을 설치하거나 업그레이드하는 것을 가능하게 하는 격리된 실행 환경 입니다. 출처 : 파이썬 공식 용어집- 가상환경 |
+ 아 그래서 전에 파이썬 그 연습하는거 프로젝트마다 패키지 설치를 따로 했던 건가...?
- 패키지 설치 방법
파일 > 설정 > 프로젝트: '내가 생성한 프로젝트 이름' > Python 인터프리터 > +

requests 를 검색하여 패키지 설치

3-6 / 파이썬 패키지 사용해보기
Requests 라이브러리 사용해보기
import requests # requests 라이브러리 설치 필요
r = requests.get('http://spartacodingclub.shop/sparta_api/seoulair')
rjson = r.json()
rows = rjson['RealtimeCityAir']['row']
for row in rows :
gu_name = row['MSRSTE_NM']
gu_mise = row['IDEX_MVL']
if gu_mise > 40 :
print(gu_name)
3-7 / 웹스크래핑(크롤링) 기초
웹페이지를 크롤링 했을때 찾고자 하는 데이터를 쉽게 찾게 해주는 라이브러리 beautifulsoup
파일 > 설정 > 프로젝트: '내가 생성한 프로젝트 이름' > Python 인터프리터 > + > bs4 검색 > 설치
beautifulSoup을 사용하는 방법
크롬 브라우저 해당 페이지에서 찾고자 하는 데이터에서 마우스 오른쪽 클릭 > 검사
해당 태그에서 오른쪽 클릭 > copy > copy selector (해당 태그를 특정할 수 있는 선택자를 가져오는 행위)

1. 일단 기본 세팅과 하나의 데이터만 가져와보기
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'}
# 코드에서 콜을 날리는 거지만 마치 브라우저에서 콜을 날리는 것처럼 header 변수 대입해 아래 url뒤에 붙도록함
data = requests.get('https://movie.naver.com/movie/sdb/rank/rmovie.naver?sel=pnt&date=20210829',headers=headers)
soup = BeautifulSoup(data.text, 'html.parser')
# ^ 기본세팅
# 코딩시작 (파이썬 사용법이 아닌 BeautifulSoup 사용법임을 인지해야함)
# 우리가 위에서 가져온 선택자를 select 또는 select_one에서 사용)
title = soup.select_one('#old_content > table > tbody > tr:nth-child(2) > td.title > div > a')
# select_one 은 한가지만
print(1, title)
print(2, title.text)
print(3, title['href'])
# 1 <a href="/movie/bi/mi/basic.naver?code=186114" title="밥정">밥정</a>
# 2 밥정
# 3 /movie/bi/mi/basic.naver?code=186114
2. 기본세팅은 위와 동일 하고 여러가지 데이터 중에 필요 부분만 가져와 보기
##old_content > table > tbody > tr:nth-child(3) > td.title > div > a
##old_content > table > tbody > tr:nth-child(4) > td.title > div > a
#selector 비교시 동일한 부분을
movies = soup.select('#old_content > table > tbody > tr')
for movie in movies :
# 나머지 부분에서 동일한 부분을
a = movie.select_one('td.title > div > a')
if a is not None :
print(a.text)
3-8 / Quiz_웹스크래핑(크롤링) 연습
혼자 짜본 코드
순서에 관계없이 작동할거라 생각했는데 예외발생. 중간 중간 존재하는 NoneType을 처리하지 못해서 그런 것.
그러니 if를 먼저 위로 올린 다음 데이터 여부 확인하고 변수 대입하는 게 맞다
#기본세팅은 3-7과 동일
# 순위 #old_content > table > tbody > tr:nth-child(2) > td:nth-child(1) > img
# 이름 #old_content > table > tbody > tr:nth-child(2) > td.title > div > a
# 평점 #old_content > table > tbody > tr:nth-child(2) > td.point
#selector 비교시 동일한 부분을 + "라인 통채로 가져오는" < tr을 기준으로 가져오니까
movies = soup.select('#old_content > table > tbody > tr')
for movie in movies :
# "줄마나 바뀌는 부분을 제외한" 나머지에서 찾고자하는 부분을
rank = movie.select_one('td:nth-child(1) > img')['alt']
title = movie.select_one('td.title > div > a').text
point = movie.select_one('td.point').text
if title is not None :
print(rank, title, point)
# 결과 : TypeError: 'NoneType' object is not subscriptable
선생님 코드에 맞춰 수정
for movie in movies :
# "줄마나 바뀌는 부분을 제외한" 나머지에서 찾고자하는 부분을
a = movie.select_one('td.title > div > a')
if a is not None :
rank = movie.select_one('td:nth-child(1) > img')['alt']
title = a.text
point = movie.select_one('td.point').text
print(rank, title, point)
3-9 / DB 개괄
* DB는 잘 뽑아쓰기 위해서 사용
* DB에는 Index 라는 순서로 데이터들이 정렬
https://velog.io/@dev-joon/DB%EB%9E%80
DB란?
Database란 무엇인지 간략하게 알아보자
velog.io
* DB 종류
| RDBMS (SQL) | 칸有, 정형화 되어있어 빠르게 찾는것이 가능 하지만 정형화 되어있기 때문에 변화에 유연하게 대처하 기가 어려움, Oracle, MS-SQL, My-SQL등 |
| No-SQL | 칸無, Not only SQL의 약자, 그때그때 쌓이기 때문에 유연하게 대처가능, 때문에 초기 서비스, 초기 스 타트업에서 많이 채택, 대표적인 것이 mongoDB |
* DB의 실체
DB라고 해서 새로운 무언가라고 많이들 생각하지만 이것 또한 프로그램의 일종. 데이터를 잘 쌓고, 데이터를 잘 찾아오게하는 프로그램.
* DB를 컴퓨터가 아닌 클라우드 형태로 제공하는 곳을 사용하면 생기는 이점 (요즘 트렌드!)
유저가 몰리거나 DB를 백업해야 하거나 할 때 좋고 모니터링 하기가 아주 용이
3-10 / mongoDB 시작하기
최신 클라우드 서비스인 mongoDB Atlas 사용하기
mongoDB 가입하고 컴퓨터를 배정받아 DB 생성
근데 홈페이지가 짧은 사이에 좀 바뀌었나.. 강의 화면 나오는거랑 자꾸 다른 화면나와서 잠시 방황ㅎㅎ
3-11 / mongoDB 연결하기
mongoDB 사용하기 위해서는 pymongo와 dnspython 패키지가 필요
| pymongo | Python으로 Mongodb를 커넥션하여 사용할 때 가장 많이 사용하는 라이브러리 mongodb 기능을 많이 사용 할 수 있고(Index, Aggregate, ClientSession과 Transaction 등등) 문서도 잘 정리되어 있는 편 |
| dnspython | Python 이 구현 한 DNS 패키지. Domain Name System의 약자 도메인 이름 시스템은 사람이 읽을 수 있는 도메인 이름(예: www.amazon.com)을 머신이 읽을 수 있는 IP주소(예: 192.0.2.44)로 변환 |
파일 > 설정 > 프로젝트: '내가 생성한 프로젝트 이름' > Python 인터프리터 > + > 두개 서치해서 > 각각 설치
하고 mongoDB 사이트에서
connect > connect your application >

2번에 있는 url을 아래 코드 안에
from pymongo import MongoClient
client = MongoClient('여기에 URL 입력')
db = client.dbsparta
* DB 연결 기본세팅
# DB연결 기본세팅
from pymongo import MongoClient
client = MongoClient('mongodb+srv://아이디:비밀번호@cluster0.i7caukz.mongodb.net/Cluster0?retryWrites=true&w=majority')
db = client.dbsparta
# 코딩시작
doc ={
'name':'bob',
'age':27
}
db.users.insert_one(doc)
# db에 users라는 콜렉션 안에 데이터를 넣겠다
들어간 데이터는 아래 버튼 누르면 확인가능


3-12 / pymongo로 DB 조작하기
파이썬으로 DB 조작해보기
# insert
db.users.insert_one(데이터)
# select
# 조건비워두면 all / _id는 보고 싶지 않다는 조건
all_users = list(db.users.find({},{'_id':False}))
for user in all_users:
print(user)
# select
# 조건에 맞는 하나만 찾기
user = db.users.find_one({'name':'bobby'})
print(user['age'])
# update
# name이 bobby인 데이터에서 age를 19로 갱신
db.users.update_one({'name':'bobby'},{'$set':{'age':19}})
# delete
# users 콜렉션에서 name이 bobby인 데이터 삭제
db.users.delete_one({'name':'bobby'})
3-13 / 웹스크래핑 결과 저장하기
상단에 DB 기본 세팅 추가하고
for movie in movies :
# "줄마다 바뀌는 부분을 제외한" 나머지에서 찾고자하는 부분을
a = movie.select_one('td.title > div > a')
if a is not None :
rank = movie.select_one('td:nth-child(1) > img')['alt']
title = a.text
point = movie.select_one('td.point').text
print(rank, title, point)
#################################### 여기서부터
doc = {
'title': title,
'rank': rank,
'point': point
}
db.movies.insert_one(doc)
하면 movies 콜렉션에 데이터 삽입 성공
3-14 / Quiz_웹스크래핑 결과 이용하기
result = db.movies.find_one({'title':'가버나움'})
print(result['point'])
# 9.59
a_list = list(db.movies.find({'point':result['point']}))
for a in a_list :
print(a['title'])
# 그린 북
# 가버나움
db.movies.update_one({'title':'가버나움'},{'$set':{'point':'0'}})
3-15 / 숙제 설명
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')
music_list = soup.select('#body-content > div.newest-list > div > table > tbody > tr')
for music in music_list :
rank = music.select_one('td.number').text[0:2].strip()
title = music.select_one('td.info > a.title.ellipsis').text.strip()
ck = music.select_one('td.info > a.title.ellipsis > span')
if ck != None :
title = title.replace('19금','').strip()
artist = music.select_one('td.info > a.artist.ellipsis').text
print(rank, title, artist)
# 처음엔 무조건 19금 문자열을 발견하면 지우는 것으로 했으나
# 판별법으로써 별로 좋지 못한게 노래 제목 자체가 19금이 들어간 노래 경우 잘못 걸러질 수 있음을 깨달음.
# music.select_one('td.info > a.title.ellipsis') 안에서 19금 span태그를 찾아볼까 했는데 검색 안됨.
# 제목에 span이 들어가는 경우가 19금일 때 뿐인거 같으니
# select_one('td.info > a.title.ellipsis > span') 으로 도전 했는데 NoneType 익셉션 발생.
# 그럼 None으로 판별하여 맞으면 19금을 빈칸으로 대체하고 다시 strip()
# 좀 더 정확성을 올리긴 했는데 19금 판정 노래에 19금 제목이면 둘 다 지워지는 사태 발생 (이건 좀더 고민 해보는 걸로ㅠ )
좀 더 좋은 방법을 생각해보자 ㅠ
해결!!!
텍스트를 list화 해놓고 보니 \n 기준으로 여러줄로 나누어져 있고 곡명은 마지막 파트에 배정 되어있다
title = list(one.select_one('td.info > a.title.ellipsis').text)
그럼 나누고 list의 마지막 부분만 출력해서 하면 어떨까
이렇게 하니 따로 19금 판정을 내릴 필요없이 제목만 가져올수 있다!
아래 해결 코드!
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')
music_list = soup.select('#body-content > div.newest-list > div > table > tbody > tr')
for music in music_list :
rank = music.select_one('td.number').text[0:2].strip()
title = one.select_one('td.info > a.title.ellipsis').text.split('\n')[-1].strip()
artist = music.select_one('td.info > a.artist.ellipsis').text
print(rank, title, artist)
| + Tip |
| * 파이참 - 실행 단축키 Ctrl + Shift + F10 |
'Experience > 항해99' 카테고리의 다른 글
| 000 - 웹개발 종합반 5주차 (AWS) (1) | 2022.10.09 |
|---|---|
| 000 - 웹개발 종합반 4주차 (Flask, API) (2) | 2022.10.08 |
| 000 - 사전 스터디 팀원 분들과의 만남 (0) | 2022.10.06 |
| 000 - 웹개발 종합반 2주차 (JQuery, Ajax) (0) | 2022.10.06 |
| 000 - 웹개발 종합반 1주차 (HTML, CSS, Javascript) (0) | 2022.10.06 |
