이번 포스팅에서는 추출한 데이터를 csv파일로 만들고 flask 맛보기로 웹서버에 웹 스크래퍼가 가져온 데이터를 뿌려볼 것이다.
파일로 내보내는 save_to_file 함수 생성
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()
open()은 파이썬 내장함수 이므로 따로 import할 필요없이 바로 쓸 수 있다.
main.py에 넣어도 되지만 file.py로 분리해 주는 것이 좋다.
최종 main.py 코드
from extractors.indeed import extract_indeed_jobs
from extractors.wwr import extract_wwr_jobs
from file import save_to_file
keyword = input("What do you want to search for?")
indeed = extract_indeed_jobs(keyword)
wwr = extract_wwr_jobs(keyword)
#리스트 합치기
jobs = indeed + wwr
save_to_file(keyword, jobs)
main.py 코드는 위와 같다.키워드에 해당하는 검색 결과값을 파일로 바로 저장해주는 프로그램이 완성되었다.
무료 강의는 여기서 끝나지 않았다..!
Flask 맛보기 및 html 코드 작성
Flask는 파이썬의 마이크로 웹 프레임워크다.
여기서는 html 코드를 렌더링 해준다. Flask에 대해 자세한 내용은 따로 포스팅을 해야겠다.
Flask 맛보기를 하면서 여러 사항이 다음과 같이 변경되었다.
(해당 코드는 replit에서 작동되도록 작성되었다.)
main.py
1. 가짜 데이터베이스는 검색된 것을 새로고침하면 또 불러올때를 방지하기 위해 만든다. '가짜'인 이유는 서버가 켜져있을때만 유지되기 때문이다. 간단히 dictionary 형태로 만든다.
2. @app.route("/search") 는 데코레이터이고, /search url로 이동해야 데코레이트 하는 함수 search()가 실행 된다.
3. keyword가 비어있을 경우 root(/)로 redirect 해줘서 오류 방지한다.
3-1. keyword가 db에 있으면 jobs 리스트에 db 내용을 할당한다.
3-2. keyword가 db에 없는, 즉 처음 입력된 값이라면 extract_***_jobs() 함수들을 실행하여 데이터를 추출한다.
4. 데이터 추출 후 search.html 을 렌더링한다.
5. /export url로 이동시 keyword를 받아 비어있는지, db에 있는지 체크 후 해당 데이터를 csv파일로 저장한다.
from flask import Flask, render_template, request, redirect, send_file
from extractors.indeed import extract_indeed_jobs
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:
indeed = extract_indeed_jobs(keyword)
wwr = extract_wwr_jobs(keyword)
jobs = indeed + 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") #replit이 웹서버를 쓰려는걸 감지, 따로 쓰는 서버 없이도 돌아감, User의 request를 받음
Flask 사용할 때 html, css 작성시 주의 사항
Flask가 인식하려면 아래 두가지 사항을 지켜야 한다.
1. main.py와 같은 레벨에 templates 폴더를 생성한다.
2. templates 폴더 하위에 html, css를 작성한다.
home.html 코드는 다음과 같다.
해당 프로젝트에서는 간단히 pico css를 사용했다.
<!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>
<link rel="stylesheet" href="https://unpkg.com/@picocss/pico@1.*/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 please">
<button>Search</button>
</form>
</main>
</body>
</html>
search.html 작성시 두가지 문법을 새로 알게 되었다.
1. html에서 변수를 받아서 쓸 때는 {{변수}}로 작성해야 한다.
2. Flask로 html코드에 파이썬 코드를 작성할 수 있는데 앞뒤로 {% 파이썬 코드 %} 를 붙여야 한다.
여기서는 for 문을 작성한다.
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>
<link rel="stylesheet" href="https://unpkg.com/@picocss/pico@1.*/css/pico.min.css">
</head>
<body>
<main class="container">
<hgroup>
<h1>Search Result for "{{keyword}}":</h1>
<a 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 %} <!--Flask에서 파이썬 코드 쓰기-->
<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>
실행화면
replit에서 실행하면 다음과 같이 정상 작동한다.
수업에서는 replit으로 완료했지만 무언가 아쉬웠다.
사유: vscode로도 실행이 되길 바람
그래서 다음 포스팅에서는 vscode에서 이 코드가 정상적으로 실행되도록 리팩토링을 해볼것이다.
일단 완성!
해당 포스팅은 노마드 코더의 무료 강의 수강 후 개인 공부한 내용입니다.
강의 링크
https://nomadcoders.co/python-for-beginners/lobby
'💻dev > 🐍Python' 카테고리의 다른 글
Python | 함수와 메서드의 차이, 더이상 헷갈리지 말자! (0) | 2023.03.17 |
---|---|
Python | 파이썬 웹 스크래퍼 만들기 - 04 (0) | 2023.03.09 |
Python | 파이썬 웹 스크래퍼 만들기 - 02 (0) | 2023.03.04 |
Python | 웹 크롤링이랑 웹 스크래퍼 뭔 차이임? (0) | 2023.03.04 |
Python | 파이썬 웹 스크래퍼 만들기 - 01 (0) | 2023.03.04 |