Programming/Python 웹 스크래퍼 만들기

Python Flask 로 HTML 에서 For 문 사용

Security Engineer 2023. 1. 5. 21:00

6.6 For Loops

 

[ 이전 게시물 정리 ]

extractors 폴더의 indeed.py 와 wwr.py ( 웹 스크래퍼 코드 ) 를 import 해서

indeed 와 wwr 이라는 변수에 각각 검색값 ( keyword )의 결과인 구인정보를 저장하고,

jobs 라는 변수에 indeed 와 wwr 변수를 합친 결과 ( 구인정보 )를 저장하여

jobs를 template 으로 보내 Flask 가 이를 웹 페이지로 출력하게 만든다.

 

keyword 로 2개의 function 을 호출했으며, 2개의 리스트( indeed, wwr )를 1개의 리스트( jobs )로 합쳤다.

그리고 합친 리스트를 search.html 로 보낸다, Flask 가 웹 페이지로 연결.


이전 게시물에서 URL 에 있는 keyword ( 검색값 ) 을 받아왔다.

그리고 그 keyword 로 indeed jobs, wwr jobs 를 가져와서, 2개를 1개의 jobs 변수로 합쳤다. ( 구인정보 )

그 jobs 변수를 search.html 로 보낸다.

이제는 가져온 jobs 변수를 render 해야한다. ( 구인정보들을 render - 웹 페이지에 출력되게 한다. )

 

< main.py 코드 중 일부 >

@app.route("/search")
def search():
    keyword = request.args.get("keyword")
    indeed = extract_indeedn_jobs(keyword)
    wwr = extract_wwr_jobs(keyword)
    jobs = indeed + wwr
    return render_template("search.html", keyword=keyword, jobs=jobs )

return render_template("search.html", keyword=keyword, jobs=jobs )

→ 여기서 사용한 jobs는 search.html 에서 받은 jobs 이며, 리스트이다.

indeed 변수도 리스트, wwr 변수도 리스트, jobs 변수는 이 2개의 리스트를 합쳐놓은 것이다.

( 각 웹사이트의 구인정보가 리스트 형태로 저장된다. )

이전에 리스트의 각 item 에서 코드를 실행할 수 있는 방법이 있었다.

바로 for 문을 사용해서 반복했었다. ( file.py 코드 처럼 )

 

< file.py 코드 >

def save_to_file(file_name, jobs):
    file = open(f'{file_name}.csv','w',encoding='utf-8-sig')
    file.write('Postition,Company,Location,URL\n')

    for job in jobs:
        file.write(f"{job['position']},{job['company']},{job['location']},{job['link']}\n")

    file.close()

for job in jobs:

→ jobs 변수를 job 변수로 반복하여 jobs 리스트의 item에 각각 실행.

( 처리중인 item은 job 변수로 접근 가능 )

 

사용자에게 jobs 리스트 안의 job 을 보여주기 위해

이런 동작을 search.html 에서 똑같이 반복한다.

( search.html 에서 jobs 리스트를 받기 때문에 쉽게 사용할 수 있다. )

 

Flask 에서 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>
</head>
<body>
    <h1>Search Results for "{{keyword}}":</h1>
    {% for job in jobs %}
    <div>{{job.link}}</div>
    {% endfor %}
</body>
</html>

Flask 에서는 어떻게 for 문을 사용할 수 있을까?

search.html 은 python 코드가 아니라 HTML 이기 때문에 문법이 약간 다르다.

{% for job in jobs %} 이렇게 사용

→ {% 로 시작하고 마지막도 %} 로 끝낸다.

 

{% %}와 {{ }} 문법의 차이가 있다.

{{ }} 는 안에 변수를 넣으면 Flask 가 변수를 값으로 변환해준다.

{% %} 안에는 실행하고 싶은 Python 코드를 넣는다.

 

그리고 Flask 한테 for 문이 끝났다고 알려줘야한다.

→ {% endfor %}

그리고 for 문 안에 사용자가 보게 될 HTML 코드를 작성할 수 있다.

Flask 는 jobs 리스트의 모든 job 마다 HTML 을 보여준다.

job은 회사의 링크, 회사명, 직군 이름, 직장 위치를 가지고 있다.

 

{{job.link}} 는 Flask template 안에서 job 안의 link 에 접근하는 방법이다.

 

< main.py > - 에러 발생 후 변경 완료한 정상 코드

from flask import Flask, render_template, request
from extractors.indeed import extract_indeed_jobs
from extractors.wwr import extract_wwr_jobs

app = Flask("JobScrapper")

@app.route("/")
def home():
    return render_template("home.html", name="james", age=20)

@app.route("/search")
def search():
    keyword = request.args.get("keyword")
    indeed = extract_indeed_jobs(keyword)
    wwr = extract_wwr_jobs(keyword)
    jobs = indeed + wwr
    return render_template("search.html", keyword=keyword, jobs=jobs )

app.run("127.0.0.1")

search.html 코드를 저장하고 main.py 코드를 실행한다.

코드를 실행하고 127.0.0.1:5000 접속 후 검색창에 react 를 검색하니 아래와 같은 에러가 떳었다.

react 검색
search 후 에러
jobs 변수 오류 콘솔창

에러의 원인은 바로 jobs = indeed + wwr 로 변수를 저장했어야 했는데, jobs = indeed + jobs 로 입력해서 발생했다.

main.py 코드를 jobs = indeed + wwr 로 변경하고 다시 실행해본다.

코드 실행 후 127.0.0.1:5000 접속 후 react 검색

react 구인정보 링크
정상 접속 콘솔 창

http://127.0.0.1:5000/search?keyword=react 검색결과 창에서 마우스 우클릭 후 검색 을 누르면 

search.html 에서 작성했던 <div>{{job.link}}</div> 에 해당하는 링크들이 출력되어있다.

( 각 item 에 대해서 만들어진 div )

이제 position, company, loaction, link 를 추가하여 좀 더 직관적으로 변경해본다. ( file. py 참고 )

 

< 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>
</head>
<body>
    <h1>Search Results for "{{keyword}}":</h1>
    {% for job in jobs %}
        <div>
            <span>{{job.position}}</span>
            <span>{{job.company}}</span>
            <span>{{job.location}}</span>
            <a href="{{job.link}}" target="_blank">Apply now &rarr;</a>
        </div>
    {% endfor %}
</body>
</html>

<div>

→ 가상의 레이아웃을 나눈다. 줄 바꿈이 가능 ( Block 속성 ) - 박스형태로 영역 구간 잡힘.

<span>

→ 가상의 레이아웃을 나눈다. 줄바꿈이 불가능 ( Inline 속성 ) - 줄 단위로 영역 설정.

 

<a href="{{job.link}}" target="_blank">Apply now &rarr;</a>

→ job.link 를 a href  을 사용하여 링크로 변경.

→ target="_blank" 사용하여 새로운 웹페이지로 링크를 열수 있게 한다.

→ &rarr 사용하여 우측 화살표(→) 작성.

 

search.html 파일 저장 후 main.py 파일 재실행 후

크롬 열고 127.0.0.1:5000 접속하여 react 접속 후 기다리면 구인정보 스크랩한 결과가 출력된다.

( 혹은 기존에 열어놨던 http://127.0.0.1:5000/search?keyword=react 창을 새로고침 해도 된다. )

react 검색 결과 ( position, company, location, link 포함 )

 

[ 정리 ]

 

Flask 로 HTML template 안에서 For 문을 사용할 수 있다.

<body>
    <h1>Search Results for "{{keyword}}":</h1>
    {% for job in jobs %}
    <div>{{job.link}}</div>
    {% endfor %}
</body>

{% %} 로 for 문 사용 

{% endfor %} 로 for 문 종료

 

{% %}와 {{ }} 문법의 차이가 있다.

{{ }} 는 안에 변수를 넣으면 Flask 가 변수를 값으로 변환해준다. ( {{keyword}} → 실제검색값 )

{% %} 안에는 실행하고 싶은 Python 코드를 넣는다. ( for 문 사용 )

<body>
    <h1>Search Results for "{{keyword}}":</h1>
    {% for job in jobs %}
        <div>
            <span>{{job.position}}</span>
            <span>{{job.company}}</span>
            <span>{{job.location}}</span>
            <a href="{{job.link}}" target="_blank">Apply now &rarr;</a>
        </div>
    {% endfor %}
</body>

<div>

→ 가상의 레이아웃을 나눈다. 줄 바꿈이 가능 ( Block 속성 ) - 박스형태로 영역 구간 잡힘

<span>

 가상의 레이아웃을 나눈다. 줄바꿈이 불가능 ( Inline 속성 ) - 줄 단위로 영역 설정

 

<a href="{{job.link}}" target="_blank">Apply now &rarr;</a>

→ job.link 를 a href  을 사용하여 링크로 변경.

→ target="_blank" 사용하여 새로운 웹페이지로 링크를 열수 있게 한다.

→ &rarr 사용하여 우측 화살표(→) 작성.

 

 

 

 


python 참고 강의

https://nomadcoders.co/python-for-beginners/lobby