wisePocket

[JSON] Fetch, 공공 데이터 OpenAPI 활용 실습 - 2 본문

Python&Flask Tutorials, AWS EB/2nd WEEK JavaScript, JQuery, Fetch, API

[JSON] Fetch, 공공 데이터 OpenAPI 활용 실습 - 2

ohnyong 2023. 7. 2. 11:42

이전 "서울시 실시간 미세먼지 상태" 와 비슷한 예제이다

따라서 이전 코드를 재활용해서 어느 부분을 고쳐나가는지 실습해봤다.

 

1. "서울시 따릉이" 위치를 확인할 수 있는 간단한 HTML 페이지를 생성

기초 HTML 뼈대는 다음과 같다.

이전 예제와 특별히 다른 부분은 없지만

button 태그에서 onclick event로 q1이라는 함수를 불러오고 fetch가 작동하는 방식이 똑같다.

하지만 리스트 태그를 이용한것과 달리

table태그로 좀 더 보기좋게? 항목을 보여주는 방식이 변경되었다.

하지만 주요 목표는 동일하게 데이터를 불러오고 불러온 데이터를 html에 기록하도록 하는 것이 목표이다.

현재 데이터처럼 보여지는 내용들은 아직 데이터 통신 없이 직접 텍스트가 하드코딩된 예시일 뿐이다.

<!doctype html>
<html lang="ko">

<head>
    <meta charset="UTF-8">
    <title>Fetch 연습하고 가기!</title>
    <!-- JQuery를 import 합니다 -->
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>

    <style type="text/css">
        div.question-box {
            margin: 10px 0 20px 0;
        }

        table {
            border: 1px solid;
            border-collapse: collapse;
        }

        td,
        th {
            padding: 10px;
            border: 1px solid;
        }
    </style>

    <script>
        function q1() {
            // 여기에 코드를 입력하세요

                    }
    </script>

</head>

<body>
    <h1>Fetch 연습하자! 2</h1>

    <hr />

    <div class="question-box">
        <h2>2. 서울시 OpenAPI(실시간 따릉이 현황)를 이용하기</h2>
        <p>모든 위치의 따릉이 현황을 보여주세요</p>
        <p>업데이트 버튼을 누를 때마다 지웠다 새로 씌여져야 합니다.</p>
        <button onclick="q1()">업데이트</button>
        <table>
            <thead>
                <tr>
                    <td>거치대 위치</td>
                    <td>거치대 수</td>
                    <td>현재 거치된 따릉이 수</td>
                </tr>
            </thead>
            <tbody id="names-q1">
                <tr>
                    <td>102. 망원역 1번출구 앞</td>
                    <td>22</td>
                    <td>0</td>
                </tr>
                <tr>
                    <td>103. 망원역 2번출구 앞</td>
                    <td>16</td>
                    <td>0</td>
                </tr>
                <tr>
                    <td>104. 합정역 1번출구 앞</td>
                    <td>16</td>
                    <td>0</td>
                </tr>
            </tbody>
        </table>
    </div>
</body>

</html>

 

 

2. Fetch 기본 골격 코드와 OpenAPI 코드를 통해 데이터를 받아오자.

Fetch 기본 골격을 script 태그에 붙이고 OpenAPI URL을 입력해보고 데이터가 콘솔에 찍히는지부터 확인하자.

OpenAPI URL은 공공데이터 포털(서울 열린데이터 광장)에서 받을 수 있는데 신청하여 인증키를 받아야한다.

과정을 생략하고자 코딩클럽에서 제공된 url을 사용하고자 한다.

fetch("여기에 URL을 입력").then(res => res.json()).then(data => {
                console.log(data)
})

 

OpenAPI URL : 

URL 부분 "http://spartacodingclub.shop/sparta_api/seoulbike" 로 변경

주석 부분들은 미세먼지 예제에서 사용되었던 코드들이라 데이터 확인 후 차근차근 본 예제 내용으로 수정해야 한다.

우선 console.log(data)들을 통해 변경된 URL의 따릉이 데이터가 정상적으로 들어오는지 확인한다.

 function q1() {
            // 여기에 fetch 골격부터 코드를 입력
            // URL "http://spartacodingclub.shop/sparta_api/seoulbike" 따릉이로 변경
            fetch("http://spartacodingclub.shop/sparta_api/seoulbike").then(res => res.json()).then(data => {
                // 데이터 들어오는지 확인
                console.log(data)

                // let rows = data['getStationList']['row']
                // 데이터 들어오는지 확인
                // console.log(rows)

                // 반복문으로 들어오는지도 확인
                // rows.forEach((a) => {
                //     console.log(a)
                // })

                //     let gu_name = a['MSRSTE_NM']
                //     let gu_value = a['IDEX_MVL']
                //     console.log(gu_name, gu_value)
                // 이렇게 원하는 값만 추출되는 것을 개발자도구로 확인했으면

                // HTML에 넣을 차례
                // JSON 넣는 공식? 항상 반복되는 사이클 :
                // 데이터를 가져온다 => 데이터중에서 list화시킬 부분을 추린다 => 반복문을 돌면서 => 필요한 정보만 꺼내고 => 조건문을 붙여서 구분한다

                // ' ` '백틱 Backtick을 사용하고 있다.
                // 백틱 문자열 내부에 변수 사용
                // ex) const backtick = `this is ${val} backtick`;

                //     let temp_html = ``
                //     if (gu_value > 100) {
                //         temp_html = `<li class="bad">${gu_name} : ${gu_value}</li>`
                //     } else {
                //         temp_html = `<li>${gu_name} : ${gu_value}</li>`
                //     }
                //     $('#names-q1').append(temp_html)
                // })
            })
        }

개발자도구의 console로 데이터가 정상적으로 들어오는 것이 확인된다.

이제 데이터의 key, value가 무엇이 무엇인지 파악하고

어떤 key들이 필요하고 value를 출력 할 것인지만 설계하면된다.

 

바로 앞전 코드에서 console.log(data)로 가장 큰 범위의 데이터를 확인했다.

해당 부분을 주석하고 좀 더 스코프를 좁혀본다.

                let rows = data['getStationList']['row']
                // 데이터 들어오는지 확인
                console.log(rows)

getStationList의 row 안에 실제 활용한 데이터가 나열되는 것을 확인 할 수 있다.

 

이제 반복문으로도 데이터가 들어오는지도 확인해본다.

                let rows = data['getStationList']['row']
                // 데이터 들어오는지 확인
                // console.log(rows)

                // 반복문으로 들어오는지도 확인
                rows.forEach((a) => {
                      console.log(a)
                })

rows로 선언한 row데이터들이 나열되는 것을 확인 할 수 있다.

이제 실제로 원하는 값인

  1. 거치대의 위치 
  2. 거치대의 수
  3. 현재 거치된 따릉이

이 3개가 어떤 명칭으로 표기되어있는지, 해당 key명칭을 찾고 value로 뽑아내면 된다.

1개 데이터를 열어서 살펴보면 

  1. 거치대의 위치 = stationName
  2. 거치대의 수 = rackTotCnt
  3. 현재 거치된 따릉이 = parkingBikeTotCnt

인것을 파악 할 수 있다.

이처럼 원하는 데이터만 가져와지는지 다시 확인

                // 반복문으로 들어오는지도 확인
                rows.forEach((a) => {
                //     console.log(a)
                    let name = a['stationName']
                    let rack_cnt = a['rackTotCnt']
                    let park_cnt = a['parkingBikeTotCnt']
                    console.log(name, rack_cnt, park_cnt)
                })
                // 이렇게 원하는 값만 추출되는 것을 개발자도구로 확인

다음처럼 원하는 값만 추출하는 것에 성공했다.

 

 

 

3. 데이터가 들어오는 것을 확인했으면 HTML에 기록되도록 해보자

저번 예제는 ul>li 에 기록했지만

이번에는 append 를 통해 HTML의 names-q1이란 id를 가진 table 태그에 누적되도록 반복문을 작성해야 한다.

 

temp_html에서 데이터에서 변수로 선언한

${name}, ${rack_cnt}, ${park_cnt} 3개의 값을 tr>td 테이블 형태로 작성되고

id가 names-q1이라는 HTML 본문에 append하여 내용을 붙이도록 한다.

 

마무리로 기존 하드코딩된 테이블 내용을 삭제하고

데이터를 받은 자료들만 나타나도록 해당 테이블을 비워줄 수 있도록

반복문 이전에 empty() 함수를 호출

function q1() {
            // 여기에 fetch 골격부터 코드를 입력
            // URL "http://spartacodingclub.shop/sparta_api/seoulbike" 따릉이로 변경
            fetch("http://spartacodingclub.shop/sparta_api/seoulbike").then(res => res.json()).then(data => {
                // 데이터 들어오는지 확인
                // console.log(data)

                let rows = data['getStationList']['row']
                // 데이터 들어오는지 확인
                // console.log(rows)

                // 반복문으로 들어오는지도 확인
                //html에 강제입력되있는것 비워주고
                $('#names-q1').empty()
                rows.forEach((a) => {
                    //     console.log(a)
                    let name = a['stationName']
                    let rack_cnt = a['rackTotCnt']
                    let park_cnt = a['parkingBikeTotCnt']
                    // 이렇게 원하는 값만 추출되는 것을 개발자도구로 확인
                    console.log(name, rack_cnt, park_cnt)
                    // HTML에 넣을 차례
                    let temp_html = `<tr>
                                        <td>${name}</td>
                                        <td>${rack_cnt}</td>
                                        <td>${park_cnt}</td>
                                    </tr>`
                    $('#names-q1').append(temp_html)
                })
            })
        }

 

4. 조건문을 통해 스타일 제어

마지막으로 따릉이 주차개수가 5개 미만일 경우

빨간색으로 텍스트를 바꾸도록 해서 가독성을 추가해보았다

 

style 태그에서는 간단하게 .red 클래스에 색상을 주도록 설정

        .red{
            color: red;
        }

park_cnt의 값에 따라

tr에 red클래스를 주는 경우와

기존 그대로 사용하는 경우로 구분하면된다.

                   // park_cnt가 5개 미만인 경우 .red style이 적용되도록 조건문 설정
                    let temp_html = ``

                    if (park_cnt<5){
                        temp_html = `<tr class="red">
                                            <td>${name}</td>
                                            <td>${rack_cnt}</td>
                                            <td>${park_cnt}</td>
                                        </tr>`
                                    } else {
                        temp_html = `<tr>
                                            <td>${name}</td>
                                            <td>${rack_cnt}</td>
                                            <td>${park_cnt}</td>
                                        </tr>`
                    }

                    $('#names-q1').append(temp_html)

해당 실습 요약은

  • 업데이트 버튼을 누르면
  • 기존 테이블 내용이 사라지고
  • 따릉이 OpenAPI 데이터를 불러와서
  • 테이블 형태로 내가 원하는 항목의 데이터를 기록한다.

 

 


 

 

해당 스터디는 아래 깃을 통해 업데이트 되고 있습니다.

https://github.com/yzpocket/Sparta99training

 

GitHub - yzpocket/Sparta99training

Contribute to yzpocket/Sparta99training development by creating an account on GitHub.

github.com