포스트

유데미 강의 대본, 브라우저 콘솔로 한 번에 추출해서 AI 정리노트 만들기

유데미 강의 대본, 브라우저 콘솔로 한 번에 추출해서 AI 정리노트 만들기

강의마다 대본을 복사-붙여넣기 하다 지친 사람을 위한 실전 기록입니다. 브라우저 개발자 도구(콘솔) 하나로 영상 자막을 통째로 뽑아내고, 그걸 AI에게 넘겨 정리노트로 만드는 워크플로를 정리했습니다.

TL;DR

  • 콘솔 스크립트는 직접 짜지 않고, 원하는 동작을 말로 설명해 Kiro에게 생성시켰습니다.
  • 로그인된 내 브라우저 콘솔에서 유데미 내부 API를 그대로 빌려 자막을 모읍니다.
  • STEP 1에서 코스 ID를 찾고, STEP 2 스크립트로 영상 자막을 transcripts.md 한 파일로 저장.
  • 에러가 나면 메시지를 그대로 Kiro에게 넘겨 고치고, 마지막엔 요약 + 셀프 퀴즈 정리노트까지.
  • 반드시 개인 학습 용도로만. 대본 원문은 공유·재배포하지 않습니다.

목차

  1. 왜 이걸 하게 됐나 (문제 상황)
  2. 큰 그림 — 전체 흐름 한눈에 보기
  3. 사전 이해 — 왜 “브라우저에서” 해야 하는가
  4. STEP 1 — 코스 ID 찾기
  5. STEP 2 — 콘솔로 전체 자막 일괄 추출
  6. STEP 3 — 파일로 저장하기
  7. STEP 4 — AI로 정리노트 만들기
  8. 내가 겪은 에러와 해결 (트러블슈팅)
  9. 결과와 회고
  10. 주의사항 (저작권과 사용 범위)

1. 왜 이걸 하게 됐나 (문제 상황)

자격증 공부를 하며 유데미 강의를 듣는데, 매 강의마다 이런 루틴이 반복됐습니다.

  1. 영상 재생 → 대본(Transcript) 패널 열기
  2. 대본 전체 드래그해서 복사
  3. 노트에 붙여넣고 번역/정리
  4. 다음 강의로 이동 → 1번부터 다시

강의가 수십, 수백 개면 이 “복붙 왕복”만으로도 시간이 훅 갑니다. 정작 중요한 “이해하고 암기하는” 시간은 줄어들죠. 그래서 대본 수집만이라도 자동화하기로 했습니다.

2. 큰 그림 — 전체 흐름 한눈에 보기

1
2
3
4
5
6
7
8
9
10
[유데미 수강 페이지(로그인 상태)]
        │  브라우저 콘솔 스크립트 실행
        ▼
[강의 목록 API 호출] → [각 영상의 자막(.vtt) 다운로드]
        │  텍스트만 추출해서 하나로 병합
        ▼
[대본 .md 파일 저장]
        │  AI에게 첨부
        ▼
[섹션별 요약 + 퀴즈 정리노트]

핵심은 “페이지가 이미 쓰고 있는 내부 API를 그대로 빌려 쓴다” 는 것입니다. 새로운 해킹이 아니라, 로그인된 내 브라우저 권한 안에서 데이터를 모으는 것뿐입니다.

3. 사전 이해 — 왜 “브라우저에서” 해야 하는가

처음엔 “AI한테 강의 URL 주면 알아서 긁어오겠지” 생각했지만 아니었습니다.

  • 유데미 수강 화면의 강의 목록·자막은 로그인(수강 등록) 상태에서만 접근됩니다.
  • 외부 도구나 크롤러는 이 인증을 통과할 수 없어서, 공개 소개 페이지의 마케팅 문구만 볼 수 있습니다.
  • 반대로 내 브라우저는 이미 로그인되어 있으니, 그 안에서 스크립트를 돌리면 내 권한 그대로 데이터에 접근할 수 있습니다.

그래서 이 작업은 반드시 로그인된 내 브라우저의 개발자 도구(F12) 콘솔에서 진행합니다.

준비물: 크롬/엣지 같은 브라우저, 수강 중인 강의, F12 개발자 도구. 그게 전부입니다.

한 가지 더. 이 글에 나오는 콘솔 스크립트는 제가 직접 짠 게 아니라 Kiro에게 “이런 걸 하고 싶다”고 설명해서 받은 결과물입니다. 즉 저는 자바스크립트 문법을 붙잡고 있었던 게 아니라, 원하는 동작을 말로 설명 → Kiro가 코드 생성 → 콘솔에 붙여넣어 실행 → 에러 나면 메시지를 다시 Kiro에게 전달하는 식으로 진행했습니다. 그래서 각 STEP마다 “제가 Kiro에게 실제로 던진 프롬프트”를 함께 적어뒀는데, 보시면 알겠지만 딱히 정제된 프롬프트가 아닙니다. 안 되면 툭 던지고, 에러가 나면 메시지만 그대로 붙여넣는 수준이었어요. 그래도 굴러갔다는 게 포인트입니다.

4. STEP 1 — 코스 ID 찾기

유데미 내부 API는 강의를 숫자 코스 ID로 식별합니다. URL의 강의 이름(slug)에는 이 숫자가 없을 수 있어서 따로 찾아야 합니다.

저는 이걸 어떻게 찾는지도 몰라서 그냥 물어봤습니다. 처음엔 네트워크 탭을 보라길래 목록을 펼치고 스크롤해봤는데 새로 잡히는 요청이 없더라고요. 그대로 다시 던졌습니다.

1
2
강의 목록 펼치거나 스크롤해도 새로 호출되는 요청이 없는데,
코스 ID 어떻게 찾아?

그랬더니 “그건 페이지 처음 열 때 이미 다 불러와서 그렇다”며, 이미 오간 요청 기록에서 찾는 아래 한 줄을 줬습니다. 수강 페이지를 연 상태에서 F12 → Console 탭에 붙여넣어 실행하면 됩니다.

1
2
console.log([...new Set((performance.getEntriesByType('resource')
  .map(e=>e.name).join(' ').match(/courses\/\d+/g))||[])]);

출력이 ["courses/1234567"] 처럼 나오면, 그 숫자가 코스 ID입니다. 여러 개가 나오면 보통 반복적으로 등장하는 숫자가 해당 강의 ID입니다.

Tip: 콘솔에 코드를 처음 붙여넣으면 “allow pasting”을 입력하라는 경고가 뜹니다. 이건 정상적인 보안 장치이니, 안내대로 allow pasting 을 직접 타이핑하고 Enter를 누른 뒤 다시 붙여넣으면 됩니다.

5. STEP 2 — 콘솔로 전체 자막 일괄 추출

여기서도 길게 설명 안 했습니다. 대본을 강의마다 복붙하기 싫었던 게 시작이라, 딱 그 불만 그대로 던졌어요.

1
2
강의 대본 이거 일일이 복붙해야 돼?
한 번에 전체 자막 뽑는 스크립트 못 만들어?

그렇게 나온 게 아래 스크립트입니다. 통째로 콘솔에 붙여넣어 실행하고, const cid = '...' 부분에 STEP 1에서 찾은 숫자를 넣으면 됩니다. (참고로 이 버전은 뒤에서 에러를 몇 번 겪고 다듬어진 최종본입니다. 그 과정은 8번에서.)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
(async () => {
  const cid = '1234567';               // ← 본인 코스 ID로 교체
  const base = location.origin;

  // 1) 강의 목록 수집 (페이지네이션 자동 처리)
  let lectures = [], url = `/api-2.0/courses/${cid}/subscriber-curriculum-items/`
    + `?page_size=200&fields[lecture]=title,asset&fields[asset]=captions`;
  while (url) {
    const r = await fetch(base + url, {headers:{Accept:'application/json'}}).then(r=>r.json());
    (r.results||[]).filter(x=>x._class==='lecture').forEach(x=>lectures.push(x));
    url = r.next ? r.next.replace(base,'') : null;
  }
  console.log('강의 수:', lectures.length);

  // 2) 각 영상의 자막(.vtt) 받아 텍스트만 추출
  let all = [];
  for (const lec of lectures) {
    const caps = (lec.asset && lec.asset.captions) || [];
    const en = caps.find(c=>/en/i.test(c.locale_id)) || caps[0];
    if (!en) { all.push(`\n\n===== ${lec.title} (자막 없음) =====`); continue; }
    const vtt = await fetch(en.url).then(r=>r.text());
    const text = vtt.split('\n')
      .filter(l=>l && !/-->/.test(l) && !/^WEBVTT/.test(l) && !/^\d+$/.test(l))
      .join(' ').replace(/\s+/g,' ').trim();
    all.push(`\n\n===== ${lec.title} =====\n${text}`);
  }

  // 3) 하나로 병합 후 .md 파일로 다운로드
  const result = all.join('\n');
  const blob = new Blob([result], {type:'text/markdown;charset=utf-8'});
  const a = document.createElement('a');
  a.href = URL.createObjectURL(blob);
  a.download = 'transcripts.md';
  document.body.appendChild(a); a.click(); a.remove();
  window.__transcript = result;        // 백업용 전역 변수
  console.log('=> transcripts.md 다운로드 완료 (강의 수:', lectures.length, ')');
})();

스크립트가 하는 일은 딱 세 가지입니다: 강의 목록 조회 → 자막 다운로드 → 텍스트만 추려 파일로 저장. 외부로 데이터를 보내거나 계정 정보를 건드리지 않습니다.

6. STEP 3 — 파일로 저장하기

스크립트가 끝나면 브라우저 다운로드 폴더에 transcripts.md 가 저장됩니다. 콘솔에는 강의 수: N 과 다운로드 완료 메시지가 찍힙니다.

  • 다운로드가 팝업 차단 등으로 안 뜨면, 콘솔에 copy(window.__transcript)직접 타이핑해서 클립보드로 받아 파일에 붙여넣으면 됩니다.
  • 저장한 파일은 정리 작업을 할 작업 폴더(예: transcripts/)에 넣어둡니다.

여기서 한 가지 알아둘 점: 추출된 항목 수와 실제 대본이 있는 항목 수는 다릅니다. 제 경우 전체 192개 항목 중 실제 자막이 있는 건 68개(영상) 였고, 나머지 124개는 Study Tips, 실습 랩, 퀴즈, 소개 자료처럼 영상이 아닌 항목이라 (자막 없음) 으로 표시됐습니다. 즉 이 방법으로 얻는 건 정확히는 “영상 강의 전체의 대본” 입니다. 학습 정리에 필요한 알맹이는 대부분 여기 있습니다.

7. STEP 4 — AI로 정리노트 만들기

이제 transcripts.md 를 Kiro에게 넘겨 정리노트를 만듭니다. 파일을 작업 폴더에 두고 채팅에서 #transcripts.md 로 첨부한 뒤, 파일이 크기 때문에 한 번에 전부가 아니라 섹션 단위로 나눠서 요청했습니다.

프롬프트 예시:

1
2
3
이 대본 파일 읽고 섹션별로 정리노트 만들어줘.
강의별 핵심 요약이랑 시험 포인트, 셀프 체크 퀴즈까지.
번역은 하지 말고 바로 압축해서.

포인트는 “번역본을 따로 만들지 않고 곧바로 압축 정리로 직행” 하는 것입니다. 대본을 그대로 번역한 뒤 다시 정독하는 방식은 강의를 세 번 보는 것과 같아서 비효율적입니다. 요약 + 능동 회상(퀴즈) 위주로 가면 학습 시간이 확 줄어듭니다.

8. 내가 겪은 에러와 해결 (트러블슈팅)

실제로는 한 번에 성공하지 못했습니다. 위 스크립트도 사실 이 과정을 거쳐 다듬어진 결과물이에요. 그런데 여기서도 제가 한 건 별거 없습니다. 대부분 콘솔에 뜬 에러 메시지만 그대로 복사해 붙여넣었어요. 부연 설명도 거의 안 붙이고요.

1
Identifier 'cid' has already been declared

이 한 줄만 던져도 “이전 실행 변수가 남아서 그렇다”며 알아서 고쳐줬습니다. 겪은 에러를 순서대로 정리합니다.

(1) “allow pasting”을 입력하라는 경고

  • 원인: 브라우저가 콘솔 붙여넣기를 보안상 막는 정상 동작.
  • 해결: 콘솔에 allow pasting 을 직접 타이핑 → Enter → 그 뒤 붙여넣기. 세션 유지됨.

(2) courses/undefined/... 로 404

  • 원인: 코스 ID 자동 추출 실패로 URL에 undefined 가 들어감.
  • 해결: STEP 1 방식(이미 오간 요청에서 courses/숫자 찾기)으로 ID를 확보해 직접 대입.

(3) Identifier 'cid' has already been declared

  • 원인: 앞선 실행에서 let/const로 선언한 변수가 콘솔에 남아 재선언 충돌.
  • 해결: 전체 코드를 (async () => { ... })(); 즉시실행 함수로 감싸 스코프를 격리. (또는 페이지 새로고침 후 재실행)

(4) copy is not defined

  • 원인: copy() 는 콘솔 최상위 전용 함수라, async 블록 내부에서 인식 안 될 때가 있음.
  • 해결: 클립보드 대신 Blob으로 파일 다운로드 방식으로 변경. 확실하고 재실행에도 안전.

(5) 스크롤/펼침에도 요청이 안 잡힘

  • 원인: 커리큘럼이 페이지 최초 로드 때 한 번에 로드됨(스크롤 시 추가 호출 없음).
  • 해결: “스크롤 시점”이 아니라 이미 로드된 전체 요청 기록에서 ID를 찾음.

9. 결과와 회고

  • 결과: 클릭 몇 번 + 콘솔 스크립트 한 번으로 영상 68개 대본을 하나의 파일로 확보. 총 분량 약 47만 자. 강의를 하나씩 복붙하던 것과는 비교가 안 되는 속도입니다.
  • 회고: 진짜 병목은 “대본 수집”이 아니라 “정리·암기”였습니다. 수집을 자동화하고 나니, 남는 에너지를 요약과 퀴즈 풀이에 쓸 수 있어 공부 효율이 크게 올랐습니다.
  • 확장: 이 흐름은 유데미뿐 아니라, 자막(.vtt)을 제공하는 다른 학습 플랫폼에도 구조만 맞추면 응용할 수 있습니다.

10. 주의사항 (저작권과 사용 범위)

이 방법은 편리하지만, 반드시 아래를 지켜주세요.

  • 개인 학습 용도로만. 추출한 대본은 강사와 플랫폼의 저작물입니다. 본인이 정당하게 수강 중인 강의에 한해, 개인 복습 목적으로만 사용하세요.
  • 재배포·공유 금지. 대본 원문이나 정리노트를 타인에게 공유하거나 공개적으로 업로드하는 것은 저작권 침해가 될 수 있습니다. 블로그에 올릴 때도 대본 원문은 싣지 말고, “방법과 과정”만 공유하세요. (이 글도 그 원칙을 따릅니다.)
  • 플랫폼 약관 확인. 서비스 이용약관에서 콘텐츠 자동 수집을 제한할 수 있으니, 본인 책임 하에 약관을 확인하세요.
  • 강사에 대한 예의. 좋은 강의를 만든 제작자의 노력을 존중하는 선에서, 어디까지나 “내 공부를 돕는 보조 수단”으로만 활용하는 것을 권합니다.

요약: 도구는 편의를 위한 것이지, 콘텐츠를 빼돌리기 위한 것이 아닙니다. 내가 산 강의를, 나 혼자 더 잘 공부하기 위해 쓰는 선을 지키면 됩니다.

마치며

“복붙 노가다”라고 느껴지는 반복 작업이 있다면, 대개는 자동화할 여지가 있습니다. 이번엔 브라우저 콘솔이 그 열쇠였습니다. 같은 고민을 하던 분께 도움이 되길 바랍니다.

(이 글은 개인 학습 경험을 정리한 것으로, 특정 플랫폼의 공식 기능이 아닙니다. API 구조는 언제든 바뀔 수 있습니다.)