[수업 목표]

  1. Flask 프레임워크를 활용해서 API를 만들 수 있다.
  2. '화성에 땅사기' API를 만들고 클라이언트에 연결한다.
  3. '스파르타피디아' API를 만들고 클라이언트와 연결한다.

수업에 앞서 먼저 이해하고 가야 할 부분 : 로컬 개발환경

로컬 개발환경이란 같은 컴퓨터에다 서버도 만들고, 요청도 하는 방식. 즉, 클라이언트 = 서버가 되는 것!

클라우드 서비스를 이용하면 아래와 같은 그림이 될 수 있다.

출처 : 스파르타코딩클럽

 

Flask 프레임워크 

  • 서버를 구동시켜주는 편한 코드 모음. 서버를 구동하려면 필요한 복잡한 일들을 쉽게 가져다 쓸 수 있다.
  • 파일 이름은 아무렇게나 해도 상관없지만, 통상적으로 flask 서버를 돌리는 파일은 app.py라고 이름 짓는다.
  • 지난 글에 올린 것처럼 환경설정 → python interpreter에서 검색 후 패키지 설치하면 준비 완료!

 

Flask 기초

① @app.route('/) 부분을 수정해서 URL을 나눌 수 있다. 단, 주의할 점은 url 별로 함수명이 같거나, route('/') 내의 주소가 같으면 안 됨.

from flask import Flask
app = Flask(__name__)

@app.route('/')
def home():
   return 'This is Home!'

@app.route('/mypage')
def mypage():  
   return 'This is My Page!'

if __name__ == '__main__':  
   app.run('0.0.0.0',port=5002,debug=True)

이렇게 한 후 오른쪽 마우스 클릭 → 실행 → 브라우저에서 localhost:5002/ 주소창으로 가면 웹페이지가 생성되는 것을 볼 수 있다.

 

② 기본 폴더구조

  • 프로젝트 폴더 안에 static 폴더 (이미지, css파일을 넣어둡니다), templates 폴더 (html 파일을 넣어둡니다), app.py 파일 이렇게 세 개를 만들어두고 시작

왼쪽 프로젝트 아래부분 참고!

 

  • index.html 파일을 templates 안에 만들어 준 다음 flask 내장 함수 render_template를 이용해 html 파일을 불러줄 수 있음
from flask import Flask, render_template //이 라인에서 프레임워크 임포트를 확인 할 수 있다
app = Flask(__name__)

## URL 별로 함수명이 같거나,
## route('/') 등의 주소가 같으면 안됩니다.

@app.route('/')
def home():
   return render_template('index.html')

if __name__ == '__main__':
   app.run('0.0.0.0', port=5002, debug=True)

③ GET, POST 요청 타입

클라이언트는 요청할 때 HTTP request method(요청 메소드)라는 방식을 통해 어떤 요청 종류인지 응답하는 서버 쪽에 정보를 알려준다.

 

[GET 요청 방식]  

  •  통상적으로 데이터 조회(Read)를 요청할 때 → 영화 목록 조회
  •  데이터 전달 : URL 뒤에 물음표를 붙여 key=value로 전달 → 예: google.com?q=북극곰
//GET 요청 API코드 app.py 파이썬파일에서 사용, 들여쓰기 주의하기

@app.route('/test', methods=['GET'])
def test_get():
   title_receive = request.args.get('title_give')
   print(title_receive)
   return jsonify({'result':'success', 'msg': '이 요청은 GET!'})

 

//GET 요청 확인 Ajax코드 - HTML파일에서 사용
$.ajax({
    type: "GET",
    url: "/test?title_give=봄날은간다",
    data: {},
    success: function(response){
       console.log(response)
    }
  })

 

[POST 요청 방식]

  •  통상적으로 데이터 생성(Create), 변경(Update), 삭제(Delete) 요청할 때 → 예) 회원가입, 회원 탈퇴, 비밀번호 수정
  •  데이터 전달 : 바로 보이지 않는 HTML body에 key:value 형태로 전달
//POST 요청 API코드 - 마찬가지고 app.py 파이썬 파일에서 사용, 들여쓰기 주의하기

@app.route('/test', methods=['POST'])
def test_post():
   title_receive = request.form['title_give']
   print(title_receive)
   return jsonify({'result':'success', 'msg': '이 요청은 POST!'})
//POST 요청 확인 Ajax코드

$.ajax({
    type: "POST",
    url: "/test",
    data: { title_give:'봄날은간다' },
    success: function(response){
       console.log(response)
    }
  })

 

[화성땅 공동구매] 연습

준비하기

  • 패키지 설치 : flask, pymongo, dnspython, certifi
  • app.py, static, templates ( → 안에 index.html 파일 만들기) 이 3가지 만들기
  • mongoDB Atlas 창 띄워두기

② POST 연습하기 ( 주문 저장 )

  • API 만들고 사용하기 - 이름, 주소, 평수 저장하기(Create → POST)
  • 서버부터 만들기 ( 필요한 정보인 name, address, size 정보를 받아서 저장해 준다)

[POST 아래 참조]클라이언트 만들기

  • 이어서 html 파일에 클라이언트 만들기

name, address, size 정보를 내보내 주는 것

  • 그리고 mongoDB Atlas에서 잘 들어갔는지 확인해주면 끝.

이렇게 잘 저장되어 있는 것을 확인했다면 성공 !

 

③ GET 연습하기 ( 주문 보여주기 )

  • API 만들고 사용하기 - 저장된 주문을 화면에 보여주기(Read → GET)
  • 서버부터 만들기 (받을 것 없이 orders에 주문정보를 담아서 내려주기만 하면 끝)

지난 번에 만들어 두었던 dbprac.py 파일에서 여러 리스트를 불러오는 함수를 복붙해 줬다.

  • 클라이언트 만들기 (응답을 잘 받아서 for 문으로 붙여주면 끝!)

 

  • 화면을 새로고침 했을 때, DB에 저장된 리뷰가 화면에 올바르게 나타나는지 확인하면 끝

[스파르타피디아]

※ 화성땅 공동구매와 겹치는 부분이 많기 때문에 추가적으로 필요한 부분만 정리

조각 기능 구현해보기

  •  API에서 수행해야 하는 작업 중 익숙하지 않은 것들은, 따로 python 파일을 만들어 실행해보고, 잘 되면 코드를 붙여 넣는 방식으로 하는 게 편하다. 

② meta 태그에 대해 알아보기

  • 메타 태그는, <head></head> 부분에 들어가는, 눈으로 보이는 것(body) 외에 사이트의 속성을 설명해주는 태그들입니다. 예) 구글 검색 시 표시될 설명문, 사이트 제목, 카톡 공유 시 표시 될 이미지 등
  • 그중 og:image / og:title / og:description 을 크롤링 할 예정
  • meta 태그 스크래핑 할 때는 select_one을 이용해 meta tag를 임시로 만들어 둔 meta_prac.py파일에 먼저 가져와 본다
og_image = soup.select_one('meta[property="og:image"]')
og_title = soup.select_one('meta[property="og:title"]')
og_description = soup.select_one('meta[property="og:description"]')

print(og_image)
print(og_title)
print(og_description)
  • 가져온 meta tag의 content를 가져와 app.py 필요한 부분에 붙여준다.
image = og_image['content']
title = og_title['content']
description = og_description['content']

print(image)
print(title)
print(description)

과제

  • 응원 남기기(POST): 정보 입력 후 '응원 남기기' 버튼 클릭 시 주문 목록에 추가
  • 응원 보기(GET): 페이지 로딩 후 하단 응원 목록이 자동으로 보이기

오늘의 과제 결과물

 


확실히 강의를 3번째 듣다 보니까 예전에 강의를 따라서 치던 코드를 이젠 과제할 때 직접 쳐볼 수 있게 되었다. POST형식과 GET형식의 유기적인 구조를 조금은 더 이해할 수 있게 된 것 같다. 물론 아직 완벽하진 않지만, 한 번 더 수강을 한다면 더 이해가 쉬울 것 같은 느낌 ! 처음부터 완전히 이해를 하기보다 일단 반복해보고 그 과정을 통해 서서히 이해하는 것이 도움이 되는 것 같다. 그리고 오늘 과제를 하면서 계속해서 오류가 떴는데, 알고 보니 comment 스펠링이 하나 틀려서 발생했던 버그였다. 

 

이젠 오류가 발생해도 오류 창의 메시지 첫 줄을 확인하는 습관이 생겼는데, 정확한 오류가 무엇인지는 몰라도 몇 번째 줄의 오류인지는 알 수 있어서 오류를 찾는 방법도 발전한 것 같다. 남들보다 느리지만 어제의 나보다 발전하고 있는 나를 칭찬하며 오늘 회고 끝. 

 

 

10월 초중반

 

 

 

 

 

전 직장 오피스뷰

 

 

 

대학에서 태국어와 중국어를 전공한 나의 첫 직장은 해외마케팅 부서였다. 그러나 매일같이 해야 하는 야근과 딱딱한 회사 분위기 그리고 무엇보다 마케팅이라는 직무에 흥미를 느끼지 못하고 이직을 결심한다. 좀 더 자유로운 분위기인 해외취업을 생각하게 된 계기였다.

 

그러다 친구의 추천으로 우연히 지원하게 된 에미레이트 항공 면접에 덜컥 붙어버렸다. 다양한 국적의 사람들을 만나고 수평적인 업무 환경에서 여행하듯 일했던 지난 4년은 내 인생에 가장 큰 선물과 같은 시기였다. 그러나 어느 순간 20대 후반이 되면서 쳇바퀴같이 돌고 있는 발전 없는 나의 커리어가 걱정되기 시작했고, 또 결혼과 같은 인생에서 내가 계획하고 있는 몇 가지의 것들이 걱정되기 시작했다.

 

나는 선택을 해야했다. 내가 좋아하는 여행을 보다 쉽게 할 수 있는 승무원이라는 직업과 해외생활이라는 내가 좋아하던 부분을 포기하기란 쉽지 않았다. 그러나 새로운 출발을 위해선 결단을 내려야 했다. 일을 하면서 한국에 있는 다른 직업을 모색하는 것은 힘들었다. 왜냐하면, 비교를 할수록 에미레이트 항공만 한 회사가 없었고, 고민이 반복되었기 때문이다. 나는 그냥 어떻게든 되겠지 라는 마음으로 올해 7월 말 계획 없이 한국에 들어왔다.

 

한국에 들어온 후, 정말 깊은 고민에 빠졌다. 원래는 그냥 아무 회사나 들어가서 경력을 쌓고 이직을 하자는 마음이었는데, 막상 일반 회사에 경영관련 사무직으로 들어가자니 내키지가 않았다. 하고 싶은 일이 없다 보니 인생의 길을 잃은 기분이었다. 일단 하고 싶은 게 없으니, 싫어하는 것을 배제하고 원하는 부분을 적어보자고 생각했다.

 

그리하여 만들어진 목록은

 

  1. 내가 계속해서 발전할 수 있는 일
  2. 결혼 출산 후에도 경력단절이 없는 일
  3. 수평적이고 자유로운 분위기에서 이루어지는 일
  4. 해외로 이직할 수 있는일 + 외국계 기업에서 할 수 있는 일
  5. 디지털노마드가 가능한 일

 

이렇게 다섯가지 부분이었다. 

 

이 모든 것이 가능한 직무는 일단 일반 사무직도 아니고(경력 단절 위험), 나는 보수적인 분위기를 못 견디기 때문에 공기업/공무원도 아니었고, 뭔가 기술을 요하는 일이라는 생각이 들었다. 그러다가 우연히 보게 된 부트캠프 광고를 보고 개발자라는 직무에 관심을 갖게 되었다.

 

사실 돌이켜 생각해보니, 내가 인턴으로 일했던 첫 직장도 IT 대기업인 NHN 이었고 (물론 그땐 마케팅 부서라 개발 분야엔 관심이 하나도 없었다), 전 남자 친구도 개발자는 아니지만 데이터 분석일을 해서 코딩을 하던 사람이었다. 이 분야는 나와는 너무 먼 거리에 있는 분야라 생각해서 한 번도 생각해보지 않았지만, 일단 도전해 보기로 했다. 물론 쉽지 않겠지만, 혹자는 이미 개발 분야는 레드오션이라고 하지만, 그래도 앞으로 인생을 살아가는데 어떤 방면으로든 도움이 될 거라 생각한다. 

 

다양한 백그라운드를 가진 사람들의 실력과 나를 비교하면 한없이 작아지기 때문에, 나는 그저 어제의 나와 오늘의 나를 비교하며 공부를 하려 한다. 10일 전 부트캠프를 시작하기 전의 나와 지금의 내가 다르 듯이 앞으로도 계속해서 조금씩 발전시키면 인생을 길게 보았을 때 그 끝에선 지금 나보다 훨씬 유능해 보이는 사람들과 비슷한 수준으로 같이 가고 있을 거라 믿는다.

 

나와 같은 고민을 하고 있을 누군가에게 가끔 이 곳에 적을 글들이 위로가 되길 바라며, 이 폴더를 만들었다. :) 

새로운 도전을 하는 모든 사람들을 응원하며! Getting out of your comfort zone = you're growing 잊지 말자! 

 

 

 

[수업 목표]

  1. 파이썬 기초 문법을 안다.
  2. 원하는 페이지를 크롤링할 수 있다.
  3. pymongo를 통해 mongoDB를 제어할 수 있다.

1) 파이썬이란 ?

(강의 회고를 하기 전에, 인터넷 검색을 통해 파이썬에 대한 설명을 좀 더 찾아 정리해 보았다.)

  • Python is a high-level, general-purpose programming language. Its design philosophy emphasizes code readability with the use of significant indentation. (Indentation = 들여쓰기)
  • 파이썬은 네덜란드 개발자 귀도 반 로섬(Guido van Rossum)이 만든 언어
  • 구글은 파이썬을 많이 사용하는 기업으로 알려져 있다. 구글 내부에서 사용하는 코드 리뷰 도구, ‘앱 엔진’ 같은 클라우드 제품 등이 파이썬을 이용해 만들어졌다.
  • 파이썬은 문법이 간결하고 표현 구조가 인간의 사고 체계와 닮아 있다. 이 덕분에 초보자도 쉽게 배울 수 있고 다양한 분야에 활용할 수 있다는 장점이 있다. (JS보다 직관적 !)
  • 반면 단점으로는 속도가 느리다는 평가도 있으며, 모바일 앱 개발 환경에서 사용하기 힘들다. 또한 컴파일 시 타입 검사가 이뤄지지 않아 개발자가 실수할 여지가 조금 더 많다거나 멀티코어를 활용하기 쉽지 않다는 지적도 있다. 
  • [출처 : wikipedia] , [출처 : 네이버 지식백과]

 

2) 파이썬 기초문법 

① 변수 & 기본 연산

a = 3      # 3을 a에 넣는다
b = a      # a를 b에 넣는다
a = a + 1  # a+1을 다시 a에 넣는다

num1 = a*b # a*b의 값을 num1이라는 변수에 넣는다
num2 = 99 # 99의 값을 num2이라는 변수에 넣는다

# 변수의 이름은 마음대로 지을 수 있음!
# 진짜 "마음대로" 짓는 게 좋을까? var1, var2 이렇게?

② 자료형

: 숫자, 문자형, 리스트 형 (Javascript의 배열형과 동일), Dictionary 형 (Javascript의 dictionary형과 동일), Dictionary 형과 List형의 조합형이 있다.

//숫자, 문자형
name = 'bob' # 변수에는 문자열이 들어갈 수도 있고,
num = 12 # 숫자가 들어갈 수도 있고,

is_number = True # True 또는 False -> "Boolean"형이 들어갈 수도 있습니다.

-------------------------------------------------------------------
//리스트 형 (Javascript의 배열형과 동일)
a_list = []
a_list.append(1)     # 리스트에 값을 넣는다
a_list.append([2,3]) # 리스트에 [2,3]이라는 리스트를 다시 넣는다

# a_list의 값은? [1,[2,3]]
# a_list[0]의 값은? 1
# a_list[1]의 값은? [2,3]
# a_list[1][0]의 값은? 2
-------------------------------------------------------------------
//Dictionary 형 (Javascript의 dictionary형과 동일)
a_dict = {}
a_dict = {'name':'bob','age':21}
a_dict['height'] = 178

# a_dict의 값은? {'name':'bob','age':21, 'height':178}
# a_dict['name']의 값은? 'bob'
# a_dict['age']의 값은? 21
# a_dict['height']의 값은? 178
------------------------------------------------------------------
//Dictionary 형과 List형의 조합
people = [{'name':'bob','age':20},{'name':'carry','age':38}]

# people[0]['name']의 값은? 'bob'
# people[1]['name']의 값은? 'carry'

person = {'name':'john','age':7}
people.append(person)

# people의 값은? [{'name':'bob','age':20},{'name':'carry','age':38},{'name':'john','age':7}]
# people[2]['name']의 값은? 'john'

 

③ 함수

# 수학문제에서
f(x) = 2*x+3
y = f(2)
y의 값은? 7

# 참고: 자바스크립트에서는
function f(x) {
	return 2*x+3
}

# 파이썬에서
def f(x):
	return 2*x+3

y = f(2)
y의 값은? 7

※ 자바스크립트에서 함수를 쓸 때 {}를 사용했다면, 파이썬은 들여 쓰기로 구분을 하기 때문에 들여 쓰기가 아주 중요하다! 

 

④ 조건문 (if / else로 구성)

def oddeven(num):  # oddeven이라는 이름의 함수를 정의한다. num을 변수로 받는다.
	if num % 2 == 0: # num을 2로 나눈 나머지가 0이면
		 return True   # True (참)을 반환한다.
	else:            # 아니면,
		 return False  # False (거짓)을 반환한다.

result = oddeven(20)
# result의 값은 무엇일까요? True

 

⑤ 반복문 (무조건 리스트와 함께 쓰임, JS와 가장 다른 부분!)

fruits = ['사과','배','배','감','수박','귤','딸기','사과','배','수박']

count = 0
for fruit in fruits:
	if fruit == '사과':
		count += 1

print(count)

# 사과의 갯수를 세어 보여줍니다.

 

3) 파이썬에서 라이브러리 사용하는 법

참고로 파이썬파일을 만들 때 생성되는 venv( = 가상 환경 virtual environment) 파일은 필요한 라이브러리를 모아두는 곳이다. 

이 남들이 만들어 놓은 라이브러리를 '패키지'라고 한다. 패키지 설치 방법은 다음과 같다. (패키지 설치 = 외부 라이브러리 설치)

 

빨간색 글씨 참조!

위는 파이썬을 통해 코드를 작성할 때 필요한 패키지들을 다운로드하는 방법이다. 빨간 글씨의 순서대로 실행해 주면 된다. 참고로 나는 맥북 프로 14를 사용하고 있는데 보안상의 문제 때문인지 항상 certifi라는 패키지를 추가로 설치해 주어야 다른 패키지들 import가 가능했다. 이번 강의에서는 requests, bs4(-> beautifulsoup4), pymonggo, dnspthon, certifi 패키지를 사용하였다. 아래 그림에서 가장 윗 윗 두줄을 참고하면 되겠다.

import requests # requests,bs4 라이브러리 설치 필요
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.naver?sel=pnt&date=20210829',headers=headers)

# HTML을 BeautifulSoup이라는 라이브러리를 활용해 검색하기 용이한 상태로 만듦
# soup이라는 변수에 "파싱 용이해진 html"이 담긴 상태가 됨
# 이제 코딩을 통해 필요한 부분을 추출하면 된다.
soup = BeautifulSoup(data.text, 'html.parser')

#############################
# (입맛에 맞게 코딩)
#############################

 

4) 웹 스크래핑(크롤링) 기초

※ 크롤링은 두 가지 작업이 필요하다

① 요청해서 html 가져오기 ( → requests 라이브러리로 구현)

② 그 안에서 필요한 정보 찾기 (타이틀, 이미지 ) → bs4 (BeautifulSoup) 라이브러리로 구현

③ headers 란?  우리가 코드에서 콜을 날릴때 마치 브라우저에서 콜을 날리는 처럼 하는것.

 

방법 ) 항상 정확하지는 않으나, 크롬 개발자 도구를 참고할 수 있다.

  • 원하는 부분에서 마우스 오른쪽 클릭 → 검사
  • 원하는 태그에서 마우스 오른쪽 클릭
  • Copy → Copy selector로 선택자를 복사할 수 있음

(예시)

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(3) > td.title > div > a
#old_content > table > tbody > tr:nth-child(4) > td.title > div > a

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:
        title = a.text
        rank = movie.select_one('td:nth-child(1) > img')['alt']
        star = movie.select_one('td.point').text
        print(rank, title, star)

※ 태그 안의 텍스트를 찍고 싶을 땐 → 태그.text  / 태그 안의 속성을 찍고 싶을 땐 → 태그['속성']

 

참고 ) beautifulsoup 내 select에 미리 정의된 다른 방법

# 선택자를 사용하는 방법 (copy selector)
soup.select('태그명')
soup.select('.클래스명')
soup.select('#아이디명')

soup.select('상위태그명 > 하위태그명 > 하위태그명')
soup.select('상위태그명.클래스명 > 하위태그명.클래스명')

# 태그와 속성값으로 찾는 방법
soup.select('태그명[속성="값"]')

# 한 개만 가져오고 싶은 경우
soup.select_one('위와 동일')

 

5) DB개괄

  • 자료를 필요할 때 쉽게 찾기 위해 사용하는 프로그램의 일종
  • 우리 눈에 보이진 않지만, 사실 DB에는 Index라는 순서로 데이터들이 정렬되어 있다.
  • 크게 두 가지 종류가 있다 ( SQL , No-SQL)

RDBMS(SQL) : 행/열의 생김새가 정해진 엑셀에 데이터를 저장하는 것과 유사. 정형화되어 있는 만큼, 데이터의 일관성이나 / 분석에 용이. 따라서 주로 대기업에서 많이 사용  ex) MS-SQL, My-SQL 등

 

No-SQL : 딕셔너리 형태로 데이터를 저장해두는 DB. 고로 데이터 하나하나마다 같은 값들을 가질 필요가 없다. 자유로운 형태의 데이터 적재에 유리한 대신, 일관성이 부족할 수 있다. 따라서 주로 스타트업에서 많이 사용  ex) MongoDB

  • 유저가 몰리거나 , DB를 백업해야 하거나, 모니터링 하기가 아주 용이하다는 이유로  요새는 Cloud 형태를 많이 사용! ex) mongoDB Atlas

 

6) mongoDB

  • mongoDB 클라우스 서비스를 이용하면 쉽게 데이터를 불러오고 정리할 수 있다. 사용법은 구글링 해보기! 나는 이미 설치와 개설이 끝났기 때문에 나에게 필요한 정보만 기록하려 한다. 

아래는 자주 사용하는 기본 코드! (필요할 때마다 복붙해서 사용하면 된다.)

from pymongo import MongoClient
import certifi

ca = certifi.where()
client = MongoClient('mongodb+srv://test:sparta@cluster0.sx4vg7k.mongodb.net/?retryWrites=true&w=majority',tlsCAFile=ca)
db = client.dbsparta


# 저장 - 예시
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}))

# 바꾸기 - 예시
db.users.update_one({'name':'bobby'},{'$set':{'age':19}})

# 지우기 - 예시
db.users.delete_one({'name':'bobby'})

예시)

import requests
from bs4 import BeautifulSoup

from pymongo import MongoClient
client = MongoClient('mongodb+srv://test:sparta@cluster0.55vah.mongodb.net/Cluster0?retryWrites=true&w=majority')
db = client.dbsparta

# 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.naver?sel=pnt&date=20210829',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:
        rank = movie.select_one('td:nth-child(1) > img')['alt'] # img 태그의 alt 속성값을 가져오기
        title = a_tag.text                                      # a 태그 사이의 텍스트를 가져오기
        star = movie.select_one('td.point').text                # td 태그 사이의 텍스트를 가져오기
        doc = {
            'rank': rank,
            'title': title,
            'star': star
        }
        db.movies.insert_one(doc)

위 과정을 거치고 실행을 시키면 mongoDB의 movies 폴더에 크롤링한 데이터가 들어가 있음을 확인할 수 있다. 

 


스파르타코딩클럽의 웹 개발 종합반은 개괄적인 내용을 다룬 강의이기 때문에 추가로 유튜브 채널 <생활코딩>에서 파이썬 강의를 들어보았다. 아직 극 초급단계인 내가 강의를 통해 이해한 포인트를 정리해보자면,

 

1. 파이썬은 프로그래밍 언어의 하나이다.

2. 자바스크립트와 다르게 들여 쓰기를 통해 함수를 구분하기 때문에 들여쓰기를 유의해야 한다.

3. 필요한 기능은 구글링을 통해 검색하여 사용한다. ex). text [0:2],. strip() 

4. 매번 프로그래밍에 필요한 패키지들을 라이브러리에서 import 한 후 사용해야 한다.

5. 클라우드와 연결하게 되면 Open API에서 실시간으로 업데이트되는 데이터를 이용하여 필요한 코드를 작성하고 필요한 결과를 효율적으로 찾아낼 수 있다.

 

여기까지가 오늘의 이해인데, 잘하고 있는지는 모르겠다. 앞으로 실전 연습이나 프로젝트를 만들면서 지금의 추상적인 개념들을 구체화할 수 있을 것 같다. 모든 비전공자 코린이들 화잇팅!! 

 

 

[수업 목표]

  1. Javascript 문법에 익숙해진다.
  2. jQuery로 간단한 HTML을 조작할 수 있다.
  3. Ajax로 서버 API(약속)에 데이터를 주고, 결과를 받아온다.

Javascript

  • 우리가 매일 접속하는 웹사이트는 크게 3가지 요소로 구성된다. ‘HTML(Hyper Text Markup Language)’, CSS(Cascading Style Sheets)’, ‘자바스크립트(Javascript)’다. 
  • HTML은 웹페이지의 큰 뼈대를 제공하고, CSS는 색깔이나 글씨체와 같은 디자인 요소를 관리한다.
  • 자바스크립트는 크로스 플랫폼(cross platform), 객체지향 스크립트 언어로 웹페이지의 동작을 담당한다
  • 자바스크립트는 컴파일 과정이 없기 때문에 다른 언어와 비교했을 때 빠른 시간 안에 스크립트 코드를 작성할 수 있게 도와준다. 기존 C나 자바 언어와 달리 굉장히 단순한 구조와 원칙을 가지고 있기 때문에 초보 개발자들이 쉽게 배우고 이해할 수 있다.
  • 단점은 성능이나 보안 측면이다. 일단 내부에서 제공되는 기능이 제한적이고, 관련된 개발도구도 적은 편이다. 또한 자바스크립트는 HTML 소스코드에 함께 작성되면서 소스코드가 외부로 공개되는데, 이 과정에서 보안 취약점이 발생할 수 있다.

                                         출처 : [네이버 지식백과] 자바스크립트 [Javascript] - 웹을 풍부하게 만들어주는 작고 가벼운 언어 (용어로 보는 IT, 이지현)

 

1) jQuery 란?

  • HTML의 요소들을 조작하는, 편리한 Javascript를 미리 작성해둔 라이브러리. (JS보다 직관적)
  • jQuery는 전문 개발자들이 짜둔 미리 작성된 Javascript 코드 (그렇게 때문에, 쓰기 전에 "임포트" 필요)
  • https://www.w3schools.com/jquery/jquery_get_started.asp (임포트 하는 법 링크 참고하기)

임포트 하는 법 : <head> 와 </head> 사이에 아래를 넣으면 끝!

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>

 

  • css와 마찬가지로, jQuery를 쓸 때에도 "가리켜야" → 조작할 수 있다. css에서는 선택자로 class="..."를 사용했다면 jQuery에서는 id="..." 값을 통해 특정 버튼/인풋박스/div/.. 등을 가리킨다.

 

자주쓰는 jQuery

// 크롬 개발자도구 콘솔창에서 쳐보기
// id 값이 url인 곳을 가리키고, val()로 값을 가져온다.
$('#url').val();
// 입력할때는?
$('#url').val('이렇게 하면 입력이 가능하지만!');

// id 값이 post-box인 곳을 가리키고, hide()로 안보이게 한다.
$('#post-box').hide();
// show()로 보이게 한다.
$('#post-box').show();

// let temp_html = `` 주의: 홑따옴표(')가 아닌 backtick(`)으로 감싸야 합니다.
// 숫자 1번 키 왼쪽의 버튼을 누르면 backtick(`)이 입력됩니다.
// backtick을 사용하면 문자 중간에 Javascript 변수를 삽입할 수 있습니다.
let title = '영화 제목이 들어갑니다';

let temp_html = `<div class="col">
				            <div class="card h-100">
				                <img src="https://movie-phinf.pstatic.net/20210728_221/1627440327667GyoYj_JPEG/movie_image.jpg"
				                     class="card-img-top" alt="...">
				                <div class="card-body">
				                    <h5 class="card-title">${title}</h5>
				                    <p class="card-text">여기에 영화에 대한 설명이 들어갑니다.</p>
				                    <p>⭐⭐⭐</p>
				                    <p class="mycomment">나의 한줄 평을 씁니다</p>
				                </div>
				            </div>
				        </div>`;
$('#cards-box').append(temp_html);

let ...=$('#...').val() 로 변수를 정해주고, 

그것을 다시 let temp_html=`` 로 받아

$('#....').append(temp_html)로 연결시키는 과정을 기억하자!

 

2) 서버-클라이언트 통신 이해하기

① 서버→클라이언트: "JSON"을 이해하기

  • JSON은 쉽게 말해 데이터를 주는 규칙 
  • JSON은, Key:Value로 이루어져 있다. 자료형 Dictionary와 유사

위 예제에서는 RealtimeCityAir라는 키 값에 딕셔너리 형 value가 들어가있고, 그 안에 row라는 키 값에는 리스트형 value가 들어가있다.

 

② 클라이언트→서버: GET 요청 이해하기

  • API는 은행 창구와 같은 것! 같은 예금 창구에서도 개인 고객이냐 기업 고객이냐에 따라 가져와야 하는 것과 처리해주는 것이 다른 것처럼, 클라이언트가 요청 할 때에도, "타입"이라는 것이 존재
  • GET → 통상적으로 데이터 조회(Read)를 요청할 때 예) 영화 목록 조회
  • POST → 통상적으로 데이터 생성(Create), 변경(Update), 삭제(Delete) 요청 할 때 예) 회원가입, 회원탈퇴, 비밀번호 수정

API이해를 돕기위한 추가 자료 - 출처 : 스파르타코딩클럽

 

GET 방식으로 데이터를 전달하는 방법

https://movie.naver.com/movie/bi/mi/basic.nhn?code=161967

위 주소는 크게 두 부분으로 쪼개집니다. 바로 "?"가 쪼개지는 지점인데요.
"?" 기준으로 앞부분이 <서버 주소>, 뒷부분이 [영화 번호] 입니다.

* 서버 주소: https://movie.naver.com/movie/bi/mi/basic.nhn
* 영화 정보: code=161967


여기서 잠깐, 그럼 code라는 이름으로 영화번호를 주자!는 것은
누가 정하는 것일까요?

→ 네, 바로 프론트엔드 개발자와 백엔드 개발자가 미리 정해둔 약속입니다.

프론트엔드: "code라는 이름으로 영화번호를 주면 될까요?"
백엔드: "네 그렇게 하시죠. 그럼 code로 영화번호가 들어온다고 생각하고 코딩하고 있을게요"

 

3) Ajax

  • Asynchronous Javascript And Xml(비동기식 자바스크립트와 xml)의 약자
  • 자바스크립트를 이용해 서버와 브라우저가 비동기 방식으로 데이터를 교환할 수 있는 통신 기능
  • 비동기 방식은 웹페이지를 리로드하지 않고 데이터를 불러오는 방식이며 Ajax를 통해서 서버에 요청을 한 후 멈추어 있는 것이 아니라 그 프로그램은 계속 돌아간다는 의미를 내포
  • 브라우저가 가지고있는 XMLHttpRequest 객체를 이용해서 전체 페이지를 새로 고치지 않고도 페이지의 일부만을 위한 데이터를 로드하는 기법
  • Ajax는 jQuery를 임포트한 페이지에서만 동작 가능

Ajax 기본 골격 + 해설

 

$.ajax({
  type: "GET", // GET 방식으로 요청한다.
  url: "http://spartacodingclub.shop/sparta_api/seoulair",
  data: {}, // 요청하면서 함께 줄 데이터 (GET 요청시엔 비워두세요)
  success: function(response){ // 서버에서 준 결과를 response라는 변수에 담음
    console.log(response) // 서버에서 준 결과를 이용해서 나머지 코드를 작성
  }
})

GET 요청은, url뒤에 아래와 같이 붙여서 데이터를 가져간다. http://naver.com?param=value¶m2=value2

POST 요청은, data : {} 에 넣어서 데이터를 가져간다. data: { param: 'value', param2: 'value2' }

 

  • 사실, 아직 이해가 완전히 되지는 않기 때문에 오늘 풀었던 예제를 통해 형식을 그냥 외워보려 한다.
    <style type="text/css">
        div.question-box {
            margin: 10px 0 20px 0;
        }
        .bad {
            color: red;
            font-weight: bold;
        }
    </style>

    <script>
        function q1() {
            // 여기에 코드를 입력하세요
            $('#names-q1').empty();
            $.ajax({
                type: "GET",
                url: "http://spartacodingclub.shop/sparta_api/seoulair",
                data: {},
                success: function (response) {
                    let rows = response["RealtimeCityAir"]["row"];
                    for (let i = 0; i < rows.length; i++) {
                        let gu_name = rows[i]['MSRSTE_NM'];
                        let gu_mise = rows[i]['IDEX_MVL'];

                        let temp_html = ''

                        if (gu_mise > 70) {
                            temp_html = `<li class="bad">${gu_name} : ${gu_mise}</li>`
                        } else {
                            temp_html = `<li>${gu_name} : ${gu_mise}</li>`
                        }
                        
                        $('#names-q1').append(temp_html);
                    }
                }
            })
        }
    </script>

let rows 를 통해 변수를 설정해주고, for문으로 리스트를 돌려주고, temp_html을 이용하여 변수갑을 브라우저에 찍어준다. 그리고 if 문의 색깔은 class="bad"라는 값을 다시 지정해 위의 <sytle>에 .bad 부분을 추가해 준다. 

 

※ tip : 이미지 바꾸기  $("#아이디값").attr("src", 이미지URL)

           텍스트 바꾸기  $("#아이디값").text("바꾸고 싶은 텍스트")

 

 


처음 보는 용어들에 정신이 어질어질 어렵지만, 반복된 연습을 통해 익숙해 질 거란 느낌이 팍 들었다 ! 일단 오늘 이해한 부분은, jQuery를 통해 보다 간결한 코드로 자바스크립트를 구현할 수 있다는 점과 서버와 클라이언트가 JSON형식의 데이터를 주고 받을때 [GET], [POST] 이 두가지 요청 방식이 있다는 점.  

 

오늘 배운 내용에 도움이 될 만한 블로그 글을 발견하여 아래에 링크를 남겨본다. 

https://velog.io/@surim014/AJAX%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%B8%EA%B0%80

 

AJAX란 무엇인가?

AJAX (Asynchronous Javascript And XML) AJAX란, JavaScript의 라이브러리중 하나이며 Asynchronous Javascript And Xml(비동기식 자바스크립트와 xml)의 약자이다. 브라우저가 가지고있는 XMLHttpRequ

velog.io


4회 수강 후 여전히 부족한 부분 정리 : 1. 오타에 유의하자 (특히 중괄호), 2. 코드를 간결히 할 수 있는 방법을 생각해보자.

 

<2-5 강의 퀴즈 부분> 

 

1 번 문제

오늘은 그래도 내가 직접 코드를 작성해 봤다. 1번은 무난하게 패스 !

 

2번 문제

2번을 푸는데 좀 시간이 걸렸지만, 이번에도 혼자 코드 작성에 성공 ! 중괄호 하나가 빠져서 이 문제때문에 오류를 찾느라 고생했다. 아, 참고로 네번째줄 alert안에 '.val()' 빼줘야 정답이다.

 

3번 문제

내가 작성한 코드
정답 코드 (훨씬 간결하다.)

 

 

과제 코드 검사

내가 작성한 코드
정답 코드 (이것도 훨씬 간결.)

+ Recent posts