ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [WEB] 웹 스크래핑, mongoDB
    Web 2022. 3. 7. 08:31

    스파르타 코딩클럽 웹개발종합반 3주차

     

    오늘은 파이썬 문법을 연습하고 라이브러리를 활용하여 네이버 영화목록을 가져와보았다.

    또한, 데이터베이스, mongoDB를 다루어보았다.

     

    배우기전에 2주차 복습부터! (API 이용)

    API이용해서 내가 만들어놓은 영화목록 카드에 붙이기

    //로딩 후 바로실행
    $(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']
    
                //출력 확인용
                //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 comment = rows[i]['comment']
    
                    //반복되서 나오게 하는 javascript 내장함수 사용
                    let star_image = '⭐'.repeat(star)
    
                    //출력확인용
                    //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)
                }
            }
        })
    }

    파이썬 문법 기초공부

     

    # 변수정의
    a = 'minkyung'
    b = 'kim'
    
    print(a+b)

    결과 

    minkyungkim

    # 리스트
    a_list = ['사과', '배', '감']
    
    print(a_list[1])
    
    a_list.append('수박')
    
    print(a_list)

    결과

    ['사과', '배', '감', '수박']

    # 딕셔너리
    a_dict = {'name' : 'bob', 'age' : 24}
    
    print(a_dict['name'])

    결과

    bob

    # 함수
    def sum(a,b):
        print('더하자!')
        return a+b
    
    result = sum(1,2)
    print(result)

    결과

    더하자!

    3

    # 조건문
    def is_adult(age):
        if age >20:
            print('성인입니다')
        else:
            print('청소년입니다')
    
    is_adult(25)

    결과

    성인입니다

    # 반복문
    fruits = ['사과','배','배','감','수박','귤','딸기','사과','배','수박']
    
    count = 0
    for aaa in fruits: # 리스트와 반복문을 함께쓰도록 되어있음
        if aaa == '사과':
            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

     

    파이썬 패키지 설치하기 (=외부 라이브러리 설치)

     

    파이썬 패키지란? 남들이 만들어놓은 라이브러리를 사용하는것을 파이썬에서는 패키지라고 부른다.

    • 모듈(일종의 기능들 묶음)을 모아놓은 단위, 이런 패키지의 묶음을 라이브러리라고 볼수있음

    1) 가상환경(venv)이란?

    • 프로젝트별로 패키지들을 담을 공구함 (라이브러리를 모아두는곳이라 생각하기)
    • 같은 시스템에서 실행되는 다른 파이썬 응용 프로그램들의 동작에 영향을 주지 않기 위해, 파이썬 배포 패키지들을 설치하거나 업그레이드하는 것을 가능하게 하는 격리된 실행 환경  (https://docs.python.org/ko/3/glossary.html#term-virtual-environment
     

    용어집 — Python 3.10.2 문서

    같은 형의 두 인자를 수반하는 연산이 일어나는 동안, 한 형의 인스턴스를 다른 형으로 묵시적으로 변환하는 것. 예를 들어, int(3.15)는 실수를 정수 3으로 변환합니다. 하지만, 3+4.5 에서, 각 인자

    docs.python.org

    + 버튼을 눌러주면 아래 화면이 나옴

    requests를 설치해두면 됨. (ajax와 같은 역할을 하는 패키지를 깔았다고 생각하면 된다.)

     

    패키지 사용해보기

    (requests 써보기)

    import requests # requests 라이브러리를 쓸것이다
    
    # requests 라이브러리마다 정리된 방식이 다르다, 만든 사람 마음, 사이트에서 갔다가 봐야함.(블로그에 많음)
    r = requests.get('http://spartacodingclub.shop/sparta_api/seoulair') # 2주차에서 했던 미세먼지 API
    rjson = r.json()
    
    rows =rjson['RealtimeCityAir']['row']
    
    for row in rows: #rows에 있는 row를 하나씩 출력
        gu_name = row['MSRSTE_NM']
        gu_mise = row['IDEX_MVL']
    
        #미세먼지 농도가 100보다 작으면 출력
        if gu_mise < 100:
            print(gu_name)
    

     

     

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

    네이버 영화 페이지 (제목 찍어보기)

    크롤링을 하기 위하면 2가지를 해야함.

    • 타켓 URL을 읽어서 HTML 받아오기 (requests를 이용)
    • 제목을 쉽게 찾게 해주는 라이브러리 beautifulSoup 설치

    # 크롤링 기본 세팅
    import requests # requests를 쓰겠다.
    from bs4 import BeautifulSoup # beautifulsoup도 쓰겠다.
    
    # headers란? 보통 코드에서 콜을 날리는데 브라우저에서 콜을 날린것처럼 해주려고 쓰는것임, 코드는 그대로 쓰되, url만 바꿔서 써주면됨
    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')

     

    soup 사용법

    영화 제목 누르고 검사 들어가서

    위 해당 코드 복사하기

     

    • 하나를 select
    # 코딩 시작 (soup 사용법)
    title = soup.select_one('#old_content > table > tbody > tr:nth-child(2) > td.title > div > a')
    print(title) # 해당 태그가 찍힘
    print(title.text) # 영화제목이 찍힘
    print(title['href']) # 해당 태그에 대한 값이 찍힘
    • 여러개 select
    #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')
    # print(movies) #출력해보면 리스트형태라는걸 알수있음
    
    for movie in movies:
        a = movie.select_one('td.title > div > a')
        #print(a)만 하면 None이 출력되므로 (가로선들) 없애주기
        if a is not None: # a != None
            # print(a) 하면 None이 아닌 값 출력
            print(a.text) # 해당 태그 제목만 출력

    웹스크래핑(크롤링) 연습 

    네이버 영화 페이지 (순위, 평점 크롤링)
    for movie in movies:
        a = movie.select_one('td.title > div > a')
        #print(a)만 하면 None이 출력되므로 (가로선들) 없애주기
        if a is not None: # a != None
            title = a.text #title
            rank = movie.select_one('td:nth-child(1) > img')['alt'] # 여기에 붙여도 상관없음
            # print(rank['alt']) #alt값만 출력
            star = movie.select_one('td.point').text
            # print(star.text) #text값만 출력
            print(rank, title, star)

    DB개괄

    DB는 왜 쓰는 것일까?

    우리가 방 정리를 하는 이유는 나중에 "잘 찾기 위해서" 인것처럼, 교보문고에서 책을 찾을 때도 꽃혀진 방법대로 찾아야 쉽게 찾을 수 있는 것처럼!

    정렬되어 있는 순서를 index라고 부르는 데 순서대로 우리가 나중에 뽑았을 때 일일이 찾지않아도

    한번에 잘 뽑히게 쓰는 목적

    DB의 종류

    • SQL -칸을 만들어두고 채우는 느낌

    행/열의 생김새가 정해진 엑셀에 데이터를 저장하는 것과 유사하다. 데이터 50만 개가 적재된 상태에서, 갑자기 중간에 열을 하나 더하기는 어려울 것이다. 그러나, 정형화되어 있는 만큼, 데이터의 일관성이나 / 분석에 용이할 수 있다.

    ex) MS-SQL, My-SQL

    • NoSQL -정해진 칸없이 들어오는대로 쌓는 느낌 

    딕셔너리 형태로 데이터를 저장해두는 DB이다. 고로 데이터 하나 하나 마다 같은 값들을 가질 필요가 없게 된다. 자유로운 형태의 데이터 적재에 유리한 대신, 일관성이 부족할 수 있다.

    ex) MongoDB

     

    DB의 실체

    우리가 쓰는 프로그램과 같은것, 즉 내 컴퓨터에 게임도 설치하고, PPT도 설치하고, DB를 설치할수도 있다.

    요새는 Cloud 형태로 제공해주는 곳들이 많다.

     

    그래서! 최신 클라우드 서비스인 MongoDB Atlas를 사용해볼것!

    (유저가 몰리거나, DB를 백업해야 하거나, 모니터링하기 아주 용이하다.)

     

    MongoDB 시작하기

    https://account.mongodb.com/account/register

     

    Cloud: MongoDB Cloud

     

    account.mongodb.com

    • 구글로 로그인하고 → Accept Privacy ... Service 에 체크 → Submit.
    • 다음 화면 체크하고 넘어가기

    • Shared를 클릭하고 넘어가기
    • 싱가포르 로 체크하고, Create Cluster 클릭하기
    • 아래와 같은 화면이 잠시 동안 나온 뒤에

    • 새로고침
    • 연결 준비하기
      • Allow Access from Anywhere 클릭 → Add IP address 클릭
      • Username, Password를 아래와 같이 입력 → Create Database User 클릭
      • Choose a connection method 클릭

    MongoDB 연결하기

    파이썬으로 DB에 접속하기
    • pymongo, dnspython 패키지 설치하기
    • URL 복사해서 URL코드에 넣고, 아래와 같이 수정
    from pymongo import MongoClient
    client = MongoClient('여기에 URL 입력')
    db = client.dbsparta

    해당 코드가 안되는경우가 있을것이다.

     

    강의를 들으며 시간을 많이 할애한 부분인데, 보안문제때문에 연결이 어려운경우가 있다.

    그럴때는 아래와 같은 코드를 사용해야한다. 

    from pymongo import MongoClient
    import certifi
    
    ca = certifi.where()
    
    client = MongoClient('mongodb+srv://test:sparta@cluster0.내주소.mongodb.net/내DB명?retryWrites=true&w=majority', tlsCAFile=ca)
    db = client.dbsparta
    
    doc = {
        'name':'bob',
        'age':27
    }
    
    db.users.insert_one(doc)

    위 코드를 사용하기전에 certifi라는 패키지 설치를 해주어야한다. (파이썬 패키지 설치 방법과 동일)

    • 데이터 연결 확인하기
    doc = {
        'name':'bob',
        'age':27
    }
    
    db.users.insert_one(doc)

    pyMongo로 DB조작하기

    • 데이터 입력
    db.users.insert_one({'name':'bobby', 'age':27})
    db.users.insert_one({'name':'john', 'age':20})
    db.users.insert_one({'name':'ann', 'age':23})

    • 데이터 전부 꺼내서 보기
    all_users = list(db.users.find({}, {'_id':False})) # users : 내 데이터베이스의 users, id는 볼필요가없어서 False
    
    for user in all_users:
        print(user)

    • 데이터 하나만 찾기
    user = db.users.find_one({'name':'bobby'})
    print(user)

    • pymongo 업데이트
    # pymongo 업데이트
    db.users.update_one({'name':'bobby'},{'$set':{'age':19}}) #users로 가서 업데이트를 하는데, name이 bobby인 애를 찾아가서 age를 19로 만들어라

    • 데이터 삭제
    # 데이터 삭제
    db.users.delete_one({'name':'bobby'})

    pymongo 코드 요약
    # 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'})
    웹스크래핑 결과 저장하기
    # 크롤링 기본 세팅
    import requests # requests를 쓰겠다.
    from bs4 import BeautifulSoup # beautifulsoup도 쓰겠다.
    
    from pymongo import MongoClient
    import certifi
    
    ca = certifi.where()
    
    client = MongoClient('mongodb+srv://test:sparta@cluster0.jagx2.mongodb.net/Cluster0?retryWrites=true&w=majority', tlsCAFile=ca)
    db = client.dbsparta
    
    # headers란? 보통 코드에서 콜을 날리는데 브라우저에서 콜을 날린것처럼 해주려고 쓰는것임, 코드는 그대로 쓰되, url만 바꿔서 써주면됨
    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')
    
    # 코딩 시작 (soup 사용법)
    movies = soup.select('#old_content > table > tbody > tr')
    # print(movies) #출력해보면 리스트형태라는걸 알수있음
    
    for movie in movies:
        a = movie.select_one('td.title > div > a')
        #print(a)만 하면 None이 출력되므로 (가로선들) 없애주기
        if a is not None: # a != None
            title = a.text #title
            rank = movie.select_one('td:nth-child(1) > img')['alt'] # 여기에 붙여도 상관없음
            # print(rank['alt']) #alt값만 출력
            star = movie.select_one('td.point').text
            # print(star.text) #text값만 출력
            # print(rank, title, star)
    
            #DB에 연결
            doc = {
                'title': title,
                'rank': rank,
                'star': star
            }
            db.movies.insert_one(doc)
    

    웹스크래핑 결과 이용하기
    # 가버나옴 평점 가져오기
    movie = db.movies.find_one({'title':'가버나움'})
    print(movie['star'])
    
    # 가버나움 평점과 같은 평점 영화 가져오기
    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'])

    # 가버나움 영화 평점 0으로 만들기
    db.movies.update_one({'title':'가버나움'},{'$set':{'star':'0'}})

    지니뮤직 크롤링해보기
    # 크롤링 기본 세팅
    import requests # requests를 쓰겠다.
    from bs4 import BeautifulSoup # beautifulsoup도 쓰겠다.
    
    # headers란? 보통 코드에서 콜을 날리는데 브라우저에서 콜을 날린것처럼 해주려고 쓰는것임, 코드는 그대로 쓰되, url만 바꿔서 써주면됨
    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)
    
    # HTML을 BeautifulSoup이라는 라이브러리를 활용해 검색하기 용이한 상태로 만듦
    # soup이라는 변수에 "파싱 용이해진 html"이 담긴 상태가 됨
    # 이제 코딩을 통해 필요한 부분을 추출하면 된다.
    soup = BeautifulSoup(data.text, 'html.parser')
    
    music = soup.select('#body-content > div.newest-list > div > table > tbody > tr')
    
    for m in music:
        title = m.select_one('td.info > a.title.ellipsis').text.strip()
        rank = m.select_one('td.number').text[0:2].strip()
        artist = m.select_one('td.info > a.artist.ellipsis').text
        print(rank, title, artist)

    파이썬 내장함수 strip() 이용

    strip() 함수 : 원래 문자열의 시작과 끝에서 주어진 문자 제거, 기본적으로 strip() 함수는 문자열의 시작과 끝에서 공백을 제거하고 공백없이 동일한 문자열을 반환 (아래 URL 참고)

    https://www.entity.co.kr/entry/Python-String-strip-%ED%95%A8%EC%88%98-strip-%ED%95%A8%EC%88%98%EC%9D%98-%EC%A0%95%EC%9D%98

     

    4.2 파이썬 문자열 strip() 함수 : strip() 함수의 정의

    파이썬 스트립()이란 무엇입니까? Python strip() 함수는 Python 라이브러리에서 사용할 수 있는 내장 함수의 일부입니다. strip() 메서드는 원래 문자열의 시작과 끝에서 주어진 문자를 

    www.entity.co.kr

    지니뮤직 크롤링를 끝으로 3주차 수강 완료

     

    DB연결을 제외하고는 수업에서 특별하게 어려웠던 부분은 없었던것같다. (보안문제때문에,,, 계속 안되다가 나중에 FAQ를 통해서 해결할수 있었다. 온라인임에도 불구하고 학생들이 궁금할만한 질문들, 그에 대한 답변들을 모아놓아서 피드백이 바로바로 되는점이 좋았던것같다)

    처음해보는 크롤링이지만, 생각보다 어렵지 않았고, 크롤링하는 방법을 배워서 가져갈게많았던 수업인듯

    'Web' 카테고리의 다른 글

    [WEB] 인터렉티브 UI 기획 & 디자인  (0) 2022.07.09
    [WEB] Flask 실행하기 (AWS 서버 이용)  (0) 2022.03.11
    [WEB] Flask시작하기 (Get, Post 정리)  (0) 2022.03.07
    [WEB] JQuery, Ajax  (0) 2022.03.03
    [WEB] HTML, CSS 기초  (0) 2022.02.27
Designed by Tistory.