brunch

You can make anything
by writing

C.S.Lewis

by 핑크곰 Feb 07. 2021

유튜브 API - 채널 안에 있는 모든 동영상 조회하기

작년에 Elastic Stack을 활용하여 자사의 콘텐츠 유통 데이터를 분석하는 시스템을 개발했다. 익숙하지 않은 플랫폼에서 다양한 데이터를 수집하다 보니 나름 시행착오가 많았는데, Logstash가 워낙 많은 기능을 지원하다 보니 다행히 짧은 기간에 적은 인원(필자 포함 2명 -_ -)으로 프로젝트를 마무리할 수 있었다.

(프로젝트에 대한 전반적인 이야기는 나중에 별도의 글을 통해 정리해보겠다.)


Kibana를 통한 시각화


본 글에서는 프로젝트에서 필자를 꽤나 괴롭혔던 유튜브 API를 활용한 수집 이야기를 해볼까 한다.




서비스에서는 다양한 콘텐츠 유통 데이터(시청자 활동, 수익, 시청률, 화제성 지수 등)를 다양한 방법(API, DB, File, Mail, 크롤링 등)으로 수집했다. 방법의 차이가 있을 뿐 종단에는 Logstash에서 ElasticSearch로 인덱싱 돼서 Kibana를 통해 시각화하는 구조였다.


다양한 크롤링 개발 경험 때문에 크게 문제없이 개발하다가 유튜브 API를 사용해서 데이터를 가져오는 부분에서 고생이 시작됐다. 이럴 거면 브런치 북은 뭐하러......



당면한 문제는 너무나 단순하고 데이터 수집의 시발점이 되는 요청사항이었다.


유튜브에서 내가 소유한 모든 동영상 정보를 가져와 주세요


얼핏 보면 너무나 쉽고 간단할 것 같은 이 녀석이 해결이 안돼서 며칠을 고생을 했다. 늘 그렇듯 내가 하고 있는 고민은 전 세계 개발자들이 똑같이 고민했고, 하고 있고 그리고 할 내용이기에 구글링도 열심히 했지만, 돌아오는 건 욕설뿐 -.-;

유튜브 이슈 트래커에는 개발자들이 Search API에 분노한 내용들을 어렵지 않게 찾아볼 수 있다.


자 그럼 본격적으로 이 간단한 문제 때문에 삽질한 필자의 경험을 풀어본다.




유튜브 API를 통해서 가져오려는 정보가 채널 하나에 몇백 개 수준의 동영상이라면 사실 크게 문제 될 게 없다. (언제나 문제는 빅데이터다. 우리가 개발을 하는 이유가 많은 데이터를 빠른 시간 안에 해결하고자 함이니.)


필자는 이 요청사항을 그 정도 수준으로 생각했다. 동영상이 아무리 많아봐야 채널별로 가져오면 해결되겠지, 채널이 수천수만 개는 아닐 테니...


해서, 유튜브 Data API 중 Search 기능을 통해서 채널별로 동영상을 검색했다. 별문제 없이 수집이 일어나야 하는 코드가 아무리 시간이 지나도 멈추지를 않는다. 디버깅을 해보니, 검색한 결과가 500건을 초과하는 경우 다음 페이징의 토큰 값(nextPageToken)이 null값이 반환되지 않고 계속 갱신되는 문제가 발생하고 있었다. pageToken이 계속 갱신되더라도 pageInfo.resultsPerPage 값은 줄어들기 때문에, 이 값이 0 보다 클 때로 제한을 둬서 수집을 해 봤으나 역시나 최대 500 ~ 600건까지만 조회되는 한계가 있었다.


왜 몰랐을까?!

유튜브 개발자 레퍼런스에서 한글 버전영문 버전이 다르다. 한글 버전에는 없는 내용이 영어 버전에는 나와있다. 야.. 이.. ㅇ애ㅑㅓㄹ미ㅑ얼;ㅇ마ㅣ럼;ㅑ덜;ㅣㅑㅁ아ㅓ이ㅏ러

Search:list() 레퍼런스 한글 버전
Search:list() 레퍼런스 영어 버전


영문 가이드대로 채널별로 가져오지 않고 콘텐츠 소유자 파라미터(forContentOwner)를 설정해서 가져오는 방법도 가능하겠지만, 뒤에서 이야기할 할당량에 문제가 발생할 수 있어서 권장하고 싶지는 않다. 참고로, 콘텐츠 소유자와 채널 아이디 파라미터를 함께 사용하면 에러를 반환한다. 그리고 필자는 콘텐츠 소유자를 설정해서 돌려봤지만 정상적으로 모든 동영상을 가져오지 못했다. (유튜브 API 잘못은 아닐 거야... 그럴 거야... -_ -;;;)


그러면 어떻게 가져올 수 있을까?

Search:list() 메서드의 publishedAfter, publishedBefore 파라미터를 사용해서 한 번에 조회할 수 있는 영상의 개수를 500건 이하로 줄여서 조회하면 가능하다.


그런데 말입니다...

필자의 경우, 조회하고자 하는 유튜브 채널은 총 68개, 동영상은 약 40만 개 정도가 된다. 일전에 할당량 최적화 글에서 안내해 드린 대로, Search:list()의 할당량은 100이다. 다른 조회 API들과 비교하면 100배나 차이 난다.(대부분 1) 때문에 단순히 동영상 개수로만 할당량을 계산해도 전체 정보를 조회하는데 80만 할당량이 필요하다.


40만(동영상 수) / 50(한 번에 최대 조회 가능한 동영상 수) * 100(Search:list() 할당량)

 = 80만(할당량)


별도로 요청하지 않는 이상, 일반적으로 Youtube Data API의 일간 할당량은 1만이다.

즉, 하루에 한 번 수집한다고 해도 택도 없다;;;;




그냥 안된다고 이야기하고 싶지만, IT 엔지니어의 자존심이 허락하지 않는다(라고 쓰고, 먹고살기 위해라고 읽음).

 

차선책으로 Reporting API로 채널(or 콘텐츠 소유자)의 모든 영상 정보를 담고 있는 최신 보고서를 다운로드한다. 그 이후 보고서의 최근 수집 종료기간(endTime) 이후의 데이터를 Search:list()로 가져와서 합치는 방식으로 개발했다. Reporting API를 통해 다운로드하는 데이터는 PST 기준 2일(KST 기준 3일) 전 데이터만 가능하기 때문에 그 이후(3일 전 ~ 오늘)에 배포된 영상은 결국 Search API로 가져올 수밖에 없었다.


꽤나 괜찮은 방법이었지만, 2 ~ 3일 사이에 올라온 동영상이 많을 경우, 간헐적으로 할당량 문제가 발생했다.
물론 테스트 때문에 할당량 소비가 많아서 그런 거였지만, 채널이 늘어나고 동영상 배포가 많아지면 결국 언젠가는 발생할 문제였다.


더 나은 방법이 없을까 고민하다 내가 예전에 쓴 글을 내가 참고하는 상황까지 왔다. -0-;

할당량을 최적화하려면 어떻게 해야 할까?!




Search API 대비 Playlist, Playlistitem API의 조회 할당량은 1/100이다. 즉, 재생목록에 있는 모든 동영상을 조회하더라도 할당량 부족함 없이 모든 동영상을 조회할 수 있다. 문제는, 재생목록에 담지 않은 동영상이 존재한다는 거.

 

다행히, 채널에는 자신이 만든 재생목록(playlist) 외에 기본으로 제공하는 재생목록이 존재한다. 그중에 업로드 동영상(upload)이라는 재생목록이 있는데, 여기에는 자신이 올린 모든 동영상이 나타난다.


좋아!

쿼터 최적화를 위해 모든 채널에서 재생목록 - 재생목록 아이템 순으로 조회하기로 했다.

Playlist API를 사용해서 contentDetails(relatedPlaylists(uploads))로 업로드 동영상 재생목록 아이디를 조회하고 이 정보를 Playlistitem API의 파라미터로 넘겨서 동영상 목록을 조회하는 방식이었다.


문제없이 수집이 진행되고 쿼터도 크게 문제가 없었다.

그런데 수집된 결과를 보니 유독 동영상이 많은 채널의 수집된 영상수가 죄다 20,000이다. 불길하다;;;


채널의 업로드 동영상 재생목록당 최대 20,000개 밖에는 조회가 안되더라. 유튜브 레퍼런스에도 나와있지 않던데... 임러;매덜미;아ㅓㄻ;ㅐ더리;ㅁ아ㅓㄹ


2만 개 이상이나 배포하는 채널이 있기는 해?!라고 생각할 수도 있지만, 뉴스 채널 같은 경우 하루에 100개~200개의 동영상이 올라간다. 2만 개 우습게 느껴지는 상황인 게다...




너덜너덜 해진 정신줄 붙잡고 결론을 내렸다.

채널의 모든 동영상 정보를 API를 통해 조회하기 위해서는 아래의 방법으로 해야 한다.(특히 채널과 동영상이 많은 콘텐츠 소유자의 경우)


1. 특정 시점에 전체 동영상 정보를 Reporting API를 이용해서 보고서를 다운로드한다.

2. 이 보고서에서 동영상 정보(동영상 아이디, 채널 아이디 등)를 마스터 데이터로 DB 또는 FILE에 저장한다.

3. 일별 데이터를 추가로 저장한다.

 - 일별 영상 정보 조회 시 할당량에 무리가 가지 않는 상황이면 Search API를 통해서 하루에 한 번 조회한다.

 - 일별 영상 정보 조회 시 할당량을 초과하는 상황이면 업로드 재생목록의 동영상 목록을 조회하여 해당 날짜에 배포된 영상 정보만 저장한다.

브런치는 최신 브라우저에 최적화 되어있습니다. IE chrome safari