본문 바로가기

Project/springfield 대본 다운로드

[Springfield 대본 다운로드] 2. Flask 연동하기

반응형

웹으로 배포하면 누군가가 사용할 수도 있지 않을까?라는 마음으로 python 코드에 Flask를 연동해보려 한다. Flask에 관한 내용은 아래 문서와 영상을 참고했다.

https://wikidocs.net/83097

 

000 동영상 강의 모음

# 이전 강의 - 01-1 ~ 01-3 : https://youtu.be/NJ6FrqVHHlE - 01-4 : https://youtu.be/BFRG8oIWpMY # 프로 ...

wikidocs.net

 

1. Flask 프로젝트 세팅

1) 가상환경 및 패키지 설정

pip install virtualenv // 가상환경
virtualenv venv //venv 폴더에 가상환경 만들 것 -> venv 폴더 생긴다

venv|Scripts|activate //가상환경 활성화 (역슬래시)
deactivate //가상환경 비활성화
//필요한 패키지 설치
pip install flask requests bs4 pylint
pip install html5lib

 

2) 폴더 구조

  • /static/index.css : 기본 css
  • /templates/index.html : 기본 html
  • /app.py: 기본 서버
  • /download.py: 대본 다운로드 코드

 

3) 테스트 코드 작성

app.py

from flask import Flask, render_template

# Flak 앱 서버 인스턴스
app = Flask(__name__)

# url 패턴 - 라우팅 - 데코레이터
@app.route('/')
def index():
    return render_template('index.html')

# 메인 테스트
if __name__ == '__main__':
    app.run(debug=True)

 

templates/index.html 

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>DSS</title>
  </head>
  <body>
	<h1>Hello</h1>
  </body>
</html>

 

-> 실행(py app.py)하면 화면에 Hello가 나오는 것을 볼 수 있음

 

 

2. 데이터 전달

1) 제목과 포멧을 입력받아 대본 다운받는 코드 작성

  • 제목에 해당하는 모든 시즌의 모든 에피소드를
  • 원하는 포멧(확장자)으로 다운받을 수 있도록 한다.

download.py

# only tv show
from bs4 import BeautifulSoup
import requests

base = "https://www.springfieldspringfield.co.uk/"
show = "view_episode_scripts.php?tv-show="
        
def get_episodes(title):
    url = f'{base}{show}{title}'
    res = requests.get(url)
    soup = BeautifulSoup(res.text, 'html5lib')
    episodes = soup.select('.season-episodes > a')
    return {'status': res.status_code, 'episodes': episodes}

def download_files(title, script, format):
    with open(f'static/scripts/{title}.{format}', 'w', encoding='utf-8') as file:
        file.write(f'{title}\n\n')
        for sentence in script:
            file.write(f'{sentence.strip()}.\n')

def get_scripts(title, format):
    res = get_episodes(title) 
    status = res['status']
    episodes = res['episodes']

    if status != 404:
        for ep in episodes: #에피소드 있는 경우만 다운로드
            url = f'{base}{ep["href"]}'
            res = requests.get(url)
            soup = BeautifulSoup(res.text, 'html5lib')
            h1 = soup.select_one('h1').get_text()
            script = soup.select_one('.scrolling-script-container').get_text().strip()

            # script 정제
            s = ""
            for alph in script:
                if alph != '\n':
                    s = s + alph
                    
            new_script = ' '.join(s.split()).replace(" - ", "").split('.') #다중 공백 & "-" 제거 후 리스트로 변환
            download_files(h1, new_script, format) # txt, hwp, docx

    return {'status': status}

 

2) 사용자 입력 받을 form 생성

index.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>DSS</title>
  </head>
  <body>
    <h1 class="title">Download Scripts from Springfield</h1>
    <form action="\" method="get">
      <div class="form-item">
        <label for="title">🎬 제목</label>
        <input type="text" name="title" id="title" placeholder="TV Show 제목을 입력하세요" required/>
      </div>
      <div class="form-item">
        <label for="format">📃 문서 형식</label>
        <select name="format" id="format">
          <option vlaue="docx">docx</option>
          <option vlaue="hwp">hwp</option>
          <option vlaue="txt">txt</option>
        </select>
      </div>
      <button class="form-item" type="submit">다운로드</button>
    </form>
  </body>
</html>

 

3) GET으로 받은 데이터 가져오기 & 다른 python 파일에 있는 메서드 호출하기

  • GET으로 받은 데이터를 request.args.get('title')의 형식으로 가져올 수 있다. 여기서 titlehtml에서 name속성에 설정한 값이다.
  • download.py에 있는 get_scripts() 함수를 호출하기 위해 import downloaddownload.get_scripts(title, format)의 형식으로 호출한다.

app.py

from flask import Flask, render_template, request
import download

# Flak 앱 서버 인스턴스
app = Flask(__name__)
app.secret_key = "abcde"

# url 패턴 - 라우팅 - 데코레이터
@app.route('/')
def index():
    #get을 통해 전달받은 데이터 확인
    title = request.args.get('title')
    format = request.args.get('format') or "docx" # 기본값을 docx로 설정

    if title and format:
        res = download.get_scripts(title, format) #html의 form에서 받은 데이터를 인자로 전달

    return render_template('index.html')

# 메인 테스트
if __name__ == '__main__':
    app.run(debug=True)

 

 

3. CSS 연동

1) url_for 사용

  • 배포 시 경로를 잘 찾게 하기 위해서 url_for을 사용해 css 파일을 연동한다.

index.html

 <head>
   <link rel="stylesheet" href="{{url_for('static', filename='index.css')}}" />
 </head>

 

2) index.css

길어서 생략 (알아서 작성!)

 

 

4. 결과

  • 소개를 추가로 작성하고 확인한 결과 페이지
  • 올바른 제목을 입력하고 다운로드 버튼을 클릭하면 static/scripts 하위에 스크립트가 저장된다.

 

반응형