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

매 주차 강의자료 시작에 PDF파일을 올려두었어요!

왕초보 시작반과 동일한 강의입니다 ! ☺️

[수업 목표]

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

[목차]

모든 토글을 열고 닫는 단축키
Windows : Ctrl + alt + t
Mac : + + t


01. 3주차 설치

  • 이번주 수업을 위해 설치할 것들!

    아래 프로그램/파일들을 가지고 계신 기기에 맞게 차근차근 다운로드 받아주세요!

    1. Python

      • 윈도우

        1. 링크를 눌러 다운로드 해주세요. (다운로드 링크)

          반드시 Python 3.8.6 버전을 설치해주세요.
          (3.9는 너무 최신 버전이라 오작동 하는 OS들이 있어요)

        2. 다운로드된 파이썬 파일을 열어 설치합니다.

          주의) Add Python 3.8 to PATH 에 체크해야 합니다!!

          • 설치 완료!
      • Mac에는 기본적으로 파이썬 2.x 버전이 설치되어 있지만, 버전3으로 업데이트 되면서 많은 변화가 있었습니다. 본 강의에서는 3.8.2 버전의 파이썬이 필요하니 아래 가이드에 따라 꼭 설치해주세요!

        1. 버튼을 눌러 다운로드 해주세요. (다운로드 링크)

        2. 다운로드된 파이썬 파일을 열어 설치합니다. 아래와 같은 폴더가 나타나면 설치가 완료된 것입니다.

    2. mongoDB

      • 윈도우

        1. C드라이브에, 그림과 같이 data 라는 폴더를 만들고, 그 안에 db 라는 폴더를 만듭니다.

        2. 링크로 가셔서, MongoDB Community Server 탭에서 다음 사항을 선택한 뒤 다운로드합니다. (캡처 이미지를 클릭하면 크게 보실 수 있어요!)

          • Version : 4.4.4 (current)
          • Platfrom : Windows
          • Package : MSI

        3. Next 를 클릭합니다.

        4. 약관에 동의한 뒤 Next를 클릭합니다.

        5. Custom을 클릭합니다.

        6. Browse를 클릭합니다.

        7. C:\data\db\ 를 찾아 선택하고 OK를 클릭합니다.

        8. Location 항목이 C:\data\db\ 로 변경된 것을 확인하고 Next 를 클릭합니다.

        9. Next 를 클릭합니다.

        10. Install MongoDB Compass 선택을 해제하고 Next를 클릭합니다.

        11. Install을 선택합니다.

        12. 아래와 같은 알림창이 뜨면, 'ignore'를 클릭해주세요.

        13. 제어판 > 시스템 및 보안 > 시스템 에서 [고급 시스템 설정]을 클릭합니다.

        14. 환경 변수 > [시스템 변수] 목록 > Path 선택 > 편집을 클릭한 뒤 다음 내용을 추가합니다.

          C:\data\db\bin

        15. 윈도우 키 + R 을 누른 후 cmd 를 입력하고 엔터를 누릅니다. 명령 프롬포트에 다음 명령어를 입력합니다.

          (입력하면 아무일도 일어나지 않는 것이 정상입니다. 🤓)

          mongod --install --serviceName MongoDB --serviceDisplayName MongoDB --dbpath C:\data\db --logpath C:\data\db\log\mongoservice.log --logappend

          그 후에, 다음 명령어를 입력합니다.

          mongo

          아래와 같은 화면이 보이면 정상 작동 하는 것입니다. cmd 창을 닫으면 끝!🔥

        1. 맥북 비밀번호 설정

          MongoDB를 설치하기 위해 Homebrew 라는 프로그램을 이용할 건데, 이 때 반드시 컴퓨터 비밀번호가 있어야 합니다. 비밀번호가 없으신 분들은 맥북의 비밀번호를 먼저 설정하시고 진행해주세요.

        2. Spotlight 에서, "terminal" 또는 "터미널"로 검색해 터미널을 열어줍니다.

          터미널이 무엇인가요?

          ****우리는 주로 마우스를 써서 컴퓨터에 명령을 내리지만, 컴퓨터가 더 익숙한 건 '명령어'를 통한 명령입니다. 터미널은, '명령어를 쓸 수 있는 창'으로 생각해주시면 되겠습니다! 잘 여셨다면 아래와 같은 창을 만날 수 있습니다!

        3. Homebrew 설치하기

          Homebrew는 무엇인가요?

          ****새로운 것이 참 많죠? 지금부터 맥의 편리함에 빠져드신 겁니다.
          Homebrew는 '다운로드 패키지'를 관리할 수 있는 툴이에요.

          brew install 프로그램이름

          을 입력하면, 프로그램을 자동으로 다운로드 받아 설치해준답니다. 엄청나죠?

          터미널 창에 아래 코드를 복사, 붙여넣기 하고 엔터!

          /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"

          그러면 아래와 같은 화면이 나옵니다. 이 화면에서 다시 엔터!

          그러면 아래와 같이 패스워드 입력칸이 나옵니다. 내 맥북 패스워드를 입력하고 엔터!
          (패스워스를 입력하더라도 화면에 나타나진 않아요. 사실 잘 입력되고 있으니 걱정 마세요! 😜)

          엔터 누른 후에 만약 맥 소프트웨어(Xcode) 업데이트 알림이 뜨면 업데이트를 해주세요.

          모든 설치가 완료되면 아래와 같은 화면이 나옵니다. Homebrew 설치 끝!

        4. mongoDB 설치하기

          터미널 창에 아래 코드 입력 후 엔터 (한줄씩 복사-붙여넣기 하세요)

          brew tap mongodb/brew
          brew install mongodb-community

          몽고DB 설치가 완료되면 다음 화면이 나옵니다.

        5. mongoDB 실행해보기

          brew services start mongodb-community

          아래와 같은 화면이 나옵니다.

          앗, 혹시 brew services start mongodb-community 실행이 안되시나요?

          • 안될 경우 대처 방안

            아래 내용을 차례대로 실행해보세요

            brew update
            brew services start mongodb-community
        6. 마지막으로, mongoDB 실행이 잘 되었는지 확인하기

          http://localhost:27017 에 접속했을 때,
          아래와 같은 화면을 만나면 잘 된 것입니다!

          이제 mongoDB 설치가 모두 완료되었습니다!

    3. Robo3T

      • 윈도우 & 맥

        • 다운로드: https://robomongo.org/download

        • Download Robo 3T 를 다운받으세요! ( ⇒ 🚨 Studio 3T를 다운 받으시면 안 됩니다!)

          이메일, 이름 입력하라는 창이 뜹니다. 입력하시고 받아주세요~! 🙂

          설치가 완료되면 자동으로 실행될텐데요,

          1. 정책 동의(agree) 창이 뜨면, agree를 클릭해주시고요!

          2. 아래에선 아무것도 입력하지 않고 Finish를 클릭하시면 Robo 3T 설치도 끝!

    4. (윈도우만!) Git bash

      • 윈도우만! 맥은 다운받지 않아도 돼요!

        • 다운로드: https://git-scm.com/

          클릭 후 다운로드 받은 설치 파일을 열어서, 설치를 진행합니다.

          모두 next → next → next .. 해서 설치하시면 아래와 같이 완료! 됩니다!

02. 3주차 오늘 배울 것

  • 오늘 배울 것 이야기 - 3주차: Python, 크롤링, mongoDB

    오늘은 드디어 '파이썬'을 배울거예요. 먼저 문법을 연습하고, 라이브러리를 활용하여 네이버 영화목록을 쫙 가져와보겠습니다. (기대되죠!)

    • 그리고, 우리의 인생 첫 데이터베이스. mongoDB를 다뤄볼게요!

03. 연습 겸 복습 - 나홀로메모장에 OpenAPI 붙여보기

2주차 리마인드를 위해 특별히 복습을 준비했어요. 한번 더 뽀개고 갑시다!

  • 1) 스파르타가 만들어둔 OpenAPI 파악하기

    • [코드스니펫] 나홀로메모장 API(GET)

      [http://spartacodingclub.shop/post](http://spartacodingclub.shop/post)
    • [코드스니펫] 나홀로메모장 구경하기

      ```html
      http://spartacodingclub.shop/
      ```

      네 그렇습니다!

      나홀로메모장에 들어가는 아티클들의 정보를 불러오는 OpenAPI입니다.
      이 API를 써서 저장된 포스팅 불러오기를 만들어볼게요!
      (나중에 이 API를 실제로 만들어 볼 예정!)

  • 2) 포스팅가져오기API 붙이기

    1. 2주차에 완성했던 '나홀로메모장'을 켜봅니다!

      • [코드스니펫] 코드가 없다면!

        <!doctype html>
        <html lang="en">
        
        <head>
            <!-- Required meta tags -->
            <meta charset="utf-8">
            <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
        
            <!-- Bootstrap CSS -->
            <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css"
                integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
        
            <!-- Optional JavaScript -->
            <!-- jQuery first, then Popper.js, then Bootstrap JS -->
            <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
            <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js"
                integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q"
                crossorigin="anonymous"></script>
            <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"
                integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl"
                crossorigin="anonymous"></script>
        
            <title>스파르타코딩클럽 | 부트스트랩 연습하기</title>
        
            <link href="https://fonts.googleapis.com/css2?family=Jua&display=swap" rel="stylesheet">
        
            <style>
                * {
                    font-family: 'Jua', sans-serif;
                }
        
                .wrap {
                    margin: auto;
                    width: 900px;
                }
        
                .comment {
                    font-weight: bold;
                    color: blue;
                }
        
                .posting-box {
                    margin: 10px auto 30px auto;
                    width: 500px;
        
                    border: 3px solid black;
                    border-radius: 5px;
        
                    padding: 25px;
        
                    display: none;
                }
            </style>
            <script>
                function openclose() {
                    let status = $('#post-box').css('display');
                    if (status == 'block') {
                        $('#post-box').hide()
                        $('#posting-box-btn').text('포스팅박스 열기')
                    } else {
                        $('#post-box').show()
                        $('#posting-box-btn').text('포스팅박스 닫기')
                    }
                }
            </script>
        </head>
        
        <body>
            <div class="wrap">
                <div class="jumbotron">
                    <h1 class="display-4">나홀로 링크 메모장!</h1>
                    <p class="lead">중요한 링크를 저장해두고, 나중에 볼 수 있는 공간입니다</p>
                    <hr class="my-4">
                    <p class="lead">
                        <a id="posting-box-btn" onclick="openclose()" class="btn btn-primary btn-lg" href="#"
                            role="button">포스팅박스 열기</a>
                    </p>
                </div>
                <div class="posting-box" id="post-box">
                    <div class="form-group">
                        <label for="exampleInputEmail1">아티클 URL</label>
                        <input id="post-url" type="email" class="form-control" aria-describedby="emailHelp" placeholder="">
                    </div>
                    <div class="form-group">
                        <label for="exampleInputPassword1">간단 코멘트</label>
                        <input type="password" class="form-control" placeholder="">
                    </div>
                    <button type="submit" class="btn btn-primary">기사 저장</button>
                </div>
                <div class="card-columns" id="cards-box">
                    <div class="card">
                        <img class="card-img-top"
                            src="https://d2ur7st6jjikze.cloudfront.net/offer_photos/29590/185689_medium_1525763241.jpg?1525763241"
                            alt="Card image cap">
                        <div class="card-body">
                            <a href="http://naver.com" class="card-title">여기 기사 제목이 들어가죠</a>
                            <p class="card-text">기사의 요약 내용이 들어갑니다. 동해물과 백두산이 마르고 닳도록 하느님이 보우하사 우리나라만세 무궁화 삼천리 화려강산...</p>
                            <p class="card-text comment">여기에 코멘트가 들어갑니다.</p>
                        </div>
                    </div>
                    <div class="card">
                        <img class="card-img-top"
                            src="https://d2ur7st6jjikze.cloudfront.net/offer_photos/29590/185689_medium_1525763241.jpg?1525763241"
                            alt="Card image cap">
                        <div class="card-body">
                            <a href="http://naver.com" class="card-title">여기 기사 제목이 들어가죠</a>
                            <p class="card-text">기사의 요약 내용이 들어갑니다. 동해물과 백두산이 마르고 닳도록 하느님이 보우하사 우리나라만세 무궁화 삼천리 화려강산...</p>
                            <p class="card-text comment">여기에 코멘트가 들어갑니다.</p>
                        </div>
                    </div>
                    <div class="card">
                        <img class="card-img-top"
                            src="https://d2ur7st6jjikze.cloudfront.net/offer_photos/29590/185689_medium_1525763241.jpg?1525763241"
                            alt="Card image cap">
                        <div class="card-body">
                            <a href="http://naver.com" class="card-title">여기 기사 제목이 들어가죠</a>
                            <p class="card-text">기사의 요약 내용이 들어갑니다. 동해물과 백두산이 마르고 닳도록 하느님이 보우하사 우리나라만세 무궁화 삼천리 화려강산...</p>
                            <p class="card-text comment">여기에 코멘트가 들어갑니다.</p>
                        </div>
                    </div>
                    <div class="card">
                        <img class="card-img-top"
                            src="https://d2ur7st6jjikze.cloudfront.net/offer_photos/29590/185689_medium_1525763241.jpg?1525763241"
                            alt="Card image cap">
                        <div class="card-body">
                            <a href="http://naver.com" class="card-title">여기 기사 제목이 들어가죠</a>
                            <p class="card-text">기사의 요약 내용이 들어갑니다. 동해물과 백두산이 마르고 닳도록 하느님이 보우하사 우리나라만세 무궁화 삼천리 화려강산...</p>
                            <p class="card-text comment">여기에 코멘트가 들어갑니다.</p>
                        </div>
                    </div>
                    <div class="card">
                        <img class="card-img-top"
                            src="https://d2ur7st6jjikze.cloudfront.net/offer_photos/29590/185689_medium_1525763241.jpg?1525763241"
                            alt="Card image cap">
                        <div class="card-body">
                            <a href="http://naver.com" class="card-title">여기 기사 제목이 들어가죠</a>
                            <p class="card-text">기사의 요약 내용이 들어갑니다. 동해물과 백두산이 마르고 닳도록 하느님이 보우하사 우리나라만세 무궁화 삼천리 화려강산...</p>
                            <p class="card-text comment">여기에 코멘트가 들어갑니다.</p>
                        </div>
                    </div>
                </div>
            </div>
        </body>
        
        </html>
    2. 우선, 로드가 다 되면 실행되는 함수를 하나 만듭니다

      구글링해보기: javascript 로딩 후 실행

      • [코드스니펫] 로딩 후 바로실행

        $(document).ready(function(){
          listing();
        });
        
        function listing() {
        	console.log('화면 로딩 후 잘 실행되었습니다');
        }
    3. API 결과값을 다시한번 확인하기

      $(document).ready(function(){
        listing();
      });
      
      function listing() {
      	$.ajax({
      	  type: "GET",
      	  url: "http://spartacodingclub.shop/post",
      	  data: {},
      	  success: function(response){
      			console.log(response)
      	  }
      	})
      }

      response['result'] 에 정상 여부가 있고, response['articles']에 리스트로 아티클들이 들어가 있습니다.

    4. 기사데이터를 log에 찍어봅시다!

      $.ajax({
        type: "GET",
        url: "http://spartacodingclub.shop/post",
        data: {},
        success: function(response){
      	   console.log(response['articles'])
        }
      })
    5. articles를 돌면서, 하나씩 출력해봅니다.

      $.ajax({
        type: "GET",
        url: "http://spartacodingclub.shop/post",
        data: {},
        success: function(response){
      	   let articles = response['articles'];
      		 for (let i = 0; i < articles.length; i++) {
      			 let article = articles[i];
      			 console.log(article);
      		 }
        }
      })
    6. article 내용(comment, desc, image, title, url)으로 HTML을 만들어 붙여줍니다.

      $.ajax({
        type: "GET",
        url: "http://spartacodingclub.shop/post",
        data: {},
        success: function (response) {
            let articles = response['articles'];
            for (let i = 0; i < articles.length; i++) {
                let article = articles[i];
                let image = article["image"];
                let url = article["url"];
                let title = article["title"];
                let desc = article["desc"];
                let comment = article["comment"];
                let temp_html = `<div class="card">
                                   <img class="card-img-top" src="${image}" alt="Card image cap">
                                   <div class="card-body">
                                     <a href="${url}" target="_blank" class="card-title">${title}</a>
                                     <p class="card-text">${desc}</p>
                                     <p class="card-text comment">${comment}</p>
                                   </div>
                                 </div>`;
                $('#cards-box').append(temp_html);
            }
        }
      })
    7. 먼저 있던 카드들을 지워줍니다.

      $(document).ready(function () {
          $('#cards-box').empty();
          listing();
      });
    8. 1~7단계 통해 완성된 전체 script 코드

      <script>
          $(document).ready(function () {
              $('#cards-box').empty('');
              listing();
          });
      
          function listing() {
              $.ajax({
      				  type: "GET",
      				  url: "http://spartacodingclub.shop/post",
      				  data: {},
      				  success: function (response) {
      				      let articles = response['articles'];
      				      for (let i = 0; i < articles.length; i++) {
      				          let article = articles[i];
      				          let image = article["image"];
      				          let url = article["url"];
      				          let title = article["title"];
      				          let desc = article["desc"];
      				          let comment = article["comment"];
      				          let temp_html = `<div class="card">
      				                             <img class="card-img-top" src="${image}" alt="Card image cap">
      				                             <div class="card-body">
      				                               <a href="${url}" target="_blank" class="card-title">${title}</a>
      				                               <p class="card-text">${desc}</p>
      				                               <p class="card-text comment">${comment}</p>
      				                             </div>
      				                           </div>`;
      				          $('#cards-box').append(temp_html);
      				      }
      				  }
      				})
          }
      
          function openclose() {
              // id 값 post-box의 display 값이 block 이면
              if ($('#post-box').css('display') == 'block') {
                  // post-box를 가리고
                  $('#post-box').hide();
                  $('#btn-posting-box').text('포스팅 박스 열기');
              } else {
                  // 아니면 post-box를 펴라
                  $('#post-box').show();
                  $('#btn-posting-box').text('포스팅 박스 닫기');
              }
          }
      </script>
    9. 완성된 코드 전체

      • 코드

        <!doctype html>
        <html lang="en">
        
        <head>
            <!-- Required meta tags -->
            <meta charset="utf-8">
            <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
        
            <!-- Bootstrap CSS -->
            <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css"
                integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
        
            <!-- Optional JavaScript -->
            <!-- jQuery first, then Popper.js, then Bootstrap JS -->
            <script src="https://code.jquery.com/jquery-3.4.1.slim.min.js"
                integrity="sha384-J6qa4849blE2+poT4WnyKhv5vZF5SrPo0iEjwBvKU7imGFAV0wwj1yYfoRSJoZ+n"
                crossorigin="anonymous"></script>
            <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/umd/popper.min.js"
                integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo"
                crossorigin="anonymous"></script>
            <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js"
                integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6"
                crossorigin="anonymous"></script>
        
            <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
        
            <title>스파르타코딩클럽 | 나홀로메모장</title>
        
            <!-- 구글폰트 -->
            <link href="https://fonts.googleapis.com/css?family=Stylish&display=swap" rel="stylesheet">
        
            <!-- style -->
            <style type="text/css">
                * {
                    font-family: 'Stylish', sans-serif;
                }
        
                .wrap {
                    width: 900px;
                    margin: auto;
                }
        
                .comment {
                    color: blue;
                    font-weight: bold;
                }
        
                #post-box {
                    width: 500px;
                    margin: 20px auto;
                    padding: 50px;
                    border: black solid;
                    border-radius: 5px;
                    display: none;
                }
            </style>
            <script>
                $(document).ready(function () {
                    $('#cards-box').empty('');
                    listing();
                });
        
                function listing() {
                    $.ajax({
        							  type: "GET",
        							  url: "http://spartacodingclub.shop/post",
        							  data: {},
        							  success: function (response) {
        							      let articles = response['articles'];
        							      for (let i = 0; i < articles.length; i++) {
        							          let article = articles[i];
        							          let image = article["image"];
        							          let url = article["url"];
        							          let title = article["title"];
        							          let desc = article["desc"];
        							          let comment = article["comment"];
        							          let temp_html = `<div class="card">
        							                             <img class="card-img-top" src="${image}" alt="Card image cap">
        							                             <div class="card-body">
        							                               <a href="${url}" target="_blank" class="card-title">${title}</a>
        							                               <p class="card-text">${desc}</p>
        							                               <p class="card-text comment">${comment}</p>
        							                             </div>
        							                           </div>`;
        							          $('#cards-box').append(temp_html);
        							      }
        							  }
        							})
                }
        
                function openclose() {
                    // id 값 post-box의 display 값이 block 이면
                    if ($('#post-box').css('display') == 'block') {
                        // post-box를 가리고
                        $('#post-box').hide();
                        $('#btn-posting-box').text('포스팅 박스 열기');
                    } else {
                        // 아니면 post-box를 펴라
                        $('#post-box').show();
                        $('#btn-posting-box').text('포스팅 박스 닫기');
                    }
                }
            </script>
        </head>
        
        <body>
            <div class="wrap">
                <div class="jumbotron">
                    <h1 class="display-4">나홀로 링크 메모장!</h1>
                    <p class="lead">중요한 링크를 저장해두고, 나중에 볼 수 있는 공간입니다</p>
                    <hr class="my-4">
                    <p class="lead">
                        <button id="btn-posting-box" onclick="openclose()" class="btn btn-primary btn-lg">포스팅박스 열기</button>
                    </p>
                </div>
                <div class="form-post" id="post-box">
                    <div>
                        <div class="form-group">
                            <label for="exampleFormControlInput1">아티클 URL</label>
                            <input id="post-url" class="form-control" placeholder="">
                        </div>
                        <div class="form-group">
                            <label for="exampleFormControlTextarea1">간단 코멘트</label>
                            <textarea class="form-control" rows="2"></textarea>
                        </div>
                        <button type="button" class="btn btn-primary">기사저장</button>
                    </div>
                </div>
                <div id="cards-box" class="card-columns">
                    <div class="card">
                        <img class="card-img-top"
                            src="https://www.eurail.com/content/dam/images/eurail/Italy%20OCP%20Promo%20Block.adaptive.767.1535627244182.jpg"
                            alt="Card image cap">
                        <div class="card-body">
                            <a href="#" class="card-title">여기 기사 제목이 들어가죠</a>
                            <p class="card-text">기사의 요약 내용이 들어갑니다. 동해물과 백두산이 마르고 닳도록 하느님이 보우하사 우리나라만세 무궁화 삼천리 화려강산...</p>
                            <p class="card-text comment">여기에 코멘트가 들어갑니다.</p>
                        </div>
                    </div>
                    <div class="card">
                        <img class="card-img-top"
                            src="https://www.eurail.com/content/dam/images/eurail/Italy%20OCP%20Promo%20Block.adaptive.767.1535627244182.jpg"
                            alt="Card image cap">
                        <div class="card-body">
                            <a href="#" class="card-title">여기 기사 제목이 들어가죠</a>
                            <p class="card-text">기사의 요약 내용이 들어갑니다. 동해물과 백두산이 마르고 닳도록 하느님이 보우하사 우리나라만세 무궁화 삼천리 화려강산...</p>
                            <p class="card-text comment">여기에 코멘트가 들어갑니다.</p>
                        </div>
                    </div>
                    <div class="card">
                        <img class="card-img-top"
                            src="https://www.eurail.com/content/dam/images/eurail/Italy%20OCP%20Promo%20Block.adaptive.767.1535627244182.jpg"
                            alt="Card image cap">
                        <div class="card-body">
                            <a href="#" class="card-title">여기 기사 제목이 들어가죠</a>
                            <p class="card-text">기사의 요약 내용이 들어갑니다. 동해물과 백두산이 마르고 닳도록 하느님이 보우하사 우리나라만세 무궁화 삼천리 화려강산...</p>
                            <p class="card-text comment">여기에 코멘트가 들어갑니다.</p>
                        </div>
                    </div>
                    <div class="card">
                        <img class="card-img-top"
                            src="https://www.eurail.com/content/dam/images/eurail/Italy%20OCP%20Promo%20Block.adaptive.767.1535627244182.jpg"
                            alt="Card image cap">
                        <div class="card-body">
                            <a href="#" class="card-title">여기 기사 제목이 들어가죠</a>
                            <p class="card-text">기사의 요약 내용이 들어갑니다. 동해물과 백두산이 마르고 닳도록 하느님이 보우하사 우리나라만세 무궁화 삼천리 화려강산...</p>
                            <p class="card-text comment">여기에 코멘트가 들어갑니다.</p>
                        </div>
                    </div>
                    <div class="card">
                        <img class="card-img-top"
                            src="https://www.eurail.com/content/dam/images/eurail/Italy%20OCP%20Promo%20Block.adaptive.767.1535627244182.jpg"
                            alt="Card image cap">
                        <div class="card-body">
                            <a href="#" class="card-title">여기 기사 제목이 들어가죠</a>
                            <p class="card-text">기사의 요약 내용이 들어갑니다. 동해물과 백두산이 마르고 닳도록 하느님이 보우하사 우리나라만세 무궁화 삼천리 화려강산...</p>
                            <p class="card-text comment">여기에 코멘트가 들어갑니다.</p>
                        </div>
                    </div>
                    <div class="card">
                        <img class="card-img-top"
                            src="https://www.eurail.com/content/dam/images/eurail/Italy%20OCP%20Promo%20Block.adaptive.767.1535627244182.jpg"
                            alt="Card image cap">
                        <div class="card-body">
                            <a href="#" class="card-title">여기 기사 제목이 들어가죠</a>
                            <p class="card-text">기사의 요약 내용이 들어갑니다. 동해물과 백두산이 마르고 닳도록 하느님이 보우하사 우리나라만세 무궁화 삼천리 화려강산...</p>
                            <p class="card-text comment">여기에 코멘트가 들어갑니다.</p>
                        </div>
                    </div>
                </div>
            </div>
        </body>
        
        </html>

04. 파이썬 시작하기

  • 3) 파이썬을 설치한다는 것의 의미

    **파이썬을 설치한다?

    →** 일종의 번역팩을 설치한다고 생각하면 됩니다. 컴퓨터는 101010001 과 같은 언어만 알아듣는다고 했지요? 파이썬 문법으로 된 것을 101010001로 변환해줄 수 있도록, 번역 패키지를 설치하는 것입니다.

  • 4) 첫 파이썬 파일 실행

    • hello.py 파일 안에 다음 내용을 붙여넣습니다.

      print('Hello, sparta')
    • 혹시 실행이 안된다면!

      file → new project 에서 아래와 같은 화면을 띄워주세요. 그리고 base interpreter에서 python 38-32 버전을 클릭한 뒤 create를 클릭합니다.

  • 5) 파이썬 문법을 시작하기에 앞서..

    • 파이썬은 매우 직관적인 언어이고, 할 수 있는 것도 많습니다. 그런데, 개발자들도 모든 문법을 기억하기란 쉽지 않습니다. 오늘 배우는 것 외에 필요한 것들은 구글링해서 찾아보면 됩니다!
    • 단, tuple과 set 자료형, class는 기초 단계에선 다루지 않겠습니다. (몰라도 괜찮고, 많은 개발자들도 모릅니다. 나중에 필요한 일이 생겼을 때 배워야 의미를 알 수 있습니다!)

05. 파이썬 기초공부

  • 6) 파이썬 기초 문법

    • 변수 & 기본연산

      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 이렇게?
    • 자료형

      • 숫자, 문자형

        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'
    • 함수

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

        # 수학문제에서
        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)
        
        # result라는 변수의 값은?
    • 조건문

      • 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의 값은 무엇일까요?
        def is_adult(age):
        	if age > 20:
        		print('성인입니다')    # 조건이 참이면 성인입니다를 출력
        	else:
        		print('청소년이에요')  # 조건이 거짓이면 청소년이에요를 출력
        
        is_adult(30)
        # 무엇이 출력될까요?
    • 반복문

      파이썬에서의 반복문은, 리스트의 요소들을 하나씩 꺼내쓰는 형태입니다.

      • 4즉, 무조건 리스트와 함께 쓰입니다!

        fruits = ['사과','배','감','귤']
        
        for fruit in fruits:
        	print(fruit)
        
        # 사과, 배, 감, 귤 하나씩 꺼내어 찍힙니다.
      • 살짝 응용해볼까요? - 과일 갯수 세기 함수

        • [코드스니펫] 리스트 예제

          ```python
          fruits = ['사과','배','배','감','수박','귤','딸기','사과','배','수박']
          ```
          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
          people = [{'name': 'bob', 'age': 20}, 
                    {'name': 'carry', 'age': 38},
                    {'name': 'john', 'age': 7},
                    {'name': 'smith', 'age': 17},
                    {'name': 'ben', 'age': 27}]
          ```
          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'])
          
          # 이번엔, 반복문과 조건문을 응용한 함수를 만들어봅시다.
          # 이름을 받으면, age를 리턴해주는 함수
          def get_age(myname):
              for person in people:
                  if person['name'] == myname:
                      return person['age']
              return '해당하는 이름이 없습니다'
          
          print(get_age('bob'))
          print(get_age('kay'))

06. 파이썬 패키지 설치하기

  • 7) 파이썬 패키지(package) 설치하기

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

    즉, 여기서는 패키지 설치 = 외부 라이브러리 설치!

      1. 가상 환경(virtual environment) 이란? - 프로젝트별로 패키지들을 담을 공구함

        문제상황:
        회사에서는 패키지 A, B, C를 설치해서 쓰고,
        개인 프로젝트에서는 패키지 B, C, D, E를 설치해서 쓰고 있었어요.

        그런데 회사팀장님이 B를 이전 버전인 B' 로 쓰자고 하시네요.
        그렇게 되면, 같은 컴퓨터에 깔려 있는 개인 프로젝트에서는 B'로 쓰면 코드를 다 바꿔야 해요 😭

        어떻게 하면 좋을까요?

        해결책:
        다 담아둘 필요 없이 공구함을 2개 만들어서,

        공구함1에 A, B', C를 담아두고,
        공구함2에 B, C, D, E를 담아두고 쓰면 관리하기 편하겠죠?

        그래서, 가상환경이라는 개념이 등장했습니다.
        즉, 프로젝트별 공구함 이에요.

        정리하자면,

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

        출처 : 파이썬 공식 용어집- 가상환경

      1. pip(python install package) 사용 - requests 패키지 설치해보기

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

      • project interpreter 화면에서 + 버튼을 누르면 아래 창이 뜹니다!

07. 패키지 사용해보기

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

    • 아래 방법으로 서울시 대기 OpenAPI에서, 중구의 NO2 값을 가져올 수 있습니다.

      • [코드스니펫] requests 써보기

        import requests # requests 라이브러리 설치 필요
        
        r = requests.get('http://openapi.seoul.go.kr:8088/6d4d776b466c656533356a4b4b5872/json/RealtimeCityAir/1/99')
        rjson = r.json()
        
        print(rjson['RealtimeCityAir']['row'][0]['NO2'])
    • 모든 구의 IDEX_MVL 값을 찍어주자!

      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:
      	print(gu['MSRSTE_NM'], gu['IDEX_MVL'])
    • IDEX_MVL 값이 60 미만인 구만 찍어주자!

      들여쓰기가 얼마나 중요한지 다시한번 확인해보세요!

      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:
      	if gu['IDEX_MVL'] < 60:
      		print (gu['MSRSTE_NM'], gu['IDEX_MVL'])

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

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

    • 어떤 걸 스크래핑 할 계획인가요?

      • [코드스니펫] 네이버영화페이지

        [https://movie.naver.com/movie/sdb/rank/rmovie.nhn?sel=pnt&date=20200303](https://movie.naver.com/movie/sdb/rank/rmovie.nhn?sel=pnt&date=20200303)
    • 패키지 추가 설치하기(beautifulsoup4)

      bs4
    • 크롤링 기본 세팅

      • [코드스니펫] 크롤링 기본 세팅

        ```python
        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')
        
        # 코딩 시작
        ```
        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이라는 변수에 "파싱 용이해진 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.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('위와 동일')
    • 항상 정확하지는 않으나, 크롬 개발자도구를 참고할 수도 있습니다.

      1. 원하는 부분에서 마우스 오른쪽 클릭 → 검사

      2. 원하는 태그에서 마우스 오른쪽 클릭

      3. Copy → Copy selector로 선택자를 복사할 수 있음

09. Quiz_웹스크래핑(크롤링) 연습

  • 10) ✍웹스크래핑 더 해보기 (순위, 제목, 별점)

    • Q. 아래와 같이 보이면 완성!

    • A. 완성 코드

      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:
              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 태그 사이의 텍스트를 가져오기
              print(rank,title,star)

10. DB설치 확인

  • 11) DB 설치 확인

    먼저, 각자 설치해온 DB가 잘 작동하는지 확인합니다. 크롬 창에 localhost:27017 이라고 쳤을 때, 아래와 같은 화면이 나오면 mongoDB가 돌아가고 있는 것입니다.

  • 12) robo 3T 준비하기

    • robo 3T의 역할

      mongoDB라는 프로그램은 참 특이한 친구예요. 눈으로 보이지 않는답니다.
      유식한 말로, 그래픽인터페이스(=GUI)를 제공하지 않는다고 표현합니다.

      데이터를 저장했는데 눈으로 보이진 않고.. 답답하겠죠?

      그래서 DB내부를 살펴보기 위한 프로그램을 따로 설치해야해요.
      → 이것이 바로 robo3T의 역할!

      참고) 우리 눈에는 안보이지만(=GUI는 없지만) 컴퓨터에서 돌아가는 프로그램들은 무척 많으니, 너무 놀라지 마세요~!

    • robo3T 세팅하기

      아래처럼 준비해서 robo3T에서 DB 볼 세팅을 미리 해둡니다!
      (sparta-local-DB는 아무 이름이나 입력해도 됩니다)

- db, collection, documents(각 데이터들을 지칭)를 확인 가능합니다.

    지금은 System, config 외엔 아무것도 없죠?
    조금 이따 데이터를 넣으면 아래처럼 보일거예요!

    ![https://s3-us-west-2.amazonaws.com/secure.notion-static.com/159fa684-005e-47f4-a1e2-295d0f639f1b/Untitled.png](https://s3-us-west-2.amazonaws.com/secure.notion-static.com/159fa684-005e-47f4-a1e2-295d0f639f1b/Untitled.png)

11. DB개괄

  • 12) 들어가기 전에 : DB의 두 가지 종류

    Database에는, 크게 두 가지 종류가 있습니다.

    RDBMS(SQL)

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

    ex) MS-SQL, My-SQL 등

    No-SQL

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

    ex) MongoDB

12. pymongo로 DB조작하기

  • 14) pymongo로 mongoDB 조작하기

    • pymongo 라이브러리의 역할

      예를 들어, MS Excel를 파이썬으로 조작하려면,
      특별한 라이브러리가 필요하지 않겠어요?

      마찬가지로, mongoDB 라는 프로그램을 조작하려면,
      특별한 라이브러리, pymongo가 필요하답니다!

    • 패키지 설치하기

      pymongo
    • [코드스니펫] pymongo 기본 코드

      from pymongo import MongoClient
      client = MongoClient('localhost', 27017)
      db = client.dbsparta
      
      # 코딩 시작
    • DB연결하기 & 데이터 넣기

      • [코드스니펫] pymongo(insert)

        ```jsx
        doc = {'name':'bobby','age':21}
        db.users.insert_one(doc)
        ```
        from pymongo import MongoClient           # pymongo를 임포트 하기(패키지 인스톨 먼저 해야겠죠?)
        client = MongoClient('localhost', 27017)  # mongoDB는 27017 포트로 돌아갑니다.
        db = client.dbsparta                      # 'dbsparta'라는 이름의 db를 만듭니다.
        
        # MongoDB에 insert 하기
        
        # '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})
    • 모든 결과 값을 보기

      • [코드스니펫] pymongo(find)

        ```jsx
        same_ages = list(db.users.find({'age':21},{'_id':False}))
        ```
        from pymongo import MongoClient           # pymongo를 임포트 하기(패키지 인스톨 먼저 해야겠죠?)
        client = MongoClient('localhost', 27017)  # mongoDB는 27017 포트로 돌아갑니다.
        db = client.dbsparta                      # 'dbsparta'라는 이름의 db를 만듭니다.
        
        # MongoDB에서 데이터 모두 보기
        all_users = list(db.users.find({}))
        
        # 참고) MongoDB에서 특정 조건의 데이터 모두 보기
        same_ages = list(db.users.find({'age':21},{'_id':False}))
        
        print(all_users[0])         # 0번째 결과값을 보기
        print(all_users[0]['name']) # 0번째 결과값의 'name'을 보기
        
        for user in all_users:      # 반복문을 돌며 모든 결과값을 보기
            print(user)
    • 특정 결과 값을 뽑아 보기

      • [코드스니펫] pymongo(find_one)

        ```jsx
        user = db.users.find_one({'name':'bobby'})
        ```
        user = db.users.find_one({'name':'bobby'})
        print(user)
    • 수정하기

      • [코드스니펫] pymongo(update_one)

        ```jsx
        db.users.update_one({'name':'bobby'},{'$set':{'age':19}})
        ```
        # 생김새
        db.people.update_many(찾을조건,{ '$set': 어떻게바꿀지 })
        
        # 예시 - 오타가 많으니 이 줄을 복사해서 씁시다!
        db.users.update_one({'name':'bobby'},{'$set':{'age':19}})
        
        user = db.users.find_one({'name':'bobby'})
        print(user)
    • 삭제하기 (거의 안 씀)

      • [코드스니펫] pymongo(delete_one)

        ```jsx
        db.users.delete_one({'name':'bobby'})
        ```
        db.users.delete_one({'name':'bobby'})
        
        user = db.users.find_one({'name':'bobby'})
        print(user)
  • 15) pymongo 사용법. 코드요약

    • [코드스니펫] pymongo 코드 요약

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

      우리는 딱 네 가지 기능만 알면 됩니다. 저장하고, 찾고, 바꾸고, 지우고!
      이 기능들을 어떻게 사용하는지 요약하면 다음과 같습니다.

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

13. 웹스크래핑 결과 저장하기

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

    • 이 코드에서 시작해봅시다!

      • [코드스니펫] 크롤링 완성코드

        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:
                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 태그 사이의 텍스트를 가져오기
                print(rank,title,star)
    • pymongo 기본 세팅

      import requests
      from bs4 import BeautifulSoup
      
      from pymongo import MongoClient           # pymongo를 임포트 하기(패키지 인스톨 먼저 해야겠죠?)
      client = MongoClient('localhost', 27017)  # mongoDB는 27017 포트로 돌아갑니다.
      db = client.dbsparta                      # 'dbsparta'라는 이름의 db를 만듭니다.
      
      # 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:
              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 태그 사이의 텍스트를 가져오기
              print(rank,title,star)
    • 도큐먼트 만들어 하나씩 insert 하기

      import requests
      from bs4 import BeautifulSoup
      
      from pymongo import MongoClient           # pymongo를 임포트 하기(패키지 인스톨 먼저 해야겠죠?)
      client = MongoClient('localhost', 27017)  # mongoDB는 27017 포트로 돌아갑니다.
      db = client.dbsparta                      # 'dbsparta'라는 이름의 db를 만듭니다.
      
      # 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:
              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)

14. Quiz_웹스크래핑 결과 이용하기

  • 17) ✍find, update 연습하기 (delete는 연습 안할게요!)

    • 파이썬 파일을 새로 하나 만들어 연습해봅니다.

      • [코드스니펫] pymongo 기본 코드

        from pymongo import MongoClient
        client = MongoClient('localhost', 27017)
        db = client.dbsparta 
        
        # 코딩 시작
    • (1) 영화제목 '매트릭스'의 평점을 가져오기

      • Q. 이렇게 되면 완성

      • A. 완성 코드

        from pymongo import MongoClient
        client = MongoClient('localhost', 27017)
        db = client.dbsparta
        
        ## 코딩 할 준비 ##
        
        target_movie = db.movies.find_one({'title':'매트릭스'})
        print (target_movie['star'])
    • (2) '매트릭스'의 평점과 같은 평점의 영화 제목들을 가져오기

      • Q. 이렇게 되면 완성

      • A. 완성 코드

        from pymongo import MongoClient
        client = MongoClient('localhost', 27017)
        db = client.dbsparta
        
        ## 코딩 할 준비 ##
        
        target_movie = db.movies.find_one({'title':'매트릭스'})
        target_star = target_movie['star']
        
        movies = list(db.movies.find({'star':target_star}))
        
        for movie in movies:
            print(movie['title'])
    • (3) 매트릭스 영화의 평점을 0으로 만들기

      • Q. 이렇게 되면 완성 (robo3T로 봤을 때)

      • A. 완성 코드

        from pymongo import MongoClient
        client = MongoClient('localhost', 27017)
        db = client.dbsparta
        
        ## 코딩 할 준비 ##
        
        db.movies.update_one({'title':'매트릭스'},{'$set':{'star':'0'}})

15. 3주차 끝 & 숙제 설명

지니뮤직의 1~50위 곡을 스크래핑 해보세요.

  • [코드스니펫] 지니뮤직 사이트

    [https://www.genie.co.kr/chart/top200?ditc=D&ymd=20200403&hh=23&rtm=N&pg=1](https://www.genie.co.kr/chart/top200?ditc=D&ymd=20200403&hh=23&rtm=N&pg=1)
  • 순위 / 곡 제목 / 가수를 스크래핑 하면 됩니다.

    • Q. 이렇게 되면 완성

      ![https://s3-us-west-2.amazonaws.com/secure.notion-static.com/c06d11e4-2d0b-4afe-a88f-4722e64f2ee7/Untitled.png](https://s3-us-west-2.amazonaws.com/secure.notion-static.com/c06d11e4-2d0b-4afe-a88f-4722e64f2ee7/Untitled.png)

      힌트:

      순위와 곡제목이 깔끔하게 나오지 않을 거예요. 옆에 여백이 있다던가, 다른 글씨도 나온다던가.. 파이썬 내장 함수인 strip()을 잘 연구해보세요!

HW. 3주차 숙제 해설

  • [코드스니펫] 3주차 숙제 답안 코드

    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://www.genie.co.kr/chart/top200?ditc=D&ymd=20200403&hh=23&rtm=N&pg=1',headers=headers)
    
    soup = BeautifulSoup(data.text, 'html.parser')
    
    trs = soup.select('#body-content > div.newest-list > div > table > tbody > tr')
    
    for tr in trs:
        title = tr.select_one('td.info > a.title.ellipsis').text.strip()
        rank = tr.select_one('td.number').text[0:2].strip()
        artist = tr.select_one('td.info > a.artist.ellipsis').text
        print(rank, title, artist)

Copyright ⓒ TeamSparta All rights reserved.

좋은 웹페이지 즐겨찾기