본문 바로가기

Python으로 웹 스크래퍼 만들기

Python으로 웹 스크래퍼 만들기 복습 13일차[Export, File Download, CSV 생성, send_file, as_attachment] (Feat. 노마드코더)

본 포스팅은 노마드코더님의 온라인 강의에 대한 복습을 기록하기 위한 포스팅입니다.

※ 본 포스팅의 내용은 강의를 들은 후 필자의 개인적인 의견을 기재한 것이니, 정답이 아닐 수 있음을 참고하십시오.

강의 소개 : 파이썬으로 웹 스크래퍼 만들기 (2주 완성반)
  -. 내용 : 파이썬 기초 (타입, 변수, 함수, 클래스 등 및 웹 스크래퍼 코드 작성법)
  -. 비용 : 100% 무료 강의
  -. 비고 : 한글 자막 제공 / 강의 100% 완료 시 10% 할인 쿠폰 제공
온라인 강의 : https://nomadcoders.co/
    /    풀스택 개발자 로드맵 : https://nomadcoders.co/roadmap
유튜브 채널 : https://www.youtube.com/channel/UCUpJs89fSBXNolQGOYKn0YQ
 

노마드 코더 Nomad Coders

한국인 린과 콜롬비아인 니꼴라스의 프로젝트 "노마드 코더" 입니다. 2015년 떠나, 현재까지 원하는 곳에서 일하며, 살고 있습니다. + + Nomad Academy: https://nomadcoders.co

www.youtube.com


 

#4.7 Export Route & #4.8 File Download

  1) try ~ except 로 예외처리 하기

""" main.py """

from flask import Flask, render_template, request, redirect
from scrapper import get_jobs

app = Flask("Flask")

db = {}

@app.route("/")
def home():
    return render_template("home.html")


@app.route("/report")
def report():
    word = request.args.get("word")

    if word:
      word = word.lower()
      
      if word in db:
        print("It is in DB")
        jobs = db.get(word)
      else:
        print("It isn't in DB")
        jobs = get_jobs(word)
        db[word] = jobs

    else:
      return redirect("/")

    return render_template(
      "report.html",
      searchingBy = word,
      jobs = jobs,
      resultsNumber = len(jobs)
    )


@app.route("/export")
def export():
  try:
    word = request.args.get("word")
    
    if not word:
      raise Exception()
    word = word.lower()
    jobs = db.get(word)
    if not jobs:
      raise Exception()
    
    return f"Generate CSV for {word}"

  except:
    return redirect("/")

  return

app.run(host="0.0.0.0")

    -. "http://flask--ilionash.repl.co/export" 로 접속을 시도하면 Exception이 발생합니다.

        * try: ~ except:

        ** 정상 처리 코드는 try: 블록에 / 예외 발생 시 코드는 except: 블록에 작성합니다.

        ** 즉, try 블록 처리중 에러 발생 혹은 개발자가 예외처리를 발생 시키는 경우 except블록으로 이동합니다.

        * if not word: ~ raise Exception()

        ** "word 변수가 없을 경우 except블록으로 이동해라"라는 뜻입니다.

        ** 위 구문과 같이 실제로는 에러가 아니지만 같이 개발자가 임의로 예외처리를 발생시키는 경우도 있습니다.

 

Python으로 웹 스크래퍼 만들기 복습 13일차 1

    -. "word" Argument가 있을 경우에는 정상적으로 작동하는 것을 보실 수 있습니다.

 

""" templates/report.html """

<!DOCTYPE html>
<html>

<head>
	<title>Job Search</title>
  <style>
    section {
      display:grid;
      grid-template-columns: repeat(4, 1fr);
    }
  </style>
</head>

<body>
	<h1>Search Results</h1>
  <h3>Found {{resultsNumber}} results for: {{searchingBy}}</h3>
  <a href="/export?word={{searchingBy}}">Export to CSV</a>
  <section>
    <h4>Title</h4>
    <h4>Company</h4>
    <h4>Location</h4>
    <h4>Link</h4>
    {% for job in jobs %}
      <span>{{job.title}}</span>
      <span>{{job.company}}</span>
      <span>{{job.location}}</span>
      <a href="{{job.link}}" target="_blank">Apply</a>
    {% endfor %}
  </section>
</body>
</html>

Python으로 웹 스크래퍼 만들기 복습 13일차 2

    -. report.html에 Export to CSV 링크 생성하기

 

 

  2) CSV 파일 생성 및 다운로드하기

""" expoter.py """

import csv

def save_to_file(jobs, word):
  f = open(f"{word}.csv", "w")
  w = csv.writer(f)
  w.writerow(["title", "company", "location", "link"])
  for job in jobs:
    w.writerow(list(job.values()))
  
  return
""" main.py """

from flask import Flask, render_template, request, redirect, send_file
from scrapper import get_jobs
from expoter import save_to_file as save

app = Flask("Flask")

db = {}

@app.route("/")
def home():
    return render_template("home.html")


@app.route("/report")
def report():
    word = request.args.get("word")

    if word:
      word = word.lower()
      
      if word in db:
        print("It is in DB")
        jobs = db.get(word)
      else:
        print("It isn't in DB")
        jobs = get_jobs(word)
        db[word] = jobs

    else:
      return redirect("/")

    return render_template(
      "report.html",
      searchingBy = word,
      jobs = jobs,
      resultsNumber = len(jobs)
    )


@app.route("/export")
def export():
  try:
    word = request.args.get("word")
    
    if not word:
      print("Not Word!!!")
      raise Exception()
    word = word.lower()
    jobs = db.get(word)
    if not jobs:
      raise Exception()
    
    save(jobs, word)

    return send_file(
      f"{word}.csv",
      mimetype='text/csv',
      as_attachment=True,
      attachment_filename=f"{word}.csv"
    )

  except:
    return redirect("/")

  return

app.run(host="0.0.0.0")

    -. expoter.py 파일을 생성하고, 위 코드와 같이 작성합니다. (코드 설명은 8일 차 복습에서 하였으므로 생략합니다.)

    -. main.py 파일을 위 코드와 같이 수정합니다.

        * from expoter import save_to_file as save

        ** expoter.py 파일의 save_to_file Function을 save라는 이름으로 import 해줍니다.

        * return send_file(

              f"{word}.csv",

              mimetype='text/csv',

              as_attachment=True,

              attachment_filename=f"{word}.csv"

          )

        ** send_file : Flask에서 "send_file" Function을 import 해주어야 합니다.

        ** f"{word}.csv" : 파일 이름

        ** mimetype='text/csv' : 파일 형식

        ** as_attachment=True : Header 정보와 함께 보내기 위해 사용 (없으면 확장자를 못 찾음)

        ** attachment_filename=f"{word}.csv" : 저장하려는 이름첨부 파일의 이름다른 경우 첨부 파일의 이름

Python으로 웹 스크래퍼 만들기 복습 13일차 3

    -. Chrome에서 Export to CSV 링크를 클릭하면 파일명과 확장자를 찾지 못하고 "export"로 저장됩니다.

Python으로 웹 스크래퍼 만들기 복습 13일차 4

    -. IE, Edge, Firefox 등에서는 정상적으로 작동합니다. (위 사진은 Firefox)

 

 

※ 본 포스팅의 내용은 강의를 들은 후 필자의 개인적인 의견을 기재한 것으로,

   정답이 아닐 수 있음을 참고하십시오.

 


이상으로 Python으로 웹 스크래퍼 만들기 복습 13일 차를 마치겠습니다.

 

Python으로 웹 스크래퍼 만들기 복습 13일차 5