축구선수 몸값 분석 웹 크롤링 (11) - 헤더 및 디자인 꾸미기, 객체지향 코드로 변경

1. 결과표 본문(헤더, 색상, 글꼴) 디자인 변경

  • 해당 디자인은 https://www.futbin.com/ 사이트를 참고하여 디자인하였다.
    (축구 관련 컨셉에 맞는 깔끔한 디자인을 선호하였는데 이에 적합하였다고 판단)
  • 글꼴 및 색상 또한 해당 사이트를 검사하여 사용하였다. 색상 코드 : #55cca2, 글꼴 : Poppins
  • 헤더 css에 box-shadow 속성을 추가하여 헤더와 본문의 구분이 자연스럽도록 하였다.

Footer 추가할 예정

2. 크롤링 파일 객체지향 코드로 변경

  • 기존의 크롤링 파일은 객체지향 방식의 코드가 아니라 각각의 변수들을 관리하기가 어려웠다.
  • 입력 숫자, 정렬 포지션, 정렬 타입을 멤버 변수로 하여 크롤링 객체의 여러 함수들이 접근할 수 있도록 하였다.
  • 그 결과 함수들의 중복되거나 코드가 긴 부분들을 따로 함수로 관리하여 가독성을 높이는 작업을 할 수 있었다.
# 변경 전 코드
pos_dict = {'AL':"alle",'GK':"Torwart",'DF':"Abwehr",'MF':"Mittelfeld",'FW':"Sturm"}

def show_valueList(list_num, typeList, position):
    list_num = int(list_num)
    url = "https://www.transfermarkt.com/"

    headers = {'User-Agent' : "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36"}
    player_list=[]
    # pos_dict value 값 저장
    pos_value = pos_dict.get(position)
    
# 변경 후 코드
class transferCrawling:
    def __init__(self, list_num, typeList, pos,sort):
        # 포지션 별로 다른 url 크롤링  
        self.pos_dict = {'ALL':"alle",'GK':"Torwart",'DF':"Abwehr",'MF':"Mittelfeld",'FW':"Sturm"}
        # index.html에서 입력받는 값들
        self.list_num = list_num
        self.typeList = typeList
        self.pos = pos
        self.sort = sort
@app.route('/', methods=['POST'])
def show_result():
    list_num = request.form["listNum"]
    # 입력 값 없으면 그냥 index 반환
    if list_num == "" or list_num is None:
        return render_template('index.html')
    else:
        typeList = request.form.getlist('type')
        pos = request.form['position']
        sort = request.form['sorting']
		
        # 변경 전 코드
        df = tf.show_valueList(list_num, typeList, pos)
        df = tf.sort_valueList(sort)
        
        # 변경 후 코드
        trans = tf.transferCrawling(list_num,typeList,pos,sort)
        df = trans.show_valueList()
        # dataframe html 변환
        df_html = df.to_html(justify='left', classes='table')

        group_data = trans.show_nationList()
        # nation_dataframe html 변환
        gd_html = group_data.to_html(index=False, justify='left',classes='table')
        # dataframe column 개수 추출
        index_num = trans.get_size()

        return render_template('result.html', df_html=df_html, gd_html=gd_html, index_num = index_num, pos = pos)

3. 문제 해결

 

show input value of html form in another field

I have a html form with fields that are filled in by the user. I also have radio buttons that when clicked show a specific piece of text in a textarea. What I want to do is to take the given name v...

stackoverflow.com

  • 결국 app.py의 뷰함수에서 받아온 list_num(입력 숫자 값)을 render_template에 같이 넘겨 주어서 이를 html에서 Jinja 템플릿으로 처리하는 방식을 사용하였다.
# app.py 뷰함수
list_num = request.form["listNum"]

return render_template('result.html', df_html=df_html, gd_html=gd_html, index_num = index_num, pos = pos)

# result.html 헤더
<header id="pageHeader">
        <div class="title-header">
            <h1>Transfermarkt Most Valuable {{pos}} Top {{index_num}} </h1>
        </div>
</header>

4. 주의 사항

  • VScode에서 Ctrl + Shift + L 단축키를 사용하면 공통되는 변수를 한번에 변경이 가능하다.
    그러나 대소문자를 구분하거나 겹치는 부분이면 다 선택된다는 단점이 있어서 코드 수정시 잘 확인해야 한다.
  • df를 self.df로 수정해야하는 상황에서 딕셔너리 키 중 하나인 'DF'까지 선택되어 같이 수정되어 버그가 발생하였다.