본문 바로가기

Python/YouTube Data API v3

[Youtube API] 페이징 구현하기

이번엔 많은 데이터를 가독성 있게 볼 수 있도록 하는 페이징, 즉 페이지네이션 기능에 대해 알아보고 적용해보려 합니다.

 

사실 페이징이 쉬운건 아닌데..(저만 그렇게 느낄 수도...) Flask에서 제공하는 Flask-paginate 라이브러리를 사용하여 쉽게 구현할 수 있답니다. 해당 라이브러리를 선정한 이유는 점프 투 플라스크 강의에서  한글 래퍼런스가 있기 때문입니다.
한글 래러펀스 바로가기

그러나 구현 자체는 쉽지만 해당 라이브러리의 파라미터 수정부분에서 개인적으로 어려웠네요.. 그래도 어째저째 구현한 부분을 공유드리겠습니다.

 

아래 코드는 flask main.py 코드로 웹 서버를 동작시키는 코드입니다.

#import와 main부 생략

@app.route('/search_list', methods=['GET', 'POST'])
def search_list():
    per_page = 10
    page, _, offset = get_page_args(per_page=per_page)

    SearchText = request.args.get('searchTxt')

    if SearchText == "":
        cur.execute("SELECT COUNT(*) FROM youtube.video_list;")
        data = cur.fetchone()
        total = int(data[0])

        cur.execute(
            "SELECT * FROM youtube.video_list ORDER BY no "  # SQL SELECT로 리스트를 가져오기,
            "DESC LIMIT %s OFFSET %s;",  # offset부터 per_page만큼의 리스트를 가져온다.
            (per_page, offset),
        )
        lists = cur.fetchall()
        conn.commit()
    else:
        sql_cnt = "SELECT COUNT(*) FROM youtube.video_list WHERE search_txt LIKE %s;"
        cur.execute(sql_cnt, SearchText)

        data = cur.fetchone()
        total = int(data[0])

        cur.execute(
            "SELECT * FROM youtube.video_list WHERE search_txt LIKE %s "  # SQL SELECT로 포스트를 가져오되,
            "LIMIT %s OFFSET %s;",  # offset부터 per_page만큼의 포스트를 가져옵니다.
            (SearchText, per_page, offset),
        )
        lists = cur.fetchall()
        conn.commit()


    pagination = Pagination(
        page=page,  # 지금 우리가 보여줄 페이지는 1 또는 2, 3, 4
        total=total,  # 총 몇 개의 포스트인지를 미리 알려주고,
        per_page=per_page,  # 한 페이지당 몇 개의 포스트를 보여줄지 알려주고,
        prev_label="<<",  # 전 페이지와,
        next_label=">>",  # 후 페이지로 가는 링크의 버튼 모양을 알려주고,
        format_total=True,  # 총 몇 개의 포스트 중 몇 개의 포스트를 보여주고있는지 시각화,
        href="javascript:goPage({0})",
    )


    return render_template(
        "search_list.html",
        lists=lists,
        pagination=pagination,
        search=True,  # 페이지 검색 기능을 주고,
        bs_version=5
    )
    conn.close()

주석 외 추가 설명을 드리자면 page는 현재 위치한 page 번호, offset은 몇 번째 post부터 보여줄지를, per_page는 얼마 만큼 페이지네이션을 할 것인지 입니다.

페이지네이션이 되는 과정은 다음과 같습니다.

1. 총 포스트 갯수를 파악

2. offset부터 per_page까지의 포스트를 가져온다.

3. 현재 페이지 값(page)이 변경되면 per_page 값 만큼 변경된 값을 시각화 한다.

아래의 코드는 main.py에서 html로 page 값을 넘겨주기 위한 스크립트 부분으로 ajax로 html전체가 아닌 화면에서 표 부부분만 변경 되도록 구현했습니다.

data 구문 안에 있는 page와 searchText로 사용자가 검색한 이름과 page번호를 넘겨주어 페이지 링크를 클릭해도 검색어가 초기화되지 않도록 구현했습니다.

<script>
    var page_num=1;
    function goPage(num){
                page_num=num;
                goList();
    }

    function goList(){
       var url = "http://127.0.0.1:8080/search_list";
       getTodo(url);
    }


    var getTodo = function (url) {
        txt = $('#SearchText').val();
        $.ajax({ //ajax 실행
            url: url,
            dataType: "html",
            data: {
                page: page_num,
                searchTxt : txt
            },
            success: function (result) { //result = data.json 메뉴 데이터
                 $("#list").html(result);
            },
            error : function(a, b, c){
            alert(a + b + c);
        }
        });
    };


$(document).ready(function() {
    goList();
});
</script>
<div id="back">
<body>
<header>
    <div id="logo" style=" cursor: pointer;" onclick="location.href='/'">DevOps 3Team</div>
</header>
<div id="box">
    <div id="search_bar">
        <form>
            검색어 : <input type="text" name="SearchText" id="SearchText"> #사용자에게 검색어를 받는 부분
        </form>
        <button id="btn" type="submit" onclick="goList();">Search</button> #검색 버튼
        <button id="new">New</button> # 데이터 추가용 버튼(미구현)
    </div>
        <div id="list"></div> # 데이터 출력부
</div>

</body>
</div>
</html>

위와 같이 구현하면 사용자가 데이터를 편리하게 확인, 검색 할 수 있습니다.

해당 화면은 아이폰 15를 유튜브에 검색 했을 때 추출한 동영상 데이터를 페이징하여 출력한 화면 입니다.

표의 상단부에 총 게시물 수와 현재 시각화된 데이터 구간을 확인할 수 있으며 표 하단에 페이징이 된 것을 확인할 수 있습니다.

 

다음 포스팅에서는 이미 캡처본 화면에서 확인할 수 있지만, 동영상의 조회수와 좋아요 수를 추출하는 방법을 알아보겠습니다!