[웹개발 종합반] 3주차

Ariul·2022년 7월 4일
0

  • 이 글은 웹개발 종합반 강의를 수강하고 공부한 내용을 정리하는 용도로 작성되었습니다.
  • 추가학습이 필요한 부분은 ❓이렇게 표시하고 학습 이후 글을 업로드 합니다.

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

Python 기초문법

1. 변수 & 기본연산

a = 3 # 3을 a에 넣는다
b = a # a를 b에 넣는다

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

2. 자료형

  • 숫자, 문자형

    name = 'bob' # 변수에는 문자열이 들어갈 수도 있고,
    num = 12 # 숫자가 들어갈 수도 있고,
    is_number = True # True 또는 False -> "Boolean"형이 들어갈 수도 있습니다.
    #########
    # 그리고 List, Dictionary 도 들어갈 수도 있죠. 
  • 리스트 형 (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'

3. 함수

  • 함수의 정의 - 이름은 마음대로 정할 수 있음!

    # 수학문제에서
    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
  • 함수의 응용

    def sum_all(a,b,c):
        return a+b+c
    
    def mul(a,b):
        return a*b
    
    result = sum_all(1,2,3) + mul(10,10)

4. 조건문

  • if / else 로 구성!

    def oddeven(num): # oddeven이라는 이름의 함수를 정의한다. num을 변수로 받는다.
        if num % 2 == 0: # num을 2로 나눈 나머지가 0이면
            return True # True (참)을 반환한다.
        else: # 아니면,
            return False # False (거짓)을 반환한다.
    result = oddeven(20)
    def is_adult(age):
        if age > 20:
            print('성인입니다') # 조건이 참이면 성인입니다를 출력
        else:
            print('청소년이에요') # 조건이 거짓이면 청소년이에요를 출력
    is_adult(30)

5. 반복문

👉 파이썬에서의 반복문은, 리스트의 요소들을 하나씩 꺼내 쓰는 형태이다.
  • 즉, 무조건 리스트와 함께 쓰인다!

    fruits = ['사과','배','감','귤']
    
    for fruit in fruits:
        print(fruit)
    # 사과, 배, 감, 귤 하나씩 꺼내어 찍힙니다.
  • 과일 개수 세기 함수

    fruits = ['사과','배','배','감','수박','귤','딸기','사과','배','수박']
    
    count = 0
    for fruit in fruits:
        if fruit == '사과':
            count += 1
    
    print(count)
    # 사과의 갯수를 세어 보여줍니다.
    def count_fruits(target):
        count = 0
        for fruit in fruits:
            if fruit == target:
                count += 1
        return count
    
    subak_count = count_fruits('수박')
    print(subak_count) #수박의 갯수
    
    gam_count = count_fruits('감')
    print(gam_count) #감의 갯수

파이썬 패키지

👉 Python 에서 패키지는 모듈(일종의 기능들 묶음)을 모아 놓은 단위

  1. 가상 환경(virtuaㅣ environment, venv)

    • 프로젝트별로 패키지들을 담을 공구함
    • 같은 시스템에서 실행되는 다른 파이썬 응용 프로그램들의 동작에 영향을 주지 않기 위해, 파이썬 배포 패키지들을 설치하거나 업그레이드하는 것을 가능하게 하는 격리된 실행 환경
  2. pip(python install package)

    • 앱을 설치할 때 앱스토어/플레이스토어를 가듯이, 새로운 프로젝트의 라이브러리를 가상환경(공구함)에 설치하려면 pip 를 이용

    • 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 < 60:
              print(gu_name)

웹스크래핑(크롤링)

1) 웹스크래핑 해보기 (영화 제목)

  • 패키지 추가 설치하기(beautifulsoup4)

  • 크롤링 기본 세팅

    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](https://movie.naver.com/movie/sdb/rank/rmovie.naver?sel=pnt&date=20210829)',headers=headers)
    
    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://movie.naver.com/movie/sdb/rank/rmovie.naver?sel=pnt&date=20210829',headers=headers)
    
    # HTML을 BeautifulSoup이라는 라이브러리를 활용해 검색하기 용이한 상태로 만듦
    # soup이라는 변수에 "파싱 용이해진 html"이 담긴 상태가 됨
    # 이제 코딩을 통해 필요한 부분을 추출하면 된다.
    soup = BeautifulSoup(data.text, 'html.parser')
    
    #############################
    # (입맛에 맞게 코딩)
    #############################
  • 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.naver?sel=pnt&date=20210829',headers=headers)
    
     # HTML을 BeautifulSoup이라는 라이브러리를 활용해 검색하기 용이한 상태로 만듦
     soup = BeautifulSoup(data.text, 'html.parser')
    
     #old_content > table > tbody > tr:nth-child(2) > td.title > div > a
     #old_content > table > tbody > tr:nth-child(3) > td.title > div > a
    
     # 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('위와 동일')
  • 항상 정확하지는 않으나, 크롬 개발자도구를 참고할 수도 있다.
    1. 원하는 부분에서 마우스 오른쪽 클릭 → 검사
    2. 원하는 태그에서 마우스 오른쪽 클릭
    3. Copy → Copy selector로 선택자를 복사할 수 있음

DataBase

1) ❓데이터베이스 쓰는 이유

⇒ 잘 찾기 위해서! DB에는 Index라는 순서로 데이터들이 정렬되어 있다

2) DB의 두 가지 종류
❓ SQL, No-SQL

👉 RDBMS(SQL)/열의 생김새가 정해진 엑셀에 데이터를 저장하는 것과 유사함. 데이터 50만 개가 적재된 상태에서, 갑자기 중간에 열을 하나 더하기는 어려울 것이다. 그러나, 정형화되어 있는 만큼, 데이터의 일관성이나 / 분석에 용이할 수 있다.
ex) MS-SQL, My-SQL 등
👉 No-SQL
딕셔너리 형태로 데이터를 저장해두는 DB이다. 고로 데이터 하나 하나 마다 같은 값들을 가질 필요가 없다. 자유로운 형태의 데이터 적재에 유리한 대신, 일관성이 부족할 수 있다.
ex) MongoDB

3) 요즘 트렌드는 Cloud 형태의 DataBase

⇒ 유저가 몰리거나 / DB를 백업해야 하거나 / 모니터링 하기가 아주 용이하기 때문

mongoDB Atlas

mongoDB

  • mongoDB - Atlas 연결하기

    👉 pymongo 라이브러리의 역할
    예를 들어, MS Excel를 파이썬으로 조작하려면, 특별한 라이브러리가 필요할 것이다.
    마찬가지로, mongoDB 라는 프로그램을 조작하려면, 특별한 라이브러리, pymongo가 필요하다!
  1. 패키지 설치하기
    pymongo, dnspython

  2. pymongo로 조작하기

    • pymongo 기본 코드
    <from pymongo import MongoClient
    client = MongoClient('여기에 URL 입력')
    db = client.dbsparta
    • DB연결하기 & 데이터 넣기
    <# 'users'라는 collection에 {'name':'bobby','age':21}를 넣습니다.
    db.users.insert_one({'name':'bobby','age':21})
    db.users.insert_one({'name':'kay','age':27})
    db.users.insert_one({'name':'john','age':30})
    • 모든 결과 값을 보기
    <# 모든 데이터 뽑아보기
    all_users = list(db.users.find({},{'_id':False}))
    
    print(all_users[0]) # 0번째 결과값을 보기
    print(all_users[0]['name']) # 0번째 결과값의 'name'을 보기
    
    for user in all_users: # 반복문을 돌며 모든 결과값을 보기
        print(user)
    • 특정 결과 값을 뽑아 보기
    user = db.users.find_one({'name':'bobby'})
        print(user)
    • 수정하기
    # 오타가 많으니 이 줄을 복사해서 씁시다!
    db.users.update_one({'name':'bobby'},{'$set':{'age':19}})
    
    user = db.users.find_one({'name':'bobby'})
    print(user)
    • 삭제하기 (거의 안 씀)
    db.users.delete_one({'name':'bobby'})
    
    user = db.users.find_one({'name':'bobby'})
    print(user)
    • 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}))
    
    # 바꾸기 - 예시
    db.users.update_one({'name':'bobby'},{'$set':{'age':19}})
    
    # 지우기 - 예시
    db.users.delete_one({'name':'bobby'})

웹스크래핑 결과 저장하기

  • insert - 웹스크래핑 결과를 DB에 저장하기

    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
    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)
profile
정성과 진심을 담아 흔적을 기록하자💡

0개의 댓글