report 페이지 설정-스크랩기능 불러오기

YEONGHUN KO·2021년 11월 16일
0

PYTHON - SCRAPPER

목록 보기
7/17
post-thumbnail

1. report 페이지 설정

앞서 flower.html 파일에서 입력값을 report 페이지로 보낸다고 했었다. 그 페이지를 설정하는 방법을 배워보자.

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


db = {} 
# database를 만들어준 이유: 한번 검색하면 여기에 저장되어 나중에 똑같은걸 검색할때 여기서 바로 꺼내서 시간을 줄일 수 있도록
# db를 제일 상위에 위치한 이유: 새로고침해도 안에 저장된 data가 그대로 있어야 하므로.

@app.route('/report')
def report():
    word = request.args.get('word').lower() # url을 보면 a = b 처럼 dict 형태가 보임 그중에서 word= $$ 해당하는 $$를 뽑아내는거임. 
    # 그리고 대문자를 입력했을 경우를 대비해 소문자로 바꾸어줬음.    
    if word: #If word has value
        fromDb = db.get(word) # db 안에 저장된 jobs data를 꺼내오기. 
        if fromDb: 
        # 만약 그게 있다면 그걸 jobs라고 다시 지정함. jobs 라고 지정했기 때문에 형태가 생겼고 ,report.html 같은 다른곳에서 사용가능해짐.
            jobs = fromDb
        else: # db에 저장되게 없으면 저장해라. {key = word, value =  get_jobs(word)}
            jobs = get_jobs(word) 
            # word 가 so.py에서 url 로 바뀌었고 필요한곳에 사용되도록 수정했다.
            #(기존 URL 은 python만 search 가능하도록 했지만 지금은 입력하는 족족 search 되도록 해야하므로.) 
            db[word] = jobs 
    else: #If word is None
        return redirect("/") # word가 None 이면 홈으로 경로를 재설정한다.(redirect 를 import 해줌.)
    return render_template("report.html",
    searchingword = word, 
    searchingrResult = len(jobs), 
    jobs = jobs[:10] # 이렇게 하면 최초로딩시간이 조금 더 줄어든다
    ) 
    # 그럼 report.html 상에서 {{searchingword}}를 word 로 치환한다.
    # 이러한 과정을 'rendering' 이라고 한다.
    # 그리고 대박!! 버그 발생했을때, 논리를 공책에 적고 라인에 번호를 매긴다음, 번호가 지나갈때마다 어떤일이 일어나는지 적으면서 눈으로 확인하자! ​
    # 왼쪽페이지 에는 코드를, 오른쪽 페이지에는 번호를 적고, 각 번호에 어떤일이 일어나는지 적자. 그렇게 해서 오늘 버그가 왜 발생했는지 알아냈다.
    # internal server error 가 발생했었는데 알고보니 if word: jobs = get_jobs(word)를 추가했기 때문이었다.

이렇게 해서 so.py안에 있는 get_jobs() 함수를 불러와 scrap 기능을 사용하게 된다. 이때 so.py안에 코드를 몇개 수정해야한다. 아래 코드를 보자

def so_last_page(url):
    result = requests.get(url)
    # word 로 입력된 url 이 인자로 들어감.

def extract_so_jobs(last_page, url):   
    jobs = [] 
    for page in range(last_page)[:10]:
        
        print(f"Scrapping SO Page:{page}")
        result = requests.get(f"{url}&pg={page + 1}")
        soup = BeautifulSoup(result.text, "html.parser")
    # 여기도 마찬가지.

def get_jobs(word):
    url =f"https://stackoverflow.com/jobs?q={word}&sort=i" 
    # get_jobs()안에 들어가는 값은 유동적이어야 하므로 f-string 을 사용해야한다. 그래서 url을 다음과 같이 추가하였다.
    last_page = so_last_page(url)
    so_jobs = extract_so_jobs(last_page, url) # 인자를 2개 넣을 수 있다.
    return so_jobs

2. report.html 설정

so.py를 수정했으면 이제 report 함수를 통해 랜더링된 report.html 을 살펴보자. 여기서 배울 것은 render_template 함수를 통해 치환하는 코드를 알아보는것이고, html 안에서의 for loop을 통해 grid 표를 만들어보는것이다.

그리고 main.py에서 랜더링 했던 변수양쪽에 중괄호 2개를 씌어야한다.

<!DOCTYPE html>
<html>
    <head>
        <title>
            report result
        </title>
        <style>
            section {
                display: grid;
                gap:20px;
                grid-template-columns: repeat(4, 1fr);
             } /* 설정된 section을 css를 통해 grid로 만들어준다 */
        </style>
    </head>        
    <body>
        <h1>
            Searching results         
        </h1>
        <h3>
            You've got results for searchingword. number of the result: searchingrResult
        </h3>
        <!-- 표만드는 법 -->
        <section>   
            <h4>title</h4>
            <h4>company</h4>
            <h4>location</h4>
            <h4>link</h4>
             {% for job in jobs %} <!-- for loop 함수를 html 에서 돌리려면 양쪽에 있는 저 기호를 추가하면 끝! report함수에서 rendering 할때 jobs = jobs[:10] 를 추가했는데 여기 for loop에 사용되는 것이다.-->
               <span>job.Title</span> <!-- 여기서도 rendering을 쓴다( 양쪽 끝에 중괄호 두개를 쓴다 ) -->
               <span>job.Company</span>
               <span>job.location</span>
               <a href="job.link" target = "_blank">Apply</a>
            {% endfor %} <!-- for loop 함수를 닫기 -->              
        </section>
        <!-- 위에 css 코드와 더불어 표를 만드는 방법이다. 매우 쉽고 직관적이다. csv 파일을 만드는것과 상당히 닮아있다. -->        
    </body>    
</html>

그럼 다음 글에서 마지막으로 파일을 export 하여 다운받는 법을 알아보자.

profile
'과연 이게 최선일까?' 끊임없이 생각하기

0개의 댓글