 
  Django 포스팅
Doyeon0430 | 2023년 08월 03일
 
      이번시간에는 XML 파일로 구성된 API를 자바스크립트로 가져오겠습니다.
이전 포스팅에서 파이썬의 BeautifulSoup를 사용했었는데 버퍼링이 생기면서 서버가 느려졌습니다.
그래서 서버에 접속할 때 불러오는 방식이 아닌 미리 접속한 후에 불러오는 최적화를 시켜줬습니다.
이러한 방식은 자바스크립트에 fetch 함수로 쉽게 표현할 수 있습니다.
fetch 함수는 자바스크립트 문법으로 비동기 방식으로 데이터를 가져오는 내장 함수입니다.
fetch 함수 문법
fetch(url, options)
    .then(response => Method(response))
    .then(data => process(data))
    .catch(error => Error(error))
    .finally(() => Finally());response는 서버로부터 받은 응답을 처리합니다.
data는 응답받은 데이터를 처리합니다.
catch는 응답에 실패할 경우 오류를 처리합니다.
finally는 요청이 끝났을 때 메소드를 수행합니다.
https://www.kobis.or.kr에서 데이터를 가져올 때 response를 거칩니다.
응답에 성공하면 data / 응답에 실패하면 catch를 호출합니다.
마지막에 finally로 요청을 마무리합니다.
이 게시물은 파이썬의 웹 프레임워크인 Django를 기반으로 제작되었습니다.
views.py에서 새로운 변수를 선언하고 html과 css로 테이블 형식을 만들었습니다.
1. views.py
from datetime import datetime, timedelta
today = datetime.today()
yesterday = today - timedelta(days=1)
target_date = yesterday.strftime("%Y%m%d")
key = env('API_KEY')
numbers = range(1, 11)API url에 사용할 날짜와 key값을 넣어봤습니다.
또한 순위를 나타내기 위해 1부터 10까지 범위를 추가했습니다.
2. HTML 코드
<div class="tag_cap">대한민국 일별 박스오피스</div>
<div id="tableContainer">
    <div id="loadingSpinner"></div>
    <table class="container tag_table" id="movieTable">
        <caption style="text-align: left; caption-side: top; font-weight: bold;">[{{ yesterday_str }} 기준]</caption>
        <thead>
            <th>No</th>
            <th>영화 제목</th>
            <th>개봉일</th>
            <th>누적 관객수</th>
        </thead>
        <tbody id="movieTableBody">
            {% for i in numbers %}
            <tr>
                <td style="font-weight: bold; width: 5%;" id="rank{{ i }}">{{ i }}</td>
                <td style="text-align: left;" id="movieNm{{ i }}"></td>
                <td id="openDt{{ i }}"></td>
                <td id="audiAcc{{ i }}"></td>
            </tr>
            {% endfor %}
        </tbody>
        <caption>제공: 영화진흥위원회 API</caption>
    </table>
</div>
3. CSS 코드
/* 테이블 css */
.tag_cap {
    font-size: 1.5rem;
    font-weight: 900;
    text-align: center;
    margin-bottom: 0.5rem;
}
.tag_table thead th {
    padding: 0.5rem 0;
    border-top: 2px solid gray;
    border-bottom: 2px solid gray;
    text-align: center;
}
.tag_table tbody td {
    padding: 0.5rem 0;
    text-align: center;
    border-bottom: 1px solid rgb(196, 196, 196);
}
.tag_table caption {
    text-align: end;
}
#tableContainer {
    position: relative;
}
/* 로딩 스피너 */
#loadingSpinner {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    border: 4px solid rgba(0, 0, 0, 0.8);
    border-top: 4px solid #ffffff;
    border-radius: 50%;
    width: 40px;
    height: 40px;
    animation: spin 1s linear infinite;
    display: none;
}다음으로 자바스크립트를 통해 데이터를 가져오겠습니다.
자바스크립트 fetch 함수로 XML 데이터들을 가져옵니다.
추가적으로 테이블에 값을 삽입하고 로딩 스피너를 작동시킬 겁니다.
1. JavaScript 코드 - 로딩 스피너
function showLoadingSpinner() {
    const loadingSpinner = document.getElementById('loadingSpinner');
    loadingSpinner.style.display = 'block';
}
function hideLoadingSpinner() {
    const loadingSpinner = document.getElementById('loadingSpinner');
    loadingSpinner.style.display = 'none';
}
2. JavaScript 코드 - 테이블
function renderMovieList(movieList) {
    for (const [index, movie] of movieList.entries()) {
        const rankCell = document.getElementById(`rank${index + 1}`);
        const movieNmCell = document.getElementById(`movieNm${index + 1}`);
        const openDtCell = document.getElementById(`openDt${index + 1}`);
        const audiAccCell = document.getElementById(`audiAcc${index + 1}`);
        rankCell.innerText = movie.rank;
        movieNmCell.innerText = movie.movieNm;
        openDtCell.innerText = movie.openDt;
        audiAccCell.innerText = `${movie.audiAcc}명`;
    }
}위에서 for문을 사용해 테이블 id를 순차적으로 정렬했습니다.
그렇기에 자바스크립트에서도 값을 나열하고 테이블에 삽입해야합니다.
3. JavaScript 코드 - fetch 함수
const apiurl = '{{ key }}';
const day = '{{ target_date }}';
function fetchMovieData() {
    showLoadingSpinner(); // 로딩창 시작
    fetch(`https://www.kobis.or.kr/kobisopenapi/webservice/rest/boxoffice/searchDailyBoxOfficeList.xml?key=${apiurl}&targetDt=${day}`)
        .then(response => response.text())
        .then(data => {
            // XML 데이터를 파싱합니다.
            const parser = new DOMParser();
            const xmlDoc = parser.parseFromString(data, 'text/xml');
            const movies = xmlDoc.getElementsByTagName('dailyBoxOffice');
            // 영화 데이터를 담을 배열
            const movieList = [];
            // 영화 데이터를 반복하면서 배열에 데이터를 추가합니다.
            for (let i = 0; i < movies.length; i++) {
                const movie = movies[i];
                const rank = movie.querySelector('rank').textContent;
                const movieNm = movie.querySelector('movieNm').textContent;
                const openDt = movie.querySelector('openDt').textContent;
                const audiAcc = parseInt(movie.getElementsByTagName('audiAcc')[0].textContent).toLocaleString();
                movieList.push({ rank, movieNm, openDt, audiAcc });
            }
            renderMovieList(movieList);
            localStorage.setItem('box_office_data', JSON.stringify({ 'movie_list': movieList }));
        })
        .catch(error => {
            console.error('영화 데이터를 가져오는 중 에러 발생:', error);
        })
        .finally(() => {
            hideLoadingSpinner(); // 로딩창 끝
        });
}
window.onload = function () {
    fetchMovieData();
};
맨 처음 페이지가 onload되면 fetchMovieData가 실행됩니다.
함수가 실행되면서 로딩 스피너가 작동합니다.
그리고 fetch 함수를 통해 API 데이터들을 불러오고 값들은 renderMovieList로 보냅니다.
4. fetch 함수 결과화면
댓글 (0)
간편 댓글 작성