본문 바로가기

개발자도구만으로 유튜브 자동자막 txt 파일로 스크래핑하기

codeConnection 2024. 8. 26.

여러 이유로 유튜브에서 몇 시간짜리 영상을 검토해야 하는 일이 올 수 있다.

그런데 몇 십분이면 그걸 다 보고 있겠지만 십 수 시간이 되는 경우 영상을 다 보고 있는 것도 고통스럽지 않겠는가.

 

Whisper AI나 vrew 같은 툴을 써서 보다 정확한 자막을 추출해낼 수 있지만, 복잡하고 또 돈이 들기 때문에

그 정도는 아니고 대강 정도만 파악이 필요한 경우 웹 브라우저의 개발자 도구만으로도 자막과 타임스탬프를 추출할 수 있다.

 

단 유튜브에서 자동자막을 생성해준 경우만 가능하다.

웬만하면 자동자막이 잘 생성이 되지만, 여러 언어가 섞여 있거나 음질이 좋지 않은 경우에는 자동자막이 생성되지 않는 것 같다.

그런데 우리나라 영상에서는 그런 경우를 잘 못 봤고 인도인 유튜브에서 그런 현상이 많았던 것 같다.

 

유튜브 들어가기

먼저 본인이 자막을 추출해야 할 유튜브 동영상을 들어가보자.

그리고 설명란에 보면 스크립트 보기라는 버튼이 있다.

이것을 눌러보면 우측에 타임스탬프를 포함해서 자동생성된 자막이 뜬다.

정확하게 무슨 말인지 알기 어렵지만 대략적으로 이 타이밍에 이런 말을 하고 있구나 정도는 파악할 수 있다.

물론 내가 추출하고자 하는 영상이 시끄러운 환경이고 전문 방송인처럼 발음이나 오디오 녹음 품질이 좋은 것은 아니라

좀 더 심각하게 보이긴 한다.

 

그러면 이것을 txt 파일로 다운로드 받아보도록 하자.

개발자도구 열기

브라우저에서 마우스 우클릭을 해서 개발자도구를 열거나 F12를 눌러 개발자도구를 연다.

MacOS에서는 검사라고 뜰 수 있다. Windows는 뭐라고 뜨는지 잘 모르겠는데 아마 위치도 비슷할 것이다.

위 사진을 보고 개발자도구에서 소스코드 패널까지 잘 뜨는지 확인한다.

그리고 그 소스코드를 잘 살펴보면 아래와 같이 되어 있을 것이다.

소스코드에 마우스 클릭을 하면 전체 선택이 된 것처럼 보이는데 ctrl+C로 복사가 가능하다.

<div class="segment style-scope ytd-transcript-segment-renderer" role="button" tabindex="0" aria-label="5분 20초 죄송합니다 쉬지 않고 한 다섯 시간 가야">
  <div class="segment-start-offset style-scope ytd-transcript-segment-renderer" tabindex="-1" aria-hidden="true">
    <div class="segment-timestamp style-scope ytd-transcript-segment-renderer">
      5:20
    </div>
  </div>
  <dom-if restamp="" class="style-scope ytd-transcript-segment-renderer"><template is="dom-if"></template></dom-if>
  <yt-formatted-string class="segment-text style-scope ytd-transcript-segment-renderer" aria-hidden="true" tabindex="-1">죄송합니다 쉬지 않고 한 다섯 시간 가야</yt-formatted-string>
  <dom-if restamp="" class="style-scope ytd-transcript-segment-renderer"><template is="dom-if"></template></dom-if>
</div>

 

여기에서 우리에게 필요한 것은

 

 

이렇게 세 개이다.

웹 페이지를 구성하는 HTML이라는 이 마크업 언어에 대해서 잘 모르시는 분들을 위해 간단하게만 설명하자면,

위에서 표시한 것들은 화면에서 특정 정보들을 구분해주는 고유한 이름 같은 것으로 사용되는 것이라고 보면 된다.

 

그러니까 자막이 매번 다른 내용이고 시간도 전부 다른데, 그 자막들의 내용들을 추출하려면 그 자막들을 가리키는 이름이 있어야 한다는 것이다.

맨 위에 긴 class는 시간: 자막내용 이 전체의 이름을 말하는 것이고,

아래 segment-timestamp, segment-text는 시간과 자막 내용을 말하는 것이다.

 

우리는 사긴과 자막을 각각 같이 저장할 것이기 때문에 이 둘이 필요한 것이고 타임스탬프가 필요 없으면 안 써도 된다.

 

저것을 아래 소스코드에 갈아 끼우면 된다.

그런데 저것 그대로 쓰는 것이 아니라 공백 없이 붙여 쓰고 또 class를 지칭할 때는 마침표를 붙여주기 때문에

실제 본인이 사용했던 소스코드를 그대로 넣겠다. 잘 보고 지금 본인의 상황과 다르다면 바꿔 끼워 주시길 바란다.

자바스크립트 소스 코드

// 타임스탬프와 자막을 담을 배열
const subtitles = [];

// 각 자막 세그먼트를 선택
const elements = document.querySelectorAll('.segment.style-scope.ytd-transcript-segment-renderer');

// 각 요소에서 타임스탬프와 자막 텍스트를 추출
elements.forEach((element) => {
    const timestamp = element.querySelector('.segment-timestamp').textContent.trim();
    const text = element.querySelector('.segment-text').textContent.trim();
    subtitles.push(`${timestamp}: ${text}`);
});

// 배열을 문자열로 변환, 각 줄은 새로운 자막
const subtitlesText = subtitles.join('\n');

// 텍스트 파일로 저장하는 함수
function saveTextAsFile(text, filename) {
    const blob = new Blob([text], { type: 'text/plain' });
    const link = document.createElement('a');
    link.href = URL.createObjectURL(blob);
    link.download = filename;
    link.click();
    URL.revokeObjectURL(link.href);  // 다운로드 후 URL 해제
}

// 자막을 "subtitles.txt"라는 이름으로 저장
saveTextAsFile(subtitlesText, 'subtitles.txt');

 

파일 이름도 본인이 설정할 수 있으니 설정하시고,

배열을 문자열로 변환하고 텍스트 파일로 저장하는 부분을 보면 뭐 여러가지 응용을 할 수 있을 것 같아 보이는데,

파일 이름을 영상 제목으로 바꾸고 싶어졌다.

 

위에서 했던 방법을 그대로 응용해서 영상 제목 부분을 가리키는 고유한 이름인 class명을 가져오면 된다.

 

최종 소스코드

// 모든 해당 클래스의 요소를 선택
const dateElements = document.querySelectorAll('span.style-scope.yt-formatted-string.bold');

// 파일 제목을 생성 (제목 요소를 정확하게 선택)
const youtubeTitle = document.querySelector('yt-formatted-string.style-scope.ytd-watch-metadata').textContent.trim();
const fileName = `${youtubeTitle}.txt`;

// 타임스탬프와 자막을 담을 배열
const subtitles = [];

// 각 자막 세그먼트를 선택
const elements = document.querySelectorAll('.segment.style-scope.ytd-transcript-segment-renderer');

// 각 요소에서 타임스탬프와 자막 텍스트를 추출
elements.forEach((element) => {
    const timestamp = element.querySelector('.segment-timestamp').textContent.trim();
    const text = element.querySelector('.segment-text').textContent.trim();
    subtitles.push(`${timestamp}: ${text}`);
});

// 배열을 문자열로 변환, 각 줄은 새로운 자막
const subtitlesText = subtitles.join('\n');

// 텍스트 파일로 저장하는 함수
function saveTextAsFile(text, filename) {
    const blob = new Blob([text], { type: 'text/plain' });
    const link = document.createElement('a');
    link.href = URL.createObjectURL(blob);
    link.download = filename;
    link.click();
    URL.revokeObjectURL(link.href);  // 다운로드 후 URL 해제
}

// 생성된 파일 이름으로 자막을 저장
saveTextAsFile(subtitlesText, fileName);

 

이걸 콘솔창에 넣고 엔터를 치면 파일 탐색기가 열리면서 로그가 잘 다운로드 되는 것을 볼 수 있다.

댓글