티스토리 뷰

공공데이터포탈(https://www.data.go.kr/data/15012690/openapi.do)에서 제공하는 특일정보 API를 이용하여 공휴일 정보를 DB에 입력하는 프로그램을 간략하게 알아보겠습니다.


1. 사전준비사항

 1. 공공데이터포탈 회원가입 후 특일 정보 활용신청
 2. vscode 설치
 3. nodejs 설치
 4. oracle client 다운(instantclient_21_13)


2. 프로젝트 생성

  • 준비가 완료되었다면 폴더를 하나 생성 합니다. 저는 "D:\\NODEJS_WS"에 생성하였습니다.
    폴더 생성후 CMD 창을 열어 해당 경로로 이동합니다. 그 후 아래 명령어를 입력합니다.
npm init

3. 패키지 설치

  • 프로젝트 생성이 완료되었으면, 추가로 필요한 패키지들을 다운로드합니다.
npm install express --save

...

npm install axios --save

...

npm install oracledb --save
  • --save 옵션을 사용하면 package-lock.json 에 저장되어 다른 PC에서 프로젝트를 열었을 때, 별도로 install 하지 않아도 같은 환경으로 구성하기 위함입니다.

4. 소스 작성

  • 패키지 설치가 완료되면 아래와 같이 소스를 구성합니다.

# api_call.js

const axios = require('axios'); // axios 라이브러리 불러오기

async function callGetApi(apiUrl) {
    try {
        // GET 방식 요청
        const response = await axios.get(apiUrl);
        return response.data;
    } catch (error) {
        throw new Error('API 호출 오류 : ', error);
    }

}

module.exports = callGetApi;
# db_call.js

const oracleDB = require('oracledb');

async function init() {
	// 오라클 
    oracleDB.initOracleClient({ libDir: '../lib/instantclient_21_13' });

    // DB 접속정보
    await oracleDB.createPool({
        user: '유저아이디',
        password: '패스워드',
        connectionString: 'IP:PORT/ServiceName',
        poolAlias: 'default'
    });
}

async function close() {
    await oracleDB.getPool().close();
}

async function getConnection() {
    let connection;
    try {
        connection = await oracleDB.getConnection();
        return connection;
    } catch (err) {
        console.error(err);
        throw err;
    }
}

module.exports = {
    init: init,
    close: close,
    getConnection: getConnection
}
# main.js

const api_call = require('./api_call');
const db_call = require('./db_call');

// DB 연결 초기화
db_call.init().catch(err => console.log('DB 연결 오류 : ', err));

const serviceKey = '제공받은 서비스키';

const apiUrl = 'http://apis.data.go.kr/B090041/openapi/service/SpcdeInfoService/getHoliDeInfo?ServiceKey=' + serviceKey;

// API URL 조회
function getApiUrl(searchYear, searchMonth) {
    return apiUrl + '&solYear=' + searchYear + '&solMonth=' + searchMonth;
}

// 휴일정보 API 조회
function getHolidayList(url) {
    return new Promise((resolve, reject) => {
        api_call(url)
            .then(data => {

                // 데이터 파싱
                const jsonString = JSON.stringify(data);
                const jsonObject = JSON.parse(jsonString);
                const itemList = jsonObject.response.body.items.item;

                if (itemList) {
                    const items = Array.isArray(itemList) ? itemList : [itemList];

                    let holidayData = [];

                    items.forEach(item => {
                        let map = {
                            locdata: item.locdate,
                            isHoliday: item.isHoliday,
                            dateName: item.dateName
                        };

                        holidayData.push(map);
                    });

                    resolve(holidayData);
                } else {

                    resolve([]);
                }
            })
            .catch(err => {
                reject(err);
            });
    });
}

async function insertDB(holidayList) {
    let connection;

    try {
        connection = await db_call.getConnection();
        if (holidayList && holidayList.length > 0) {
            holidayList.forEach(async data => {
                if (data.isHoliday === 'Y') {
                    let id = String(data.locdata);
                    let year = id.substring(0, 4);
                    let month = id.substring(4, 6);
                    let day = id.substring(6, 8);
                    let name = String(data.dateName);

                    const result = await connection.execute(
                        `MERGE INTO HOLIDAYS dest
                         USING (SELECT :val1 AS HOLIDAY_ID,
                                       :val2 AS HOLIDAY_YEAR,
                                       :val3 AS HOLIDAY_MONTH,
                                       :val4 AS HOLIDAY_DAY,
                                       :val5 AS HOLIDAY_NAME
                                FROM dual) src
                         ON (dest.HOLIDAY_ID = src.HOLIDAY_ID)
                         WHEN MATCHED THEN
                             UPDATE SET dest.HOLIDAY_YEAR = src.HOLIDAY_YEAR,
                                        dest.HOLIDAY_MONTH = src.HOLIDAY_MONTH,
                                        dest.HOLIDAY_DAY = src.HOLIDAY_DAY,
                                        dest.HOLIDAY_NAME = src.HOLIDAY_NAME,
                                        dest.UPDDT = sysdate
                         WHEN NOT MATCHED THEN
                             INSERT (dest.HOLIDAY_ID, dest.HOLIDAY_YEAR, dest.HOLIDAY_MONTH, dest.HOLIDAY_DAY, dest.HOLIDAY_NAME)
                             VALUES (src.HOLIDAY_ID, src.HOLIDAY_YEAR, src.HOLIDAY_MONTH, src.HOLIDAY_DAY, src.HOLIDAY_NAME)`,
                        {
                            val1: id,
                            val2: year,
                            val3: month,
                            val4: day,
                            val5: name
                        },
                        { autoCommit: true }
                    );
                    console.log("Inserted:", result.rowsAffected);
                }
            });
        }
    } catch (err) {
        console.error(err);
    } finally {
        if (connection) {
            try {
                await connection.close();
            } catch (err) {
                console.error(err);
            }
        }
    }
}

// main()
async function run() {
    var yearList = [
        '2024', '2025'
    ];

    var monthList = [
        '01', '02', '03', '04', '05', '06',
        '07', '08', '09', '10', '11', '12'
    ];

    var holidayList = [];

    for (const yearData of yearList) {
        for (const monthData of monthList) {
            const url = getApiUrl(yearData, monthData);
            try {
                const list = await getHolidayList(url);

                // 빈값체크
                if (!list || list.length === 0) {
                    console.log('[' + yearData + '/' + monthData + '] : 공휴일 없음.')
                } else {
                    list.forEach(item => {
                        holidayList.push(item);
                        console.log('[' + yearData + '/' + monthData + '] : ' + JSON.stringify(item));
                    });
                }

            } catch (err) {
                console.error('실행 오류 : ', err);
            }
        }
    }

    insertDB(holidayList);
}

run();

 

감사합니다.

최근에 올라온 글
Total
Today
Yesterday