안녕하세요

Youtube API Search로 검색한 자료 일자별로 구분하기 본문

유튜브컨텐츠탐색-StelLife

Youtube API Search로 검색한 자료 일자별로 구분하기

sakuraop 2023. 2. 15. 22:43

Github에서 구현한 코드 보러가기

 

GitHub - youngentry/youtubeApiModule: youtube api 프로젝트 하면서 만든 기능

youtube api 프로젝트 하면서 만든 기능. Contribute to youngentry/youtubeApiModule development by creating an account on GitHub.

github.com

 

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) 등 날짜 묶음 단위 선택