3주차
- 파이썬 기초 문법 배우기
- 파이썬으로 웹에 있는 데이터를 긁어올 수 있는 크롤링 방법 알아보기
- pymongo를 통해 mongoDB를 제어하기
설치
- Python
- MongoDB (설치 custom 경로: Windows-data-db 폴더 내부에 설치 / Install mongoDB Compass 체크박스 해제)
- 시스템 환경변수 편집: 시스템환경변수편집 - 환경변수 - 시스템변수 - Path - 편집 - 새로만들기 - MongoDB를 설치한 폴더 경로(C:\data\db\bin) 추가 - 확인
- cmd - mongod - mongoDB 실행완료 - http://localhost:27017/ 검색
복습
⭐ 나홀로메모장에 openAPI 붙여보기
이번엔 우리가 만들었던 나홀로메모장에 들어가는 아티클들의 정보를 불러오는 openAPI를 이용해서 저장된 포스팅 불러오기를 만들어 볼 것이다.
API에 저장된 포스팅은 페이지가 로드 됐을 때 자동으로 붙어나올 수 있도록 한다.
⭐ 코드 스니펫
<script>
$(document).ready(function () { // 페이지 로드 완료 후 실행될 함수
$('#cards-box').empty(); // cards-box의 내용을 비우고
listing(); // listing() 함수를 실행
});
function listing() {
$.ajax({
type: "GET",
url: "http://spartacodingclub.shop/post",
data: {},
success: function (response) {
let rows = response['articles']
for (let i = 0; i < rows.length; i++) {
let comment = rows[i]['comment']
let desc = rows[i]['desc']
let image = rows[i]['image']
let title = rows[i]['title']
let url = rows[i]['url']
let temp_html = `<div class="card">
<img class="card-img-top"
src="${image}"
alt="Card image cap">
<div class="card-body">
<a href="${url}">${title}</a>
<p class="card-text">${desc}</p>
<p class="card-text text-blue">${comment}</p>
</div>
</div>`
$('#cards-box').append(temp_html)
}
}
})
}
</script>
1. 파이썬 시작하기
파이참 - File - New Project - Location: 파일을 생성할 폴더 지정
- Location> Location: 파일 경로 이름 마지막에 venv 가 붙어있어야한다.
- Base Interpreter: Python 3.8
- Create a main.py welcome script 체크 해제
- 생성된 venv 폴더(가상환경)는 절대 이동/수정/추가 를 하면 안된다!
⚡ 가상환경(virtual environment)
같은 시스템에서 실행되는 다른 파이썬 응용 프로그램들의 동작에 영향을 주지 않기 위해, 파이썬 배포 패키지들을 설치하거나 업그레이드 하는 것을 가능하게 하는 격리된 실행 환경. 프로젝트별 공구함 같은 개념이다.
2. 파이썬 기초
변수
a = 2
b = 3
print (a+b) // 5
문자열 더하기
first_name = 'Spa'
last_name = 'rta'
print(first_name+last_name) // Sparta
만약 문자열+숫자 하게되면 오류가 뜬다.
자료형
리스트
a_list = ['사과', '배', '감']
print(a_list)
딕셔너리
a_dict = {'name': 'bob', 'age': 2}
a_dict['height'] = 178
print(a_dict['age'])
리스트+딕셔너리
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)
함수
def sum(num1, num2):
return num1 + num2
result = sum(2,3)
print(result)
조건문
age = 25
if age > 20:
print('성인입니다')
else:
print('청소년입니다')
함수로 활용
def is_adult(age):
if age > 20:
print('성인입니다')
else:
print('청소년입니다')
is_adult(30)
is_adult(15)
반복문
fruits = ['사과','배','배','감','수박','귤','딸기','사과','배','수박']
count = 0
for fr in fruits:
if fr == '수박':
count += 1
print(count)
반복문을 리스트에서 실행할 경우 해당 리스트가 끝날때까지 반복을 실행하게 된다.
따라서 위에 반복문을 보면 fruits 리스트를 받아와서 fr 에 할당하고, 리스트의 원소를 하나하나씩 가져온다.
그래서 원소를 '수박'을 만나게 되면 count 값을 1 더해주므로 count 값을 출력하면 2가 나오게 된다.
2. 파이썬 패키지 사용해보기
패키지 설치
File - Settings - Project - Python Interpreter - (+) 추가 requests
⭐ 미센먼지 수치가 100 이상인 구만 찍어보자
import requests # requests 라이브러리 설치 필요
r = requests.get('http://openapi.seoul.go.kr:8088/6d4d776b466c656533356a4b4b5872/json/RealtimeCityAir/1/99')
rjson = r.json()
gus = rjson['RealtimeCityAir']['row']
for gu in gus:
gu_name= gu['MSRSTE_NM']
gu_mise= gu['IDEX_MVL']
if (gu_mise > 100):
print(gu_name, gu_mise)
3. 웹스크래핑(크롤링) 기초
내가 어느 웹페이지의 데이터를 얻고자 가져오는 것을 스크래핑이라고 한다. (주로 크롤링이라고 한다.)
*크롤링: 구글이나 네이버 등의 검색엔진이 내 사이트를 퍼가는 행위를 일컫는 말
크롤링 시 중요한 기술
- 코드 단에서 브라우저를 켜지 않고 요청하는 것 (requests)
- 요청돼서 가지고 온 데이터 중에 내가 원하는 정보를 잘 골라내는 것 (beautifulsoup)
크롤링 기본세팅
크롤링에 필요한 패키지: beautifulsoup4 설치 (bs4)
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.nhn?sel=pnt&date=20200303',headers=headers)
soup = BeautifulSoup(data.text, 'html.parser')
# 코딩 시작
select / select_one 사용법
- select : 가져온 여러개의 값을 리스트로 출력
- select_one : 하나의 값만 가져와서 출력
- 태그 안의 텍스트를 찍고 싶을 때: 태그.text
- 태그 안의 속성을 찍고 싶을 때: 태그['속성']
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://movie.naver.com/movie/sdb/rank/rmovie.nhn?sel=pnt&date=20200303',headers=headers)
# HTML을 BeautifulSoup이라는 라이브러리를 활용해 검색하기 용이한 상태로 만듦
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를 찍어본다.
print (a_tag.text)
beautifulsoup 내 select에 정의된 다른 방법
# 선택자를 사용하는 방법 (copy selector)
soup.select('태그명')
soup.select('.클래스명')
soup.select('#아이디명')
soup.select('상위태그명 > 하위태그명 > 하위태그명')
soup.select('상위태그명.클래스명 > 하위태그명.클래스명')
# 태그와 속성값으로 찾는 방법
soup.select('태그명[속성="값"]')
# 한 개만 가져오고 싶은 경우
soup.select_one('위와 동일')
[Quiz] 웹스크래핑(크롤링) 연습
⭐ 영화 순위, 제목, 별점 출력하기
⭐ 코드 스니펫
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.nhn?sel=pnt&date=20200303',headers=headers)
soup = BeautifulSoup(data.text, 'html.parser')
trs = soup.select('#old_content > table > tbody > tr')
for tr in trs:
a_tag = tr.select_one('td.title > div > a')
if a_tag is not None:
rank = tr.select_one('td:nth-child(1) > img')['alt']
title = a_tag.text
star = tr.select_one('td.point').text
print(rank, title, star)
4. DB
- mongoDB 설치 확인: 브라우저에 http://localhost:27017/ 검색
- Robo3T - create - connect (데이터베이스에 접속)
mongoDB는 데이터베이스이며 우리 눈에 보이지 않게 실행되고 있다.
Robo3T는 그런 데이터베이스를 시각화해서 눈으로 볼 수 있게 하는 프로그램이다.
데이터베이스(DB)
잘 분류되어 있는 정리된 데이터에서 가져다 쓰기 위해서 데이터베이스를 사용한다.
데이터 베이스에는 SQL과 NoSQL(Not only SQL)이 있다.
- SQL (RDBMS)
- 행/열의 생김새가 정해진 엑셀에 데이터를 저장하는 것과 유사하다. 데이터 50만 개가 적재된 상태에서, 갑자기 중간에 열을 하나 더하기는 어려울 것이다. 그러나, 정형화되어 있는 만큼, 데이터의 일관성이나 분석에 용이할 수 있다.
- ex) MS-SQL, My-SQL, Oracle
- No-SQL
- 딕셔너리 형태로 데이터를 저장해두는 DB이다. 고로 데이터 하나 하나 마다 같은 값들을 가질 필요가 없게 된다. 자유로운 형태의 데이터 적재에 유리한 대신, 일관성이 부족할 수 있다.
- ex) MongoDB
5. pymongo로 DB 조작하기
파이썬에서 mongoDB를 조작하기 위해서 pymongo라는 라이브러리를 이용한다.
위에서와 똑같이 라이브러리 pymongo 를 설치해주면 된다.
pymongo 기본 세팅
from pymongo import MongoClient #pymongo 를 사용하겠다
client = MongoClient('localhost', 27017) #내 컴퓨터에서 실행되고 있는 mongoDB에 접속
db = client.dbsparta #dbsparta 라고 하는 DB 이름으로 접속할 것이다. (없으면 생성)
# 코딩 시작
요약
# 저장 - 예시
doc = {'name':'bobby','age':21}
db.users.insert_one(doc)
# 한 개 찾기 - 예시
user = db.users.find_one({'name':'bobby'})
# 여러개 찾기 - 예시 ( _id 값은 제외하고 출력)
same_ages = list(db.users.find({'age':21},{'_id':False}))
# 바꾸기 - 예시
db.users.update_one({'name':'bobby'},{'$set':{'age':19}})
# 지우기 - 예시
db.users.delete_one({'name':'bobby'})
insert
doc = {'name':'bobby','age':21}
db.users.insert_one(doc) # db 안에 users라는 collection에 insert 해라
find
여러개 찾기
# 'age'가 21인 데이터를 찾아라. _id: False 는 id 값은 출력하지 않는다는 의미
same_ages = list(db.users.find({'age':21},{'_id':False}))
# 모든 데이터 딕셔너리를 가져와라 (빈 중괄호). 주로 쓰게 될 방법
same_ages = list(db.users.find({},{'_id':False}))
하나만 찾기
여러개 있어도 제일 위에 있는 것을 가져옴
user = db.users.find_one({'name':'bobby'})
update
# 이름이 'bobby' 인 것을 찾아서 age를 19로 바꿔라
db.users.update_one({'name':'bobby'},{'$set':{'age':19}})
# 이름이 'bobby' 인 것을 '모두' 찾아서 age를 19로 바꿔라 (한번에 다 바꾸는게 위험해서 잘 안씀)
db.users.update_many({'name':'bobby'},{'$set':{'age':19}})
delete
# 이름이 'bobby'인 것을 찾아서 삭제. (이것도 위험해서 잘 안씀)
db.users.delete_one({'name':'bobby'})
# 이름이 'bobby'인 것을 찾아서 '모두' 삭제. (이것도 위험해서 잘 안씀)
db.users.delete_many({'name':'bobby'})
6. 웹스크래핑 결과 저장하기
위에서 크롤링해온 영화 순위와 평점을 DB에 저장해보려고 한다.
import requests
from bs4 import BeautifulSoup
from pymongo import MongoClient # mongoDB 이용하기 위해 불러오기
client = MongoClient('localhost', 27017)
db = client.dbsparta
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=20200303',headers=headers)
soup = BeautifulSoup(data.text, 'html.parser')
trs = soup.select('#old_content > table > tbody > tr')
for tr in trs:
a_tag = tr.select_one('td.title > div > a')
if a_tag is not None:
rank = tr.select_one('td:nth-child(1) > img')['alt']
title = a_tag.text
star = tr.select_one('td.point').text
doc = { # 문서에 넣을 정보 분류
'rank': rank,
'title': title,
'star': star
}
db.movies.insert_one(doc) # 저장
[Quiz] 영화제목 '매트릭스'의 평점 가져오기
⭐ 코드 스니펫
from pymongo import MongoClient
client = MongoClient('localhost', 27017)
db = client.dbsparta
movie = db.movies.find_one({'title':'매트릭스'})
print(movie['star'])
[Quiz] '매트릭스'의 평점과 같은 평점의 영화제목들 가져오기
⭐ 코드 스니펫
from pymongo import MongoClient
client = MongoClient('localhost', 27017)
db = client.dbsparta
movie = db.movies.find_one({'title':'매트릭스'})
target_star = movie['star']
target_movies = list(db.movies.find({'star': target_star},{'_id':False}))
print(target_movies)
같은 평점의 영화제목들을 리스트 내 딕셔너리 형태로 가져오기 때문에 한눈에 알아보기 어려우므로 for 문을 이용해서 영화제목들만 가져올 수 있도록 했다.
for target in target_movies:
print(target['title'])
그러면 하나씩 출력해주기 때문에 알아보기 편리해진다.
[Quiz] 매트릭스 영화의 평점을 0으로 만들기
from pymongo import MongoClient
client = MongoClient('localhost', 27017)
db = client.dbsparta
db.movies.update_one({'title': '매트릭스'}, {'$set': {'star': 0}})