하고 싶은게 많음

항해99 공부하면서 생긴 문제해결 본문

카테고리 없음

항해99 공부하면서 생긴 문제해결

쏘매띵 2023. 9. 3. 13:41

 

 

아직 배워가는 중이라 틀린게 있을 수 있습니다. 

 

 

 

1. 문제: flask를 이용하여 서버를 연결하고,  랜덤 숫자를 만들어서 기존 번호와 동일한 숫자의 갯수만큼 출력하는 페이지를 작성하고 있었다. 아래의 코드를 저장 후 서버에 연결해서 화면에 출력되는 결과를 확인해봤는데, 

<!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>안녕하시오. {{ data.name }}</h1>    
    <h1>금회 당첨 번호는 {{ data.lotto }}</h1>
    <h1>랜덤 로또 번호는 {{ data.random_lotto }}</h1>
    <h1>{{data.common_count}}</h1>
    
    {% if data.common_count == 6 %}
        <h2>{{data.common_count}}개 맞았습니다. 1등입니다.</h2>
    { %elif data.common_count == 5 %}
        <h2>{{data.common_count}}개 맞았습니다. 2등입니다.</h2>
    { %elif data.common_count == 4 %}
        <h2>{{data.common_count}}개 맞았습니다. 3등입니다.</h2> 
    { %elif data.common_count == 3 %}
        <h2>{{data.common_count}}개 맞았습니다. 4등입니다.</h2>
    { %else %}
        <h2>{{data.common_count}}개 맞았습니다. 재도전하십시오...</h2> 
    {% endif %} 
</body>
</html>

▲ index.html

 

import random
from flask import Flask, render_template
app = Flask(__name__)


@app.route('/')
def home():
    name = '정윤영'
    lotto = [1, 2, 3, 4, 5]

    def generate_lotto_numbers():
        lotto_numbers = random.sample(range(1, 46), 6)
        lotto_numbers.sort()
        return sorted(lotto_numbers)

    random_lotto = generate_lotto_numbers()

    def count_common_elements(list1, list2):
        common_elements = set(list1) & set(list2)
        return len(common_elements)

    common_count = count_common_elements(lotto, random_lotto)
    
    context = {
        "name": name,
        "lotto": lotto,
        "random_lotto": random_lotto,
        "common_count":common_count
    }

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



@app.route('/mypage')
def mypage():
    return 'This is Home!'


if __name__ == '__main__':
    app.run(debug=True)

▲ app.py

 

위와 같은 결과가 나왔다. html에서 if문으로 만들어놨던 코드가 아예 작동을 안했다. 숫자 몇개가 동일한지 확인하는 코드는 잘 작동하는지 확인 완료했다. 무엇이 문제일까. 이럴땐 껐다키는게 직빵인데 그것조차 안먹힌다!

문제해결!

문제는 if문에 있었다. %앞에 띄어쓰기를 넣어서 실행이 안됐던 것...! 

{% if data.common_count == 6 %}
	<h2>{{data.common_count}}개 맞았습니다. 1등입니다.</h2>
{% elif data.common_count == 5 %} 
	<h2>{{data.common_count}}개 맞았습니다. 2등입니다.</h2>
{% elif data.common_count == 4 %}
    <h2>{{data.common_count}}개 맞았습니다. 3등입니다.</h2> 
{% elif data.common_count == 3 %}
    <h2>{{data.common_count}}개 맞았습니다. 4등입니다.</h2>
{% else %}
	<h2>{{data.common_count}}개 맞았습니다. 재도전하십시오...</h2> 
{% endif %}

 

 


2. 문제:  아래와 같이 코드를 작성할 때 자꾸 패키지가 없는지 request 에 밑줄이 쳐진다.

#flask(로컬환경에서 서버만들어서 불러오기), 랜덤함수
import random
from flask import Flask, render_template
# 스크래핑
from bs4 import BeautifulSoup
import requests
app = Flask(__name__)

@app.route('/')
def home():
    name = '정윤영'
    lotto_number = [1,2,3,4,4,5]
     #랜덤 로또 숫자 만드는 함수
    def generate_lotto_numbers():
        lotto_numbers = random.sample(range(1, 46), 6)
        return sorted(lotto_numbers)

    random_lotto = generate_lotto_numbers()

    #두 개의 리스트의 같은 숫자 갯수 알아내는 함수
    def count_common_elements(list1, list2):
        common_elements = set(list1) & set(list2)
        return len(common_elements)

    common_count = count_common_elements(lotto_number, random_lotto)    

    context = {
        "name": name,
        "lotto_number": lotto_number,
        "random_lotto": random_lotto,
        "common_count":common_count
    }

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

@app.route('/movie')
def movie():
    print(request.args.get('query'))
    return render_template('movie.html')

if __name__ == '__main__':
    app.run(debug=True)

 

간단한 문제지만 맨날 requests와 request가 헷갈린다.

requests와 request의 차이는 아래와 같다.

requests request
pip install requests로 설치한 라이브러리 flask에서 import하여 사용

고로 request에 밑줄이 그어지면 아래와 같이 import만 하면 해결됨.

 

 

 

 

 


3. requests를 이용하여 api를 불러와서 json화 시켜 필요한거를 추출하는 와중에 keyError가 났다.

#flask(로컬환경에서 서버만들어서 불러오기), 랜덤함수
import random
from flask import Flask, render_template, request
# 스크래핑
from bs4 import BeautifulSoup
import requests
app = Flask(__name__)

# 박스오피스 검색
@app.route('/answer')
def answer():
    query = request.args.get('query') # 검색어. movie.html에서 input의 name속성이 query임. 리퀘스트
    URL = f"	https://kobis.or.kr/kobisopenapi/webservice/rest/boxoffice/searchDailyBoxOfficeList.json?key=f5eef3421c602c6cb7ea224104795888&targetDt={query}" # URL
    
    res = requests.get(URL) #requests기능
    rjson = res.json() #json화 시키기
    box_office_list = rjson["boxOfficeResult"]["dailyBoxOfficeList"] #json에서 필요한거 추출. !!여기서 문제가 발생함.!!
	
    return render_template("movie.html", data = box_office_list)

if __name__ == '__main__':
    app.run(debug=True)

▲ 문제가 발생한 app.py

 

KeyError가

box_office_list = rjson["boxOfficeResult"]["dailyBoxOfficeList"]

여기서 문제가 발생해서 키를 내가 잘 못 입력한건가? 싶어서 api사이트에 들어가서 다시 확인함. 근데 맞게 했잖아?!         (KeyError는 키가 존재하지 않기때문에 뜨는 에러)

 

난 저 하이라이트한 부분을 타고 들어가서 영화정보를 얻고싶은거뿐이라고!!!

 

get 메소드를 이용해서 오류를 잡을 수 있는건가. get을 이용하면 그래도 오류가 잡힐 수 있다는 글을 보았다.

    res = requests.get(URL) #requests기능
    rjson = res.json() #json화 시키기
    box_office_list = rjson.get("boxOfficeResult").get("dailyBoxOfficeList")

이렇게 수정을 하고, 다시 서버를 실행해봤다.

이젠 AttributeError가 뜬다. 젠장. 

 

그러다가 그냥 일단 코드를 진행해보자 하여 진행하게됐음. url 뒤에 query들어가는 부분을 작성했다. input 에 text 아무것도 안넣었을때는 임의의 날짜를 입력되도록 if문을 만들어서 넣어줬더니 오류가 해결되었다.

 

 

 

# 박스오피스 검색
@app.route('/answer')
def answer():
    if request.args.get('query'):
        query = request.args.get('query') # 검색어. movie.html에서 input의 name속성이 query임. 리퀘스트
    else:
        query = '20230101'

    URL = f"	https://kobis.or.kr/kobisopenapi/webservice/rest/boxoffice/searchDailyBoxOfficeList.json?key=f5eef3421c602c6cb7ea224104795888&targetDt={query}" # URL
    res = requests.get(URL) #requests기능
    rjson = res.json() #json화 시키기
    # box_office_list = rjson.get("boxOfficeResult").get("dailyBoxOfficeList") 
    box_office_list = rjson["boxOfficeResult"]["dailyBoxOfficeList"] #json에서 필요한거 추출

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

if __name__ == '__main__':
    app.run(debug=True)

▲ 해결된 app.py파일

 

날짜가 입력되지않아서 아래와 같은 페이지로 넘어가고, api에서 키를 못찾았던 것이었다!!! 이걸 알았다면, 예외처리를 해줬을텐데!

 

▲ 날짜를 입력하지 않거나 날짜의 형식을 맞추지않았을때&nbsp; api페이지

 

▲ 완료한 웹 페이지 화면

 

에러가 뜨더라도 그 부위가 문제라는 장담은 못한다는걸 알았다... 삽질만했지만, 이유를 알았기에 만족한다.

 


4. 멜론 사이트를 크롤링 하기 위해서 코드를 짰다.

@app.route('/music')
def music():
    url ="https://www.melon.com/chart/"
    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 (url ,headers = headers )
    soup =BeautifulSoup (data.text,'html.parser')

    trs = soup.select('table > tbody > tr')
    for tr in trs:
        title = tr.select_one('.rank01 > span > a').text()
        artist = tr.select_one('.rank02 > a').text()
        image_url = tr.select_one('.img')['src']
        context = {
            "title": title,
            "artist" : artist,
            "image_url" : image_url
        }

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

물론 다른 코드들도 있었지만, 유독 문제가 되는 부분만을 발췌했다.

 

 

로컬변수에 접근할 수 없다는 말. 몬말이야 이게. 젠장. 내가 놓친 코드가 있나 샅샅이 뒤져봤는데 결국 발견하지 못했다. 챗GPT한테도 물어봄. 사실 위의 코드말고 전 코드가 있는데 태그 이름을 잘 못 쓴게 있었다. 그부분을 챗GPT가 짚어주었다. 왕신기...

 

▲ 챗GPT한테 물어보고 얻은 대답_태그이름을 수정했다.

 

챗GPT한테 물어본걸로도 에러가 해결되지 않아 체감 1시간 이상 잡아놓고 보고있었다...결국 수업자료로 올려주신 자료를 보게됐는데 데이터가 들어갈 빈 리스트를 초기화하고 선언해야했다. 띠용. 여태 그렇게 수업진행을 안했었는데?! 데이터의 양이 많아서 인가...(여태 한 두가지의 데이터의 양만 전달하기만 했음. 하지만 여기서는 크롤링이라 데이터가 방대하다)

 

# 음악 사이트
@app.route('/music')
def music():
    url ="https://www.melon.com/chart/"
    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 (url ,headers = headers )
    soup =BeautifulSoup (data.text,'html.parser')

    # username = request.args.get('query')
    melon_list = []
    trs = soup.select('table > tbody > tr')
    for tr in trs:
        title = tr.select_one('.rank01 > span > a').text()
        artist = tr.select_one('.rank02 > a').text()
        image_url = tr.select_one('.img')['src']
        melon_list.append({
            "title": title,
            "artist" : artist,
            "image_url" : image_url
        })

    return render_template('music.html', data = melon_list)

 

암튼 고친 코드로 에러를 해결했다. 

 

 

 

 

 


5. 총 html페이지 6페이지를 만들고 app.py도 잘돌아가고 로컬환경에서 사이트가 잘 나오는걸 확인했다. 파이썬애니웨어에 올리고 들어가보는데 오류가 떠있었다. 역시 하나 해결하면 다른 하나가 문제구나. 

 디버깅 팁스에서 에러로그를 살펴보았다.

2023-09-09 06:41:08,071: If you're seeing an import error and don't know why,
2023-09-09 06:41:08,071: we have a dedicated help page to help you debug: 
2023-09-09 06:41:08,072: https://help.pythonanywhere.com/pages/DebuggingImportError/
2023-09-09 06:41:08,072: ***************************************************
2023-09-09 06:41:38,424: Error running WSGI application
2023-09-09 06:41:38,425: ModuleNotFoundError: No module named 'flask_app'
2023-09-09 06:41:38,425:   File "/var/www/jeongyy123_pythonanywhere_com_wsgi.py", line 16, in 
2023-09-09 06:41:38,425:     from flask_app import app as application  # noqa
2023-09-09 06:41:38,425: ***************************************************
2023-09-09 06:41:38,425: If you're seeing an import error and don't know why,
2023-09-09 06:41:38,425: we have a dedicated help page to help you debug: 
2023-09-09 06:41:38,425: https://help.pythonanywhere.com/pages/DebuggingImportError/
2023-09-09 06:41:38,425: ***************************************************
2023-09-09 06:45:43,745: Error running WSGI application
2023-09-09 06:45:43,745: ModuleNotFoundError: No module named 'flask_app'
2023-09-09 06:45:43,745:   File "/var/www/jeongyy123_pythonanywhere_com_wsgi.py", line 16, in 
2023-09-09 06:45:43,745:     from flask_app import app as application  # noqa
2023-09-09 06:45:43,746: ***************************************************
2023-09-09 06:45:43,746: If you're seeing an import error and don't know why,
2023-09-09 06:45:43,746: we have a dedicated help page to help you debug: 
2023-09-09 06:45:43,746: https://help.pythonanywhere.com/pages/DebuggingImportError/
2023-09-09 06:45:43,746: ***************************************************

▲에러로그

flask_app 이라는 모듈이 없다고?! 바로 아래에 도움이 있길래 눌러서 검색해봤다.

https://www.pythonanywhere.com/forums/topic/12092/ 

 

ModuleNotFoundError : Forums : PythonAnywhere

2019-02-13 10:58:31,090: Error running WSGI application 2019-02-13 10:58:31,096: ModuleNotFoundError: No module named 'pdfkit' 2019-02-13 10:58:31,096: File "/var/www/kkff_pythonanywhere_com_wsgi.py", line 16, in <module> 2019-02-13 10:58:31,096: from flas

www.pythonanywhere.com

 

뭔말이야...암튼 찾다보니 파일명을 제대로 썼는가에 대한 말이 있길래 확인해보니 내가 이번에 만들었던 프로젝트파일을 올린게 아니었다! 이런 정말 말도 안되는 실수를 하다니! 다시 프로젝트를 압축해서 다시 올렸고, 파일명도 제대로 수정했다. (꼭 올릴 땐 app.py를 flask_app.py로 변경해야 알아먹는다) 그랬더니 다시 발생하는 오류...이번에는 unhandled exception 이라는 에러가 떴다. 머리를 득득 긁으면서 아이스크림 하나 먹으면서 좀 쉬었다가 다시 천천히 처음부터 다시 시작했다. 

 

 

체크 포인트

1. 프로젝트 파일을 압축을 제대로 했는가. 

2. 가상환경을 잘 만들었는가.

3. 가상환경을 만든 후 패키지 설치를 제대로 했는가.

4. pythonanywhere 사이트에서 입력해야하는 부분(virtualenv 부분)을 잘했는가

 

체크포인트를 하나씩 확인하다보니 3번 패키지 설치를 잘못했었다. 어이없어ㅎ 꼭 가상환경이 켜져 있는 상태에서( venv가 안떠있다면 꼭 source venv/bin/activate 로 가상환경을 활성화 시키고 패키지를 설치해야함) 패키지 설치하도록...

그렇게 다시 리로드 하고 페이지를 열어보니 이제서야 된다. 대신 다른 다양한 문제가 발생했다. 

 

1. 일부 메뉴 페이지(외부 사이트에서 크롤링한 결과를 보여주는 사이트)를 누르면 아래와 같은 에러 화면이 나오고, 

 

2. 멜로디 쉐어에서 음악추가하여 모달에서 폼을 입력해서 저장하면 아래와 같은 화면이 나오고,

 

3. (이건 로컬환경에서도 발생했던 문제인데...) 주소뒤에 ' /iloveyou/쏘매띵 ' 을 넣으면 아래와 같은 페이지가 연결되도록  app.py에서 만들어놨었다. 근데 페이지이동을 하면 꼭 저렇게 왼쪽 로고 부분이 깨져서 나온다. 

 

 

 

 

된장헐. 답도 없다 답도 없어.

 

Comments