유튜브 댓글에서 한국인 찾 기
🔎
- 이 글은 개인적인 분석이며 YouTube가 소스 코드를 공개하기 전까지는 이 글을 검증할 방법이 없습니다. 이 점 유념하시고 글을 읽어주시기 바랍니다.
YouTube는 언어를 기준으로 댓글을 보는 기능이 없다. 이 글은 그 불편함을 조금이나마 해소하기 위해 개발한 "YouTube 댓글 언어 필터"의 알파, 베타, 그리고 정식 출시 버전까지의 개발 이야기를 담았다.
anaclumos/youtube-comment-language-filter
- Chrome 계열 설치 링크 (Chrome, Brave, Naver Whale, Microsoft Edge)
- Firefox 계열 설치 링크
0. 구상
하루는 불편함을 느끼던 와중 호기심이 들어 YouTube의 댓글 HTML이 어떻게 묶여있는지 뜯어보았다. console
에서 이런저런 값들을 입력해보다가 한글이 포함된 댓글만 남기고 싹 지워주는 자바스크립트 파일을 만들었다. 과거 한글과 유니코드 규칙에 관련된 한글깨기.py라는 프로젝트를 진행했던 경험이 도움이 됐다.
🧼 초기 필터 스크립트. YouTube 댓글에서 한글이 포함되어 있지 않으면 그 댓글을 지워버리는 원리이다. GitHub 저장소의 첫 커밋에도 저장되어 있다.
var commentList = document.getElementsByTagName('ytd-comment-thread-renderer')
var comment
function containsUnicode(str, startUnicode, endUnicode) {
for (var i = 0; i < str.length; i++) {
if (startUnicode.charCodeAt(0) <= str.charCodeAt(i) && str.charCodeAt(i) <= endUnicode.charCodeAt(0)) {
return true
}
}
return false
}
for (var x = 0; x < commentList.length; x++) {
comment = commentList[x].childNodes[1].childNodes[1].childNodes[3].childNodes[3].innerText
if (containsUnicode(comment, '가', '힣')) {
// comment = "한글임 \n" + comment;
} else {
// console.log(typeof commentList[x]);
commentList[x].parentNode.removeChild(commentList[x])
x--
}
}
for (var x = 0; x < commentList.length; x++) {
console.log(commentList[x].childNodes[1].childNodes[1].childNodes[3].childNodes[1].innerText)
// 작성자 이름과 작성날짜가 같이 묶여있다. "이름\n작성날짜"
console.log(commentList[x].childNodes[1].childNodes[1].childNodes[3].childNodes[3].innerText)
// 댓글!
}
// End of code
/* 참고: 이 코드는 초기 코드이며, 일부 경우에서는 정상 동작하지만
* 여러 에러가 발생하며 성능 저하 문제가 있었다.
* 디버깅과 성능 개선 작업이 진행된 코드는 GitHub에 업로드되어 있다.
*/
이때 이 코드를 프로젝트로 키울 수 있겠다고 생각했다. 하지만 이 스크립트는 몇 가지 문제점이 있었다.
- 우선 콘솔에서 코드를 붙여 넣어야 하니 다른 사람들이 쓰기 어렵고 불편했다.
- 자동적으로 실행되지 않았기에 댓글이 새로 로딩되면 콘솔에서 다시 실행해야 했다.
- 한글만 걸러낼 수 있다는 점에서 용도가 무척 제한적이었고, 실행 속도가 느렸다.
이 문제점들을 해결하는 것이 자연스러운 개발 목표가 되었다. 우선 크롬 익스텐션을 만드는 것이 가장 편리할 것이라 생각했다.
- 엣지나 웨일도 크로미움 기반이며 파이어폭스 애드온도 크롬 익스텐션으로 만들 수 있다.
- 사파리는 YouTube 4K 동영상 재생이 안 되기 때문에 사파리 사용자들도 YouTube를 볼 때 크로미움을 쓰는 경우가 많다.
- 인터넷 익스플로러는 YouTube 지원이 끊겼다.
또한 컴퓨터를 잘 모르는 사람들도 사용하기 편하려면 "YouTube의 기능인 것처럼" 동영상과 댓글 사이 위치해 있어야 한다고 생각했다. 그래야만 사용자가 마우스 커서를 동영상에서 댓글로 옮겨가면서 자연스럽게 사용할 수 있다. 그래서 크롬 익스텐션에는 별다른 기능이 없고 YouTube 화면 자체에 직접 메뉴를 삽입하도록 만들고 싶었다.
이제 목표가 구체화되었다.
- 이 크롬 익스텐션은 동영상과 댓글 사이에 언어를 컨트롤하는 인터페이스를 삽입할 것이다.
- 그 인터페이스를 통해 모든 댓글이 자동적으로 필터링할 수 있을 것이다. 댓글을 더 불러와도 계속 그대로 작동할 것이다.
- 새로운 언어를 추가할 때 큰 어려움이 없도록 확장성을 갖춰야 한다.
- 납득할 수 있을 정도로 빨라야 한다.
참고: versioning
버전 숫자를 부여하는 방식은 사람마다, 단체마다 다르다. 이 글에서는 다음과 같은 분류를 따른다.
- 일의 자리는 메이저 업데이트를 뜻한다.
- 첫 번째 소수점은 기능의 추가, 두 번째 소수점은 버그 수정을 뜻한다.
- 세 번째 소수점은 코드 상의 수정 없이 스토어에 재업로드를 할 때 사용한다.
이름 | 버전 | 설명 |
---|---|---|
알파 | 0.1+ | 최소한의 기능, 소수에게 배포/피드백 |
베타 | 0.9+ | 최초 구상 대부분 구현, 다수에게 배포/피드백 |
정식 | 1+ | 지속적 개선, 누구에게나 배포/피드백 |
1. 알파 버전은 최대한 빨리
알파 버전(더 정확하게는 Minimum Viable Product)을 만들기 위해서는 최소한의 기본적인 기능이 동작해야 한다. 더 구체적으로는 다음 목표가 달성되어야 했다.
- 댓글이 새로 로딩될 때마다 자동적으로 재실행되어야 한다.
- 언제든지 다시 전체 댓글을 볼 수 있어야 한다.
- 원클릭 설치를 할 수 있어야 한다.
가장 먼저 "어떻게 자동적으로 재실행되게 만들 것인가"를 고민했 다.
방법 1. 시간 기반 자동 재실행
하지만 YouTube 동영상을 켜자마자 동영상만 감상하는 사람들에게는 성능의 낭비일 것 같았다. 그렇다고 재실행 간격이 너무 길면 댓글을 읽을 때 불편함이 생길 것이다. 가장 먼저 떠올렸지만 가장 먼저 접은 방법이다.
방법 2. YouTube의 로딩 아이콘 감지
YouTube의 로딩 아이콘
확인해보니 로딩 아이콘이 생길 때마다 댓글 아래에 <can-show-more>
태그가 나타났다 사라졌다. 즉 난독화된 YouTube의 자바스크립트 코드가 <can-show-more>
태그를 삽입하는 순간을 포착하여 같이 필터가 재실행되도록 하면 될 것 같다는 생각이 들었다.
방법 3. MutationObserver
이후 자바스크립트의 MutationObserver
를 알게 되었다. 관찰 대상인 target
과 관찰 조건인 config
를 설정한 후 config
에 맞는 변경 사항이 일어나면 callback
함수를 실행하는 것이었다. YouTube 댓글 HTML을 target
으로 삼았고, HTML 내의 childNodes
와 attributes
의 변경에 반응하도록 했다. 원했던 대로 댓글이 로딩될 때마다 재실행되었다. 1번 해결.
하지만 성능이 크게 떨어졌다. 우선 console.log
가 수만 번 실행된다는 것을 확인하고 이를 지우니 쓸만할 정도로 빨라졌다. 속도를 조금이나마 개선하기 위해 매번 댓글의 언어 테스트를 진행하는 대신 댓글을 display:none;
으로 가리고 HTML 태그로 판정 결과를 기록해놓는 방법을 사용했다. 전체 댓글을 보는 버튼을 클릭하면 display:none;
을 없애도록 했다. 그러다가 다시 재실행하면 앞서 기록해둔 태그만으로 판단했다. 2번 해결. (나중에야 알았지만 온전한 해결이 안 되었다. 이렇게 annotation을 활용하는 방법은 속도를 별로 개선하지 않았고 문제만 더 만들었다. 베타 버전 중 2번 YouTube의 SPA스러움 참고.)
이후 3일 동안 크롬 익스텐션의 구조에 대해서 배우면서 크롬 익스텐션의 틀 안에 기존 코드를 이식하는 작업을 했다. 크롬 익스텐션의 공식 문서, 스택 오버플로, 그리고 크롬 익스텐션에 대한 Udemy 강의를 주로 참고했다. 3번 해결.