[스파르타_웹개발종합] 3주차_파이썬, 크롤링과 mongoDB

et Ji·2022년 10월 12일
0

TIL

목록 보기
3/40

학습일자 : 22.10.10 ~ 10.11

3.2 강 _ 2주차 리마인드

스파르타피디아 + OpenAPI

  • 페이지가 로딩되면, API에서 타이틀, 이미지, 설명, 코멘트, 별점 데이터 추출해서 웹페이지에 추가해주기
  • 로딩 후 바로 실행 코드
    • 로딩되면, listing 함수가 실행.

    • listing 함수 내부에서 a.jax로 데이터를 받아오기.

      
      $(document).ready(function(){
        listing();
      });
      
      function listing() {
      	console.log('화면 로딩 후 잘 실행되었습니다');
      }
  • 포인트 코드
    • 별점같은 경우, repeat 함수를 이용한다.

       `let star_image = '⭐'.repeat(star)`
      <script>
        $(document).ready(function () {
            listing();
        });
      
        function listing() {
            $('#cards-box').empty()
            // console.log('화면 로딩 후 잘 실행되었습니다');
            $.ajax({
                type: "GET",
                url: "http://spartacodingclub.shop/web/api/movie",
                data: {},
                success: function (response) {
                    let rows = response['movies']
                    // console.log(rows)
                    for (let i = 0; i < rows.length; i++) {
                        let title = rows[i]['title']
                        let desc = rows[i]['desc']
                        let image = rows[i]['image']
                        let star = rows[i]['star']
                        // ( 전에 별찍기 했던 것처럼 )미리 변수에 담아서 넣기.
                        let star_image = '⭐'.repeat(star)
                        let comment = rows[i]['comment']
      
                        // console.log(title, desc, image, star, comment)
                        let temp_html = `<div class="col">
                                            <div class="card">
                                                <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>${star_image}</p>
                                                    <p class="mycomment">${comment}</p>
                                                </div>
                                            </div>
                                        </div>`
                        $('#cards-box').append(temp_html)
                    }
                }
            })
        }
      
      </script>

3.3 강 _ 파이썬 시작하기

세팅

  • 파이썬 설치
  • 경로에 새 프로젝트 생성 (파이참 상단 메뉴바 - 파일 - 새프로젝트)
    • 생성 설정
      • location을 새로 만든 프로젝트로 설정
      • 기본 인터프리터가 Python38인지 체크
      • main.py 웰컴 스크립트 생성 체크 해제 후 생성
  • 파이썬 파일 생성 후 실행

3.4 -5 강 - 파이썬 기초공부 (1)(2)

1) 변수 & 기본연산

  • 자바스크립트에서처럼 변수 선언시 let, const 등의 예약어가 필요없다.
  • 코드
    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) 자료형

  • 숫자형 / 문자형 / 불린형
  • 코드
    # 숫자형
    a = 2
    b = 3
    
    print(a+b) ## 5
    
    # 문자형
    c = 'Ji'
    d = 'Hoesu'
    
    print(c+d) ## JiHoesu
    
    # 불린형
    ## True 또는 False -> "Boolean"형이 들어갈 수도 있다.
    is_number = True 
    
  • List 형 : 자바스크립트의 배열형과 동일
  • 코드
    # 리스트 생성 및 탐색 
    
    a_list = ['사과', '배', '감']
    
    print(a_list[2]) ## 감
    print(a_list[1]) ## 배
    
    # 리스트 추가 
    
    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 형 : 자바스크립트의 객체형과 동일
  • 코드
    # 딕셔너리형 생성 및 탐색 
    
    a_dict = {
        'name': 'bob',
        'age': 27,
    }
    
    print(a_dict['name'])
    
    # 리스트 추가 
    
    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}]
      
      ## peple[0]['name']의 값? 'bob'
      ## peple[1]['name']의 값? 'carry'
      
      # 추가
      
      person = {'name':'john','age':7}
      people.append(person)
      
      	## people의 값? [{'name':'bob','age':20},{'name':'carry','age':38},{'name':'john','age':7}]

3) 함수

  • 기본구조
    • def 함수이름(인자값) : 실행 코드
      • definition의 약자, { }없이 줄을 맞춰서 사용한다.
      • ‘ : ‘기호 뒤에는 다음에 실행될 코드가 작성된다.
      • 파이썬에서는 들여쓰기가 굉장히 중요하다.
  • 코드
    # 수학문제에서
    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
  • 코드 2
    def sum(a, b):
        print('더하자')
        return a + b
    
    result = sum(1, 2) 
    print(result)

4) 조건문

  • if / else 로 구성!
    • if 조건 : 실행코드
    • else : 실행코드
  • 코드
    def is_adult(age):
        if age > 20:
            print('성인입니다.')
        else:
            print('청소년입니다.')
    
    is_adult(15)
    is_adult(25)
  • 코드 2
    def oddeven(num):
    	## oddeven이라는 이름의 함수를 정의한다. num을 변수로 받는다.
    	if num % 2 == 0:
    		return True
    	else:
    		return False
    
    result = oddeven(20)
    
    	## result의 값? True

5) 반복문

  • 파이썬에서의 반복문은, 리스트의 요소들을 하나씩 꺼내쓰는 형태
    • 보통 단수 in 복수형 의 이름을 쓴다.
    • 반복문은 리스트(배열)와 거의 같이 쓰기 때문에
    • 파이썬의 반복문은 리스트와 같이 쓰도록 만들어져있다.
  • 코드
    ## 리스트 예제 
    
    fruits = ['사과','배','배','감','수박','귤','딸기','사과','배','수박']
    
    ### 배열 요소 하나씩 출력하기
    
    for fruit in fruits:
        print(fruit)
    
    ### 사과의 개수 세기.
    
    count = 0
    for aaa in fruits:
        if aaa == '사과':
            count += 1
    
    print(count)
    
    ## 딕셔너리 + 리스트 예제
    
    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:
        print(person['name'], person['age'])
    
    ### 20세 이상인 사람의 나이 출력 - 조건문 활용
    
    for person in people:
        # print(person)
        if person['age'] > 20:
            print(person['name'])
    
    ### 이름을 받으면, 나이를 리턴 - 조건문 활용
    
    def get_age(myname):
    	for person in people:
    		if person['name'] == myname:
    			return person['age']
    		return '해당하는 이름이 없습니다.'
    
    print(get_age('bob'))
    print(get_age('kay'))

3.6 강 _ 파이썬 패키지

💡용어설명

  • 크롤링 : 크롤링(crawling) 혹은 스크레이핑(scraping)은 웹 페이지를 그대로 가져와 데이터를 추출하는 행위. ※ 크롤링하는 소프트웨어를 크롤러라고 한다.
  • 패키지 : 크롤링을 하려면, 남이 만들어놓은 라이브러리를 사용해야 한다. 이것을 파이썬에서 패키지라 한다.

👉 패키지? 라이브러리?
Python 에서 패키지는 모듈(일종의 기능들 묶음)을 모아 놓은 단위이다. 이런 패키지 의 묶음을 라이브러리 라고 볼 수 있다. 지금 여기서는 외부 라이브러리를 사용하기 위해서 패키지를 설치한다.
즉, 여기서는 패키지 설치 = 외부 라이브러리 설치

  • 가상 환경(virtual environment) : 프로젝트 별로 패키지들을 담을 공구함. 라이브러리를 모아두는 곳. ※ 파이썬 프로젝트 생성시 venv 폴더가 바로 그것!

👉 정리하자면,
가상환경(virtual environment)
같은 시스템에서 실행되는 다른 파이썬 응용 프로그램들의 동작에 영향을 주지 않기 위해, 파이썬 배포 패키지들을 설치하거나 업그레이드하는 것을 가능하게 하는 격리된 실행 환경 입니다.

pip(python install package) 사용

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

  • requests 패키지 설치해보기

  • 파이참 - 상단 메뉴 - 파일 - project interpreter 화면에서 + 버튼

  • requests를 검색 - 패키지 설치


3.7 강 _ 패키지 사용해보기

Requests 라이브러리 사용해보기 + List/Dictionary/함수/If/For문 연습

  • requests 패키지 : 다양한 WEB HTTP 요청을 쉽게 다룰 수 있도록 도와주는 패키지이다. 한 눈에 봤을 때에도 어떤 기능인지 알 수 있게 직관적인 API를 제공한다.
  • requests 사용하기
    # requests 라이브러리 불러오기
    ## requests 라이브러리 설치 필요
    
    import requests 
    
    r = requests.get('url 주소')
    rjson = r.json()
  • 예제 코드 : 미세먼지가 60이하인 구 이름 가져오기
    # 데이터 가져오기
    ## 라이브러리마다 쓰는 방식이 다르므로, 다른 라이브러리의 경우 사이트에서 찾아서 볼 것.
    r = requests.get('http://spartacodingclub.shop/sparta_api/seoulair')
    rjson = r.json()
    
    print(rjson)
    
    ##
    rows = rjson['RealtimeCityAir']['row']
    
    for row in rows:
        gu_name = row['MSRSTE_NM']
        gu_mise = row['IDEX_MVL']
        # print(gu_name, gu_mise)
        if gu_mise < 60:
            print(gu_name)
    
    # print(rjson)

3.8 강 _ 웹스크래핑(크롤링) 기초

1) 웹스크래핑 해보기 - 네이버 영화 페이지

  • 준비 : 패키지 (beautifulsoup4) - bs4로 설치
    • beautifulsoup4는 원하는 태그를 쉽게 불러올 수 있는 HTML/XML parser인 패키지이다. 👉 requests가 아닌 BeautifulSoup를 사용하는 이유?
    • 크롤링 기본 세팅
      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')

👉 headers : headers는 우리가 코드에서 콜을 날리면, 마치 브라우저에서 콜을 날린 것처럼(사람인 것처럼) 해주려고 쓰는 것. - url만 바꿔서 사용하면 된다.

  • beautifulsoup 데이터 가져오기 방법

    👉가져오는 데이터가 리스트 형태일 경우, select_one()을 사용하면 오류가 난다.

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

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

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

        # 한 개만 가져오고 싶은 경우
        soup.select_one('위와 동일')
  • 크롬 개발자도구 사용해서 태그 가져오기
    - 항상 정확하지는 않을 수 있음.
    1. 원하는 부분에서 마우스 오른쪽 클릭 → 검사
    2. 원하는 태그에서 마우스 오른쪽 클릭
    3. Copy → Copy selector로 선택자를 복사할 수 있음

3.9 강 **Quiz웹스크래핑(크롤링) 연습**

1) 웹스크래핑 해보기 - 네이버 영화 페이지

  • 포인트 코드
    movies = soup.select('#old_content > table > tbody > tr')
    
    #  나의 풀이
     for movie in movies:
        name = movie.select_one('td.title > div > a')
         star = soup.select_one('td.point')
         rank = soup.select_one('td:nth-child(1) > img')
         # print(a)
         if name is not None:
             print(rank['alt'], name.text, star.text)
    
    # 강의 풀이
    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)

3.10 강 _ DB개괄

1) DB는 왜 쓰는 것일까?

  • 데이터가 정렬된 순서를 Index라고 한다.
  • Database는 이 순서들이 잘 정렬되어 있고, 이 순서로 나중에 찾게될 때 그것을 일일이 찾지 않아도 한 번에 잘 찾아지도록 만드는 데 사용 목적이 있다.

👉 Database 는 데이터를 나중에 잘 찾기위해 쓴다.

2) DB의 두 가지 종류

  • DB는 크게 두 가지 종류가 있다.

    • RDBMS(SQL)

      : 칸을 만들어두고 데이터를 채우는 형식 (엑셀 처럼)

      ex) MS-SQL, My-SQL 등

      • 장점

        • 정형화되어 있기 때문에, 예외적인 데이터(이상한)가 들어올 일이 없다.
        • 데이터의 일관성이나 분석에 용이하며, 찾을 때 좀더 빠르게 찾을 수 있다.
      • 단점

        • 중간에 열 등이 추가되는 식으로 양식이 바뀌면, 유연하게 대처하기가 어렵다.

          ex) 처음에 이름, 전화번호만 입력하다가 나중에 이메일, 주소 등을 더 추가하고자 할때

    • No-SQL(Not only SQL)

      ex) MongoDB

      : 정해진 칸이 없고, 데이터가 들어오는 순서대로 쌓는다.

      • 장점

        • 데이터가 들어오는 대로 쌓이기 때문에 변화에도 유연하게 대처하기가 쉽다.
        • 초기 스타트업이나 초기 서비스에서 많이 사용한다.
      • 단점

        • 자유로운 형태의 데이터 적재에 유리한 대신, 일관성이 부족할 수 있습니다.

3) DB의 실체에 관하여

  • 데이터를 잘 쌓고, 잘 가져오게 하는 프로그램.
  • 컴퓨터에도 설치할 수 있으나, 최근에는 클라우드 환경에서 제공하는 Database를 사용하는 추세이다.
    • 클라우드서비스는 유저가 몰리거나 / DB를 백업해야 하거나 / 모니터링 하기가 아주 용이하다

3.11 - 12 강. mongo DB 설치와 연결

mongo DB 클라우드 Atlas 연결

  • 준비 : 파이참에서 패키지 설치 (dnspython, pymongo)
  • mongoDB Atlas 화면에서 Connect your application 클릭
  • pymongo로 조작하기
    • pymongo 기본 코드
      from pymongo import MongoClient
      client = MongoClient('여기에 URL 입력')
      ## URL는 위 참고 화면에서 2번 'Add your conneciton string into your application code'
      db = client.dbsparta
  • 잘 연결됐는지 테스트 - 코드 저장 + 실행 후 - Cluster0의 Collections를 확인
    • 테스트 코드
      doc = {
          'name':'bob',
          'age':27
      }
      
      db.users.insert_one(doc)

3.13 강 _ pymongo로 DB조작하기

  • 저장 - db.collection.insert_one( )
    • 코드
      # '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})
  • 한개 찾기 - db.collection.find_one(query, projection, options)
    • 코드
      user = db.users.find_one({'name':'bobby'})
      ## 또는
      user = db.users.find_one({'name':'bobby'},{'_id':False})
      print(user)
      print(user['age'])
  • 여러 개 찾기 - list(db.collection.find(query, projection, options)
    • mongoDB에서 데이터를 가져올 때 자동으로 id값이 부여되어 보여지는데, {'_id':False} 를 두번째 매개변수로 전달하면, id를 제외하고 보여진다.
    • 코드
      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)
  • 수정하기 - db.collection.update_one(query, newvalues)

👉 주의 : $set을 붙이지 않으면, 바꾸려는 데이터 뿐 아니라 기존 데이터까지 모두 사라지게 된다.

- **코드**
    
    ```python
    db.users.update_one({'name':'bobby'},{'$set':{'age':19}})
    ```
    
  • 삭제하기 (거의 안씀) - db.collection.delete_one(query)
    • 코드
      db.users.delete_one({'name':'bobby'})
      
      user = db.users.find_one({'name':'bobby'})
      print(user)

3.14강 _ 웹스크래핑 결과 저장하기

insert 연습하기

  • 포인트 코드
    import requests
    from bs4 import BeautifulSoup
    
    **from pymongo import MongoClient
    client = MongoClient('mongodb+srv://test:sparta@cluster0.xuc2jrn.mongodb.net/Cluster0?retryWrites=true&w=majority')
    db = client.dbsparta**
    
    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)
    
            **doc = {
                'title': title,
                'rank': rank,
                'star': star
                }
            db.movies.insert_one(doc)**

👉 데이터를 insert로 불러오기전에, document 딕셔너리를 만들어 불러오기 할 것.


3.15 강 **Quiz웹스크래핑 결과 이용하기**

find, update 연습하기

  • (1) 네이버 영화 페이지 - 영화제목 '가버나움'의 평점을 가져오기
    • 포인트 코드
      ## 나의 풀이
      gover = db.movies.find_one({'title':'가버나움'},{'_id':False})
      
      print(gover)
      print(gover['star'])
  • (2) '가버나움'의 평점과 같은 평점의 영화 제목들을 가져오기
    • 포인트 코드
      ### 나의 풀이
      
      movies = list(db.movies.find({},{'_id':False}))
      
      goverStar = gover['star']
      print(goverStar)
      print(movies)
      
      for movie in movies:
          if movie['star'] == goverStar:
              print(movie['title'])
      
      ### 강의 풀이
      
      movie = db.movies.find_one({'title':'가버나움'})
      star = movie['star']
      
      all_movies = list(db.movies.find({'star': star},{'_id':False}))
      
      for m in all_movies:
          print(m['title'])
  • (3) '가버나움' 영화의 평점을 0으로 만들기
    • 포인트 코드
      ### 나의 풀이
      
      db.movies.update_one({'title': '가버나움'},{'$set':{'star':'0'}})

💡 배운 내용

  • 두번째 프로그래밍 언어로 파이썬을 배웠다. 들었던 것처럼 직관적이어서 빠르게 익힐 수 있을 것 같다.
  • 데이터베이스 개념
  • 크롤링한 데이터를 mongoDB 클라우드를 이용해서 저장하고, 다시 데이터 추출하기

⁉️ 어려웠던 내용

  • 듣어보기는는 했었지만, 실제로 그 뜻은 처음 알아본 용어들이 많아서 좀 어려웠다.
  • 크롤링하는 게 익숙하지 않아서, 아직까진 사용법을 봐가면서 써야한다.

❎ 한 번 더 공부할 내용

  • HTTP headers

🎯 문제와 해결


📗 출처

profile
codesign

0개의 댓글