개발자도구만으로 유튜브 자동자막 txt 파일로 스크래핑하기
여러 이유로 유튜브에서 몇 시간짜리 영상을 검토해야 하는 일이 올 수 있다.
그런데 몇 십분이면 그걸 다 보고 있겠지만 십 수 시간이 되는 경우 영상을 다 보고 있는 것도 고통스럽지 않겠는가.
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);
이걸 콘솔창에 넣고 엔터를 치면 파일 탐색기가 열리면서 로그가 잘 다운로드 되는 것을 볼 수 있다.
'Programing > JavaScript' 카테고리의 다른 글
JSON.stringify :: JSON serialization (직렬화) (0) | 2024.08.12 |
---|---|
브라우저 콘솔에서 특정 클래스 스크래핑 (0) | 2024.08.05 |
API key 환경 변수로 설정하기 (.env) (0) | 2024.06.22 |
배열.length : 배열의 아이템 개수 렌더링 하기 (0) | 2024.06.17 |
포매팅 함수 - 데이터를 원하는 형식으로 변환하기 (0) | 2024.06.17 |
댓글