Flask란?
플라스크는 Python의 마이크로 웹 프레임워크이다. 다양한 웹 엔진과 붙여서 쓸 수 있고 또 가볍기도 해서 Django와 같이 쓰는 경우도 있다. 코드도 비교적 단순하고, 특히 API 서버를 만들기에 매우 편리하다. 관련된 확장 기능들이 많기 때문이다.
출처: 나무위키
웹 서버 만들기
from flask import Flask
app = Flask("JobScrapper")
@app.route("/")
def home():
return 'Hello Flask!'
app.run("0.0.0.0")
웹 서버 만드는 방법은 간단하다.
몇 줄의 코드 작성으로 홈페이지에 접속한 유저에게 'Hello Flask!'를 보여주는 웹 서버가 생성된다.
replit.com에서 코드를 작성해서 실행하므로 "0.0.0.0"을 넣어주었다.
무엇을 보여줄까?
저번 게시물에서 작성한 JobScrapper를 사용한다.
원하는 키워드를 검색하면 weworkremotely 사이트에서 키워드를 검색하고 스크래핑해서 유저에게 보여준다.
그리고 목록을 다운로드 받을 수 있는 기능도 추가한다.
List를 csv 파일로 만들기
def save_to_file(file_name, jobs):
file = open(f"{file_name}.csv", "w")
file.write("Position,Company,Location,URL\n")
for job in jobs:
file.write(f"{job['position']},{job['company']},{job['location']},{job['link']}\n")
file.close()
file.py를 생성하고 저번 게시물에서 스크랩한 정보(List)를 파일로 생성한다.
HTML 작성하기
HTML 파일은 Main.py와 같은 레벨의 폴더에 'templates'라는 폴더를 생성하고 그 안에 생성한다.
그 이유는 Flask가 templates 폴더 안의 HTML 파일을 검색할 수 있도록 하기 위함이다.
home.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>Job Scrapper</title>
# Pico.css
<link rel="stylesheet" href="https://unpkg.com/@picocss/pico@latest/css/pico.min.css">
</head>
<body>
<main class="container">
<h1>Job Scrapper</h1>
<h4>What job do you want?</h4>
<form action="/search">
<input type="text" name="keyword" placeholder="Write Keyword" />
<button>Search</button>
</form>
</main>
</body>
</html>
유저가 홈페이지에 접속했을 때, 직무를 검색할 수 있는 Input과 버튼을 만든다.
버튼을 클릭하면 /search 페이지로 이동한다.
search.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>Job Scrapper</title>
# Pico.css
<link rel="stylesheet" href="https://unpkg.com/@picocss/pico@latest/css/pico.min.css">
</head>
<body>
<main class="container">
<hgroup>
<h1>Search Results for "{{keyword}}":</h1>
<a target="_blank" href="/export?keyword={{keyword}}">Export to file</a>
</hgroup>
<figure><table role="grid">
<thead>
<tr>
<th>Position</th>
<th>Company</th>
<th>Location</th>
<th>Link</th>
</tr>
</thead>
<tbody>
{% for job in jobs %}
<tr>
<td>{{job.position}}</td>
<td>{{job.company}}</td>
<td>{{job.location}}</td>
<td><a href="{{job.link}}" target="_blank">Apply now →</a></td>
</tr>
{% endfor %}
</tbody>
</table></figure>
</main>
</body>
</html>
스크랩해온 데이터를 Loop하면서 보여준다.
데이터는 테이블로 표시된다.
CSV 파일로 만든 데이터를 다운로드 받을 수 있도록 버튼을 추가하고 다운로드 페이지로 이동하도록 만든다.
{{ }} : 변수를 사용할 수 있다.
{% %} : for 구문 등 로직을 사용할 수 있다.
Pico.css
Pico.css는 우리가 작성한 못생긴 HTML 사이트를 간단한 로직을 사용해서 미려하게 만들 수 있는 툴이다.
다양한 방법으로 사용할 수 있는데, 나는 HTML <head>에 로직을 추가하는 방법을 사용했다.
<main class="container"> : 콘텐츠를 중앙에 배치한다.
<table role="grid"> : 한 줄마다 색이 다르게 된다. (SAP ALV Layout의 zebra 옵션과 비슷하다..)
<figure> : 페이지를 가로로 스크롤 할 수 있게 된다. 모바일로 접속해도 가로로 스크롤 할 수 있다. 반응형으로 설계 가능.
Main.py
from flask import Flask, render_template, request, redirect, send_file
from extractors.wwr import extract_wwr_jobs
from file import save_to_file
app = Flask("JobScrapper")
db = {} # 데이터베이스
@app.route("/")
def home():
return render_template("home.html")
@app.route("/search")
def search():
keyword = request.args.get("keyword")
if keyword == None: # 키워드 미입력 시
return redirect("/")
if keyword in db: # 키워드가 데이터베이스에 있으면
jobs = db[keyword]
else: # 키워드가 데이터베이스에 없으면
wwr = extract_wwr_jobs(keyword)
jobs = wwr
db[keyword] = jobs # 스크랩 해온 데이터 -> 데이터베이스
return render_template("search.html", keyword = keyword, jobs=jobs)
@app.route("/export") # 데이터 다운로드
def export():
keyword = request.args.get("keyword")
if keyword == None:
return redirect("/")
if keyword not in db:
return redirect(f"/search?keyword={keyword}")
save_to_file(keyword, db[keyword])
return send_file(f"{keyword}.csv", as_attachment=True)
app.run("0.0.0.0")
유저에게 키워드를 받고(request), 데이터를 보내주고(render_template), 리다이렉트하고(redirect), 파일을 전송하기(send_file)위해서 import 한다.
db를 사용한 이유는, 유저가 검색한 키워드를 계속 스크랩 할 수 있지만 매번 수행하면 좋지 않기 때문에 속도 향상을 위해 사용했다. (실제 데이터베이스는 아니다..)
request.args.get("keyword") : 유저가 입력한 키워드를 받는다.
render_template( ) : 사용자에게 html과 함께 파라미터도 보내줄 수 있다.
redirect( ) : 유저가 키워드를 입력하지 않았으면 홈페이지로 보내고, 데이터베이스에 없는 데이터를 검색하면 키워드를 스크랩해올 수 있도록 한다.
send_file( ) : 유저가 웹페이지에서 Export to File 버튼을 선택하면 /export 페이지로 이동하게 되고, file.py의 save_to_file()로 만들어진 csv 파일을 다운로드하게 된다.(as_attachement=True)
결과
홈 페이지
처음 접속한 홈페이지. 검색하고 싶은 키워드를 넣고 Search 버튼을 클릭할 수 있다. (Pico.css를 사용해서 확실히 이쁘다..)
검색 페이지
Java를 검색한 결과이다. 데이터가 잘 표시되고 링크로 잘 이동하며 Export to file을 클릭하면 데이터를 csv 파일로 다운로드 받을 수 있다.
느낀 점
Flask는 Python으로만 작성하면 심심한 코드를 웹 서버와 HTML, CSS를 사용해서 유저에게 보여줄 수 있는 웹사이트를 아주 간단하게 제작할 수 있는 장점이 있는 것 같다.
마이크로 프레임워크라고 하지만, 강력한 기능을 많이 제공하고 단순한 로직으로 쉽게 사용이 가능하다.
앞으로 간단하게 웹사이트를 제작해보고 싶으면 사용할 것 같다.
'Python' 카테고리의 다른 글
[Python] 구글 바드 비공식 API 사용해보기 (+ FastAPI) (0) | 2023.07.03 |
---|---|
[VSCode] 코딩 단축키 (0) | 2022.10.31 |
[Python] BeautifulSoup를 활용한 웹 크롤링 예제 (0) | 2022.09.05 |