[내배캠 AI코스] TIL

내일배움캠프 4일차 TIL - Flask를 활용한 웹개발 및 라우팅 연습

띵제 2024. 2. 16. 22:45

오늘 들은 강의 : Chat GPT 3주차 숙제해설, Chat GPT 4주차, TIL특강, 웹개발 특강

 

 

14강 영화 검색 사이트 만들기

 

우리가 사용자로부터 영화 이름을 입력 받으면 그 결과를 보여주는 사이트를 만들어보자!

 

1) movie 페이지 보여주기

 

로또 추천 사이트 만들던 app.py파일에서 그대로 진행하는 게 당황스러웠다.

templates에 movie.html 파일을 만들어주고 app.py에서

 

@app.route(‘/movie’)

def movie():

    return render_template(‘movie.html’)

 

이렇게 입력해준다. 그리고 브라우저에서 주소창 뒤에 /movie 만 추가해주면 

movie.html 화면이 동작하는 것을 볼 수 있다.

 

그 후, movie.html에 form을 만들어준다.

 

<form action="">

        <input type=“text>

        <button type="submit">검색</button>

    </form>

 

기본 form의 모양. 브라우저에 가서 확인해보면,

 

 

이렇게 기본적인 검색 창이 만들어졌다.

 

 

이 form에서 입력한 데이터를 movie로 보내주는데 그때 이름은 query로 보내준다.

 

<input type=“text” name=“query”>  👉사용자가 텍스트로 데이터를 보내면 이걸 query라고 이름붙여서

url_for(‘movie’)  👉movie에다가 넣어주겠다.

 

이때의 movie는 app.py에 있는 def movie(): 에서의 movie로 보내주는 것.

 

그럼 app.py에서는 어떻게 movie를 통해 데이터를 받아먹을 수 있을까.

 

바로 해보자.

 

 

먼저 맨 윗 줄에 request를 추가해주고,

 

@app.route(‘/movie’)

def movie():

    print(request.args.get(‘query’))

    return render_template(‘movie.html’)

 

이후 브라우저 검색창에 “아무검색어” 나 입력을 한 뒤 검색 버튼을 누르면,

서버에 “아무검색어”가 와 있는 걸 볼 수 있다. 이게 request가 동작하는 것이다.

 

 

그러면 본격적으로 영화진흥위원회에서 데이터를 받아와 페이지를 만들어보도록 하겠다.

 

영화진흥위원회 API코드 스니펫을 붙여주면,

 

이렇게, 우리가 아닌 다른 사람이 만든 requests 코드가 새로 생긴다.

 

이 코드를 쓰기 위해 가져오려면 다시 위로 올라가 import random 밑의 줄에

import requests 를 입력, 노란줄이 떴다면 requests가 설치가 안된 것이다.

 

그러면 터미널로 가서, 가상환경 확인하고(.venv) $ pip install requests, 설치됨

 

라이브러리는 설치했다가 또 설치해도 문제 되는 것이 없으니 뭔가 잘 안된다면 한번씩 다시 확인해도 좋다.

 

res = requests.get~~ 코드를 다시 살펴보면 get방식으로 한국영화진흥회 주소에 요청을 보내고,

받은 응답을 json으로 바꾼 다음에, 그걸 또 다시 movieResult, movieList로 결국 movie_list로 만드는 과정이다.

 

query로 검색어를 통해 영화데이터를 받은 다음에, 그 영화데이터들을 data = movie_list 라고 정의를 해준뒤,

일단은 화면에 표시할거니까 return render_template 에 넣어준다.

 

그 다음에는 받아온 검색어를 가지고 영화진흥위원회에서 데이터를 받아올 거다.

 

후..

 

자, 영화진흥위원회 API 홈페이지로 들어가서

 

 

우리는 ? 뒤에 movieNm = 아이언맨 뭐 이런식으로 사용하면 되겠다.

 

print(request.args.get('query'))   query = request.args.get('query') 로 바꿔주고

 

res = requests.get(

    "http://kobis.or.kr/kobisopenapi/webservice/rest/movie/searchMovieList.json?key=f5eef3421c602c6cb7ea224104795888&movieNm={query}"

    )

 

 

API 코드에 있던 링크 뒤에 변수를 넣어준다.

 

근데 이 링크를 쓰려면 링크 앞에 f자를 넣어줘야한다. f-string이라고 한다. 이유는 설명을 안해줌. 

print에서 query로 값을 변경해주는 것도 설명 한 마디가 없음. 이 강의는 이유를 너무 설명 안함. 밥아저씨야 뭐야.

오죽하면 내가 강의를 무슨 받아쓰기 하는 것 마냥 .. 어휴

 

마지막으로 movie_list = rjson["movieListResult"]["movieList"] 밑에 print(movie_list) 

넣어주면 드디어 실행을 해본다. python app.py 엔터!

 

 

오예!!!

 

그럼 이제 movie_list를 화면에 띄워보자.

 

movie.html로 이동해 냅다 출력을 한다. 무슨 설명이 이래..?

 

form 코드 밑에 {{ data }} 입력후 새로고침 < app.py의 data=movie_list를 불러오는 것.

 

아, 냅다 불러오는 거 맞았네.

 

보아하니 영화 데이터들은 모두 [ ] 이렇게 리스트로 되어 있어 for문을 사용할거임 ffor 엔터,

 

 {% for element in collection %}

            {{ element|e }}

    {% endfor %}

 

값 넣어주기

 

{% for movie in data %}

            {{ movie|e }}

    {% endfor %}

 

p태그 만들어서 사이에 낑겨주고

 

{% for movie in data %}

           <p> {{ movie|movieNm }} </p>

    {% endfor %}

 

하고 새고고침하면, 장렬하게 오류오류 에러에러

 

 

 

오늘의 N번째 질문을 남겨본다. 한참한참한참 후에 온 답장의 내용.

 

튜터님 : movie|movieNm 에서 |을 지우고 .으로 적어보세요!

 

 

나 : 헐!? 왜 돼요? 갑자기 왜 돼요?

 

튜터님 : 님이 오타낸 거니까요^^

(실제론 친절히 말씀해주심)

 

📙 3주차 숙제

 

YYYYMMDD 형식으로 날짜를 검색하면 그 날짜의 박스오피스 순위가 나오는 사이트를 만들어보자.

 

..막막하군.

 

일단 숙제 코드 스니펫에 있는 자료들을 냅다 복붙해본다.

오류가 난다.

 

 

잠시 화면을 째려보다가.. 

혹시 전날 실습때도 query를 사용했어서 그런가 싶어 전날 실습하던 내용들을 전부 주석처리 해보았다.

사라지지 않는 오류.

 

브라우저에도 오류가 난다.

 

일단 URL에서 뭐가 오류가 났는지 살펴보기로 한다.

영화진흥위원회 박스오피스 홈페이지를 들어가 필요한 정보들을 살펴보고 코드를 고쳐보았다.

 

 

실습때는 영화명으로 검색을 했고.. 지금은 날짜로 검색을 할거니까.. 요거 킵

요것도 킵

 

강의에서 제공해주는 코드스니펫을 보니 더 헷갈린다.

싹 지우고 처음부터 그냥 해보기로 한다.

 

 

완전완전 처음부터.

이제 vs코드에서 query 문제 있다고 뜨는 건 사라졌다.

그리고 내가 바보같은 짓을 했다는 걸 깨달았다. 부랴부랴 브라우저 주소창에 /answer를 추가해준다.

 

..잘 나온다. 염병.

 

그럼 다시 코드스니펫 복사해오니, 다시 query 오류..

 

다시 지우고 처음부터..

어제 강의 들었던 내용 그.대.로. 따라가본다.

 

 

자 아무검색어 서버로 도착했고,

영화진흥회 API 넣어주면 또또또 에러가 난다.

 

syntaxerror : invalid syntax 의 의미는 파이썬에서는 사용하지 않는 문법, 즉 문법상의 에러가 났다는 뜻이다.

 

아..

작고 소중한 f를 빼먹었다. 다시 정상작동.

 

어제 실습과 비교해보니 이게 없어서 추가해주었다.

근데 이 문장의 뜻이 뭔지 모르겠다.

이따가 찾아보기로 한다.

 

어제 작성한 코드 중 movie_list는 왜 들어갔었지 곰곰히 생각해보니

브라우저 창에서 검색했을때 보여줄 데이터가 바로 그거였다.

어제 분명 다 이해했다고 생각했는데..

 

::기록 못한 시간::

이후로 2시간동안 끙끙대다가.. 결국 숙제해설 영상을 봐버린다..ㅠ

 

코드스니펫에서 내가 추가했어야 하는 거

 

app.py 에서

 

if request.args.get('query'): query = request.args.get('query') else: query = '20230601'

이거랑

movie_list = rjson.get("boxOfficeResult").get("weeklyBoxOfficeList")

 

전체코드는 이렇게 나왔어야

 

from flask import Flask, render_template, request

import requests

 

app = Flask(__name__)

 

@app.route("/answer")

def answer():

 

    if request.args.get('query'):

        query = request.args.get('query')

    else:

        query = '20230601'    

 

    URL = f"http://kobis.or.kr/kobisopenapi/webservice/rest/boxoffice/searchWeeklyBoxOfficeList.json?key=f5eef3421c602c6cb7ea224104795888&targetDt={query}"

 

    res = requests.get(URL)

 

    rjson = res.json()

    movie_list = rjson.get("boxOfficeResult").get("weeklyBoxOfficeList")

 

    return render_template("answer.html", data=movie_list)

 

answer.html  에서는

 

<tbody> {% for movie in data %} <tr>

<th scope="row">{{ movie.rank }}</th>

<td>{{ movie.movieNm}}</td>

<td>{{ movie.openDt }}</td>

<td>{{ movie.audiAcc}}명</td>

</tr> {% endfor %}

 

요거를 넣었어야 했다. 전체코드는 이렇게 나왔어야함.

 

<!DOCTYPE html>

<html lang="en">

<head>

  <meta charset="UTF-8">

  <meta name="viewport" content="width=device-width, initial-scale=1.0">

  <title>Document</title>

 

</head>

<body>

  <h1>박스오피스 검색</h1>

  <p>20230501 형식으로 검색하세요.</p>

  <form action="{{ url_for('answer') }}">

    <input type="text" name="query">

    <button type="submit">검색</button>

  </form>

 

  <table class="table">

    <thead>

      <tr>

        <th scope="col">랭킹</th>

        <th scope="col">영화명</th>

        <th scope="col">영화개봉일</th>

        <th scope="col">누적관객수</th>

      </tr>

    </thead>

    <tbody>

      {% for movie in data %}

      <tr>

        <th scope="row">{{ movie.rank }}</th>

        <td>{{ movie.movieNm}}</td>

        <td>{{ movie.openDt }}</td>

        <td>{{ movie.audiAcc}}명</td>

      </tr>

      {% endfor %}

    </tbody>

  </table>

 

 <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js" integrity="sha384-geWF76RCwLtnZ8qwWowPQNguL3RmwHVBC9FhGdlKrxdiJJigb/j/68SIy3Te4Bkz" crossorigin="anonymous"></script>

</body>

</html>

 

이해가, 너무 안된다.

특강이 있어서 일단 특강을 들으러 감.

 

4주차 수업 시작!

1~5강 [데일리모토] 라우팅 연습

 

강의 실습 따라하다가 

@app.route("/")

def home():

    name = '제이미'

    motto = “행복해서 웃는게 아니라 웃어서 행복합니다.”

 

    context = {

        "name" : name,

        "motto" : motto,

    }

    return render_template('motto.html', data=context)

 

 

요 내용 고대로 잘 따라하는데 오류가 남

 

그래서 “행복해서~행복합니다.” 를 ‘행복해서~행복합니다.’ 로 바꿔줌.

(큰따옴표에서 작은 따옴표로)

 

근데 됨. 강의 화면을 다시 보니 강사는 분명 큰따옴표를 씀. 바로 질문 ㄱㄱ

 

튜터님의 답변 : 따옴표는 종류 상관없이 문자열을 표시하는데 사용함. 원래 오류가 발생하지 않는 것이 원칙이나

실행환경의 문법오류감지 설정에 따라 두 개를 혼용해서 쓰지 말라고 에러표시 뜨기도 함.

 

근데 이미 강의 실습을 진행중이었기에 오류 화면을 캡쳐를 못해놨었다ㅠ

그래서 다음에 에러 또 뜨면 원격으로 상황을 살펴보기로 했다. (그래서 아직도 왜인지는 모르겠음.)

 

일단 강의 내용 계속 진행해본다.

이름과 모토 두 가지 데이터를 보여줄것이기 때문에 context 사용,

 

context = {

        'name' : name,  #주소창에서 받아온 이름

        'motto' : motto,

    }

 

 

응, 오류.

조금 포기하고 싶다는 생각이 듦. 하하..하하핳하..하하하ㅏㅎ핳핳

 

맨 아래줄에 포트를 설정해줘봄. (어제 이걸로만 거의 15번 오류남.)

 

app.run(debug=True)

 

app.run(debug=True, port=5001)

 

그리고 들어가니 오류 해결됨!

우와 오류에 대한 지식이 쌓이고 있어..!!

 

결과문 완성!

 

 

 

6강 [데일리모토] - 페이지 이동 기능 만들기

 

1) 메뉴 - 페이지 이동 기능 만들기

 

먼저, 화면 안에서 눌렀을 때 페이지간 이동을 할 수 있는 버튼을 만들기로 한다.

music.html의 네브바에서 

 

요렇게 줄을 접어서 드래그하면 한방에 드래그를 할 수 있다. 드래그 범위 즉, 네브바 범위 잘 확인하고 ctrl+c 해오기.

motto.html로 와서 motto.html의 네브바 밑에 그대로 붙여넣는다.

 

그러면 이렇게 두 개의 네브바가 생겼다. 헷갈리지 않게 주석 달아주자.

 

 

오케이, 그 다음은 버튼을 만들때 빠질 수 없는 부트스트랩을 추가해준다.

제공되는 코드스니펫 복사.

★ 넣어주는 위치 중요!! 꼭 style 태그 위에 넣는다. ★

 

그리고 자바스크립트 CDN은 닫는 body태그 위!

 

요렇게 넣어준다.

 

style 태그 안에 원래있던 네브바는 주석처리를 해버림.

그리고 밑으로 내려와 두 개의 네브바 중에서,

motto 네브바의 head부분을 복사해서,

 

<div class="weather">

            <img id="weather-icon">

            <p id="weather-msg"></p>

        </div>

 

music 네브바에 넣어준다.

 

줄 번호를 잘 보고 넣어주면 된다.

그리고 기존 motto 네브바는 싹 다 지워준다.

그리고 다시 파이썬 서버 실행. 브라우저를 가보면,

 

상단 네브바가 멜로디쉐어랑 같아진 걸 확인할 수 있다.

 

만들어진 네브바 안의 버튼들을 누르면 다른 페이지로 이동하도록 해줄건데, Home 버튼을 누르면 이동하는 걸로 해보겠다.

 

music네브바 중에서 90번째 줄에 있는 Home 버튼을 찾아 하이퍼링크부분을  

href=“#” 에서 href=“{{url_for(‘home’)}}” 으로 바꿔준다.

 

여기서 말하는 ‘home’은 무엇이냐면,

 

app.py에 있는 저 home이다! 너무 헷갈리니 항상 천천히 차근차근 확인하도록 하자,,

 

데일리모토 페이지에 있는 Music버튼을 누르면 멜로디쉐어 페이지로 이동하도록 만들거니까,

여기는 motto.html이니까, 바로 아래 Music 버튼에도 하이퍼링크 부분을 바꿔준다. href=“{{url_for(‘music’)}}” 으로.

 

그러면, 멜로디 쉐어 페이지에 있는 Home 버튼을 눌러서 다시 데일리모토 페이지로 올 수도 있어야 하니까,

music.html에도 같은 작업을 해줘야겠지. music.html > 네브바의 Home버튼 > 하이퍼링크 수정!

 

브라우저에 가서 해당 버튼들을 눌러보면 구현이 잘 된 것을 확인할 수 있다!

 

 

::오늘의 회고::

어제 되게 열심히 강의를 들었다고 생각했는데3주차 숙제를 혼자 못해내고 종국에는 이해를 포기해버려서 조금 자존감이 낮아졌다..웹개발 특강과 TIL특강을 적절한 타이밍에 잘 들어서 다행이었던 것 같다.특강 내용이 별로 어려운 내용이 없었기 때문에 약간 휴식이 되었던 것도 사실.그래도 담주 월욜에는 나머지 강의를 다 들을 수 있을 듯..? 아마도..?TIL을 계속 기록하면서 따라가니 그래도 전보다는 실제적으로 습득을 하게 되는 것 같아

도움이 많이 되는 듯 하다. 개떡같이 쓰더라도 매일 써야지.