안녕하세요
Youtube API Search로 검색한 자료 일자별로 구분하기 본문
Github에서 구현한 코드 보러가기
API Search 기능을 이용해 조건을 입력하고 검색하면
검색 결과를 담은 JSON 데이터를 한 번에 최대 50개 items까지 받을 수 있다.
이렇게 받은 데이터 중에서 원하는 정보만 골라 일자별로 구분해보자.
=> 검색 결과를 ["YYYYMMDD", videoArray] 형태로 분류하여
=> 이용하고 싶은 정보인 channelId, videoId 등등을 골라 저장한다.
1. publishedAt 데이터에서 "YYYYMMDD" 형태로 만들기
=> 영상 발행은 ISO Date 자료형으로 태평양 표준시(PST)를 나타낸다.
(1) 우선 PST를 한국 시간대로 기준을 맞춰 주자
/**
* 유튜브 업로드 시간(publishedAt)과 한국 시간에 차이 없앰
* @param {*} datePST
* @returns
*/
export const utcToKor = (datePST) => {
const parsedDatePST = Date.parse(datePST);
const krUtcTimeDifference = 1 * 60 * 60 * 1000;
const krTime = new Date(parsedDatePST + krUtcTimeDifference);
return krTime;
};
=> 대한민국 표준시에서 17시간을 빼주면 된다고 하는데,
직접 해 본 결과 1시간으로 설정해주었더니 실제 표기와 일치했다.
(2) 한국 기준으로 시간을 맞춘 뒤에 YYYYMMDD 형태로 만들어 반환하면 끝!
/**
* datePST 데이터를 입력받아 (20230101) 형태의 string 반환
* @param {datePST} datePST
* @returns {string} ex) '20230101'
*/
getDatePSTAsYYYYMMDD(datePST) {
const krTime = utcToKor(datePST);
const year = krTime.getFullYear();
const month = String(krTime.getMonth() + 1).padStart(2, "0");
const day = String(krTime.getDate()).padStart(2, "0");
const date = `${year}${month}${day}`;
return date;
}
2. 여러 검색 결과 한 번에 적용 하기
(1) 원본 데이터에서 items 만을 담은 배열 searchVideoDataArray를 만들어서
export class SearchVideo {
#videoArray;
constructor(searchResultData) {
this.originSearchVideoData = searchResultData;
this.searchVideoDataArray = [...this.originSearchVideoData.items];
this.videoIdArray = []; // 중복된 비디오 탐색할 때 효율성 높이기 위함
this.#videoArray = [];
}
getOriginSearchData() {
return this.originSearchVideoData;
}
getSearchVideoDataArray() {
return this.searchVideoDataArray;
}
(2) 검색 결과가 둘 이상일 때도 searchVideoDataArray 데이터에 모조리 담도록 하자
export const createSearchVideoInformation = (searchResult1, ...otherSearchResults) => {
const searchVideo = new SearchVideo(searchResult1);
const searchVideoDataArray = searchVideo.getSearchVideoDataArray();
// 검색 결과가 둘 이상일 경우 배열에 포함시키기
for (const otherSearchResult of otherSearchResults) {
if (otherSearchResult) {
const otherSearchVideo = new SearchVideo(otherSearchResult);
searchVideoDataArray.push(...otherSearchVideo.getSearchVideoDataArray());
}
}
3. 날짜 구분하기
(1) 날짜가 겹치지 않는 케이스를 만들기 위해 Set Object를 이용한다.
// 중복되는 날짜를 제거하기 위함
const dateSet = new Set();
for (const videoData of searchVideoDataArray) {
// Set 객체에 "YYYYMMDD" 형태의 날짜 저장
const fullDate = searchVideo.getDatePSTAsYYYYMMDD(videoData.snippet.publishedAt);
dateSet.add(fullDate);
=> 위에서 만든 함수(getDatePSTAsYYYYMMDD)를 이용하여 "YYYYMMDD" 형태로 만든 문자열을 Set에 추가한다.
(2) [ 날짜, [ video 담을 배열 ] ] 형태로 만들어 주자
// Set객체를 [["YYYYMMDD",[]],["YYYYMMDD"],[]] 형태의 배열로 만듦
const dateArray = Array.from(dateSet).map((date) => [date, []]);
searchVideo.pushNewDate(dateArray);
(3) 검색결과가 두개 이상일 경우에는 date의 순서가 뒤죽박죽이 될 수 있기 때문에 정렬까지 해 준다.
ex) 1번 검색결과는 2일 전까지의 영상을 포함하지만, 2번 검색결과는 3일 전까지의 영상을 포함할 때
=> 0215, 0214, 0215, 0214, 0213
// Set객체를 [["YYYYMMDD",[]],["YYYYMMDD"],[]] 형태의 배열로 만듦
const dateArray = Array.from(dateSet).map((date) => [date, []]);
searchVideo.pushNewDate(dateArray);
searchVideo.sortDateArrayByDate();
4. video를 발행된 날짜에 추가하기
(1) videoId가 중복되어 있다면 추가를 하지 않도록 중복검사를 하자
/**
* this.videoIdArray에 담긴 배열에 입력받은 videoId가 없으면 새 videoId 요소 추가
* @param {*} videoId
* @returns
*/
isDuplicatedVideoId(videoId) {
const isDuplicatedVideoId = this.videoIdArray.includes(videoId);
if (isDuplicatedVideoId) {
return true;
}
}
=> isDuplicatedVideoId 함수는 videoId를 입력받아 배열 안에 동일한 videoId 가 있는지 살피고, 있다면 true를 반환한다.
(2) videoIdArray 배열에 videoId가 존재하지 않으면 추가한다
export class SearchVideo {
#videoArray;
constructor(searchResultData) {
this.originSearchVideoData = searchResultData;
this.searchVideoDataArray = [...this.originSearchVideoData.items];
this.videoIdArray = []; // 중복된 비디오 탐색할 때 효율성 높이기 위함
this.#videoArray = [];
}
=> videoIdArray를 만들어 주어 데이터 전체에서 순회하며 찾지 않도록 한다.
이렇게 배열을 만들면 최초 탐색에서 최소 50배 효율 // 50+00회 => 0회++ (videoId 가 추가되는 만큼)
const videoId = videoData.id.videoId;
// videoId 중복검사
if (!searchVideo.isDuplicatedVideoId(videoId)) {
// ["YYYYMMDD",[]] 비디오를 비디오 발행 일자와 일치하는 날짜 배열에 추가
searchVideo.pushVideoId(videoId);
=> 중복검사 함수를 이용하여 존재하지 않을 경우 videoId 추가
5. 데이터 추가하기
(1) 이제 필요한 데이터만 골라 추가해보자
=> 이런 형태로 만들고 싶다면 필요한 데이터를 아래와 같이 object 에 저장해주면 된다.
insertVideoDataIntoDateArray(YYYYMMDD, videoData) {
const {
id: { videoId },
snippet: {
channelId,
channelTitle,
publishedAt,
title,
description,
thumbnails: {
medium: { url },
},
},
} = videoData;
this.#videoArray.forEach((date, index) => {
const sameDate = YYYYMMDD === date[0];
if (sameDate) {
this.#videoArray[index][1].push({
videoId,
channelId,
channelTitle,
publishedAt,
title,
description,
thumbnailUrl: url,
});
}
});
}
=> YYYYMMDD 매개변수는 video 발행 날짜와 일치하는 배열에 담을 수 있도록 한다.
videoData 매개변수는 object에 데이터를 전달할 수 있도록 한다.
(2) YYYYMMDD, videoData 인자를 전달하면 Object 형태로 해당하는 날짜 배열에 추가된다.
const videoId = videoData.id.videoId;
// videoId 중복검사
if (!searchVideo.isDuplicatedVideoId(videoId)) {
// ["YYYYMMDD",[]] 비디오를 비디오 발행 일자와 일치하는 날짜 배열에 추가
searchVideo.pushVideoId(videoId);
searchVideo.insertVideoDataIntoDateArray(YYYYMMDD, videoData);
}
}
Github에서 구현한 코드 보러가기
검색 결과 여러개를 인자로 넣고 실행을 해보면~
createSearchVideoInformation(mockSearchData1,mockSearchData2,mockSearchData3);
14+17+28+31+26+21 = 137
총 150개의 결과 중에서 중복되는 13개의 비디오를 제외하고,
20230210~20230215 일자로 구분된 video 정보를 받을 수 있다.
기능을 추가한다면...
- 저장하고 싶은 속성 선택
- 1일, 3일, N일, 한달(202301, 202302) 등 날짜 묶음 단위 선택
'유튜브컨텐츠탐색-StelLife' 카테고리의 다른 글
filter 기능 구현: 할 때 목록을 state로 만들 필요는 없다. (0) | 2023.03.11 |
---|---|
express 라우터에 async-await 사용하기. next() 메서드 (0) | 2023.02.23 |
특정 시간에 API로 받아온 데이터를 DB에 업데이트 (0) | 2023.02.18 |
프로젝트(3) - Koyeb 배포, 환경변수, websocket connection to failed Error (0) | 2023.02.08 |
프로젝트 설계 연습 (0) | 2023.02.04 |