Last translated: 12 Jun 2025

Translation Not Available Yet

This repository's README hasn't been translated yet. Once translated, it will be easier to read and understand in your native language (中文).

After translating, add the links to README so others can view it directly.

✨ YouTube Transcript API ✨

Donate Build Status Coverage Status MIT license Current Version Supported Python Versions

이 Python API는 주어진 YouTube 동영상의 자막/대본을 추출할 수 있게 해줍니다. 자동 생성된 자막도 지원하며, Selenium 기반 솔루션과 달리 헤드리스 브라우저가 필요하지 않습니다! 또한 자막 번역 기능도 제공합니다.

이 프로젝트의 유지보수는 모든 기여자스폰서 덕분에 가능합니다. 이 프로젝트를 후원하고 아바타나 회사 로고를 아래에 표시하고 싶으시면 여기를 클릭하세요. 💖

SearchAPI        supadata        Dumpling AI

설치

이 모듈은 pip를 사용하여 설치하는 것을 권장합니다:

pip install youtube-transcript-api

이 모듈을 기존 애플리케이션에 통합하거나 CLI를 통해 사용할 수 있습니다.

API

주어진 동영상의 대본을 얻는 가장 쉬운 방법은 다음과 같이 실행하는 것입니다:

from youtube_transcript_api import YouTubeTranscriptApi

ytt_api = YouTubeTranscriptApi()
ytt_api.fetch(video_id)

참고: 기본적으로 이는 동영상의 영어 대본에 접근하려고 시도합니다. 동영상이 다른 언어로 되어 있거나 다른 언어의 대본을 가져오고 싶다면 아래 섹션을 참조하세요.

참고: 동영상 URL이 아닌 동영상 ID를 전달하세요. URL이 https://www.youtube.com/watch?v=12345인 동영상의 ID는 12345입니다.

이렇게 하면 다음과 같은 FetchedTranscript 객체가 반환됩니다:

FetchedTranscript(
    snippets=[
        FetchedTranscriptSnippet(
            text="Hey there",
            start=0.0,
            duration=1.54,
        ),
        FetchedTranscriptSnippet(
            text="how are you",
            start=1.54,
            duration=4.16,
        ),
        # ...
    ],
    video_id="12345",
    language="English",
    language_code="en",
    is_generated=False,
)

이 객체는 List의 대부분 인터페이스를 구현합니다:

ytt_api = YouTubeTranscriptApi()
fetched_transcript = ytt_api.fetch(video_id)

# is iterable
for snippet in fetched_transcript:
    print(snippet.text)

# indexable
last_snippet = fetched_transcript[-1]

# provides a length
snippet_count = len(fetched_transcript)

원시 대본 데이터를 직접 처리하고 싶다면 fetched_transcript.to_raw_data()를 호출할 수 있으며, 이는 다음과 같은 딕셔너리 리스트를 반환합니다:

[
    {
        'text': 'Hey there',
        'start': 0.0,
        'duration': 1.54
    },
    {
        'text': 'how are you',
        'start': 1.54
        'duration': 4.16
    },
    # ...
]

다른 언어로 대본 가져오기

원하는 언어로 대본을 가져오고 싶다면 languages 매개변수를 추가할 수 있습니다 (기본값은 영어입니다).

YouTubeTranscriptApi().fetch(video_id, languages=['de', 'en'])

이는 내림차순 우선순위의 언어 코드 리스트입니다. 이 예제에서는 먼저 독일어 대본('de')을 가져오려고 시도하고, 실패할 경우 영어 대본('en')을 가져옵니다. 사용 가능한 언어를 확인하려면 list()를 참조하세요.

하나의 언어만 원하는 경우에도 languages 인수를 리스트 형식으로 제공해야 합니다.

YouTubeTranscriptApi().fetch(video_id, languages=['de'])

형식 유지

<i>(기울임꼴) 및 <b>(굵게)와 같은 HTML 형식 요소를 유지하고 싶다면 preserve_formatting=True를 추가할 수 있습니다.

YouTubeTranscriptApi().fetch(video_ids, languages=['de', 'en'], preserve_formatting=True)

사용 가능한 대본 목록 보기

주어진 동영상에 대해 사용 가능한 모든 대본을 나열하려면 다음과 같이 호출할 수 있습니다:

ytt_api = YouTubeTranscriptApi()
transcript_list = ytt_api.list(video_id)

이는 반복 가능한 TranscriptList 객체를 반환하며, 특정 언어 및 유형으로 대본 목록을 필터링하는 메서드를 제공합니다:

transcript = transcript_list.find_transcript(['de', 'en'])

기본적으로 이 모듈은 요청된 언어로 수동 생성된 대본과 자동 생성된 대본이 모두 있는 경우 수동 생성된 대본을 선택합니다. TranscriptList를 사용하면 특정 대본 유형을 검색하여 이 기본 동작을 우회할 수 있습니다:

# filter for manually created transcripts
transcript = transcript_list.find_manually_created_transcript(['de', 'en'])

# or automatically generated ones
transcript = transcript_list.find_generated_transcript(['de', 'en'])

find_generated_transcript, find_manually_created_transcript, find_transcript 메서드는 Transcript 객체를 반환합니다. 이 객체는 대본에 대한 메타데이터를 포함합니다:

print(
    transcript.video_id,
    transcript.language,
    transcript.language_code,
    # whether it has been manually created or generated by YouTube
    transcript.is_generated,
    # whether this transcript can be translated or not
    transcript.is_translatable,
    # a list of languages the transcript can be translated to
    transcript.translation_languages,
)

그리고 실제 대본 데이터를 가져올 수 있는 메서드를 제공합니다:

transcript.fetch()

이는 YouTubeTranscriptApi().fetch()와 마찬가지로 FetchedTranscript 객체를 반환합니다.

대본 번역

YouTube는 자막을 자동으로 번역하는 기능을 제공합니다. 이 모듈을 통해 이 기능에 접근할 수도 있습니다. 이를 위해 Transcript 객체는 translate() 메서드를 제공하며, 이는 새로운 번역된 Transcript 객체를 반환합니다:

transcript = transcript_list.find_transcript(['en'])
translated_transcript = transcript.translate('de')
print(translated_transcript.fetch())

예제

from youtube_transcript_api import YouTubeTranscriptApi

ytt_api = YouTubeTranscriptApi()

# retrieve the available transcripts
transcript_list = ytt_api.list('video_id')

# iterate over all available transcripts
for transcript in transcript_list:

    # the Transcript object provides metadata properties
    print(
        transcript.video_id,
        transcript.language,
        transcript.language_code,
        # whether it has been manually created or generated by YouTube
        transcript.is_generated,
        # whether this transcript can be translated or not
        transcript.is_translatable,
        # a list of languages the transcript can be translated to
        transcript.translation_languages,
    )

    # fetch the actual transcript data
    print(transcript.fetch())

    # translating the transcript will return another transcript object
    print(transcript.translate('en').fetch())

# you can also directly filter for the language you are looking for, using the transcript list
transcript = transcript_list.find_transcript(['de', 'en'])  

# or just filter for manually created transcripts  
transcript = transcript_list.find_manually_created_transcript(['de', 'en'])  

# or automatically generated ones  
transcript = transcript_list.find_generated_transcript(['de', 'en'])

IP 차단 우회 (RequestBlocked 또는 IpBlocked 예외 처리)

유감스럽게도 YouTube는 AWS, Google Cloud Platform, Azure 등과 같은 클라우드 제공업체에 속한 대부분의 IP를 차단하기 시작했으며, 이는 코드를 클라우드 솔루션에 배포할 때 ReuquestBlocked 또는 IpBlocked 예외가 발생할 가능성이 높다는 것을 의미합니다. 너무 많은 요청을 하는 경우 자체 호스팅 솔루션의 IP에도 동일한 문제가 발생할 수 있습니다. 프록시를 사용하여 이러한 IP 차단을 우회할 수 있습니다. 그러나 YouTube는 정적 프록시를 장기간 사용한 후 차단하므로, 회전하는 주거용 프록시를 사용하는 것이 가장 신뢰할 수 있는 옵션입니다.

회전하는 주거용 프록시를 제공하는 다양한 공급자가 있지만, 여러 제품을 테스트한 결과 Webshare가 가장 신뢰할 수 있는 것으로 확인되어 이 모듈에 통합하여 설정을 최대한 쉽게 만들었습니다.

Webshare 사용

Webshare 계정을 생성하고 작업량에 적합한 "Residential" 프록시 패키지를 구매한 후 ("Proxy Server" 또는 "Static Residential"을 구매하지 않도록 주의하세요!), Webshare Proxy Settings에서 "Proxy Username"과 "Proxy Password"를 확인하세요. 이 정보를 사용하여 다음과 같이 YouTubeTranscriptApi를 초기화할 수 있습니다:

from youtube_transcript_api import YouTubeTranscriptApi
from youtube_transcript_api.proxies import WebshareProxyConfig

ytt_api = YouTubeTranscriptApi(
    proxy_config=WebshareProxyConfig(
        proxy_username="<proxy-username>",
        proxy_password="<proxy-password>",
    )
)

# all requests done by ytt_api will now be proxied through Webshare
ytt_api.fetch(video_id)

WebshareProxyConfig를 사용하면 회전하는 주거용 프록시를 기본으로 사용하며 추가 구성이 필요하지 않습니다.

여기서는 추천 링크가 사용되었으며 이 링크를 통해 이루어진 모든 구매는 이 오픈 소스 프로젝트를 지원하게 되어 매우 감사합니다! 💖😊🙏💖

그러나 다른 공급자를 사용하거나 자신만의 솔루션을 구현하고 싶다면 다음 섹션에서 다루는 GenericProxyConfig 클래스를 사용하여 자체 프록시 솔루션을 통합할 수도 있습니다.

다른 프록시 솔루션 사용

Webshare 대신 GenericProxyConfig 클래스를 사용하여 일반적인 HTTP/HTTPS/SOCKS 프록시를 설정할 수 있습니다:

from youtube_transcript_api import YouTubeTranscriptApi
from youtube_transcript_api.proxies import GenericProxyConfig

ytt_api = YouTubeTranscriptApi(
    proxy_config=GenericProxyConfig(
        http_url="http://user:[email protected]:port",
        https_url="https://user:[email protected]:port",
    )
)

# all requests done by ytt_api will now be proxied using the defined proxy URLs
ytt_api.fetch(video_id)

프록시를 사용한다고 해서 차단되지 않을 것이라는 보장은 없으며, YouTube는 언제든지 프록시의 IP를 차단할 수 있습니다! 따라서 신뢰성을 극대화하려면 프록시 주소 풀을 회전시키는 솔루션을 선택해야 합니다.

요청 기본값 덮어쓰기

YouTubeTranscriptApi 객체를 초기화할 때 모든 HTTP(S) 요청에 사용될 requests.Session이 생성됩니다. 이는 여러 요청을 검색할 때 쿠키를 캐시할 수 있게 해줍니다. 그러나 requests.Session 객체를 생성자에 전달하여 YouTubeTranscriptApi의 다른 인스턴스 간에 쿠키를 수동으로 공유하거나 기본값을 덮어쓰거나 사용자 정의 헤더를 지정하거나 SSL 인증서를 지정할 수 있습니다.

from requests import Session

http_client = Session()

# set custom header
http_client.headers.update({"Accept-Encoding": "gzip, deflate"})

# set path to CA_BUNDLE file
http_client.verify = "/path/to/certfile"

ytt_api = YouTubeTranscriptApi(http_client=http_client)
ytt_api.fetch(video_id)

# share same Session between two instances of YouTubeTranscriptApi
ytt_api_2 = YouTubeTranscriptApi(http_client=http_client)
# now shares cookies with ytt_api
ytt_api_2.fetch(video_id)

쿠키 인증

일부 동영상은 연령 제한이 있어 이 모듈은 인증 없이는 해당 동영상에 접근할 수 없습니다. 불행히도 YouTube API의 최근 변경 사항으로 인해 쿠키 기반 인증의 현재 구현이 중단되어 이 기능은 현재 사용할 수 없습니다.

포매터 사용

포매터는 전달한 대본에 대한 추가 처리 계층으로 사용됩니다. 목표는 FetchedTranscript 객체를 주어진 "형식"의 일관된 문자열로 변환하는 것입니다. 기본 텍스트(.txt) 또는 JSON(.json), WebVTT(.vtt), SRT(.srt), 쉼표로 구분된 형식(.csv) 등과 같이 정의된 사양이 있는 형식까지 가능합니다.

formatters 서브모듈은 몇 가지 기본 포매터를 제공하며, 그대로 사용하거나 필요에 따라 확장할 수 있습니다:

  • JSONFormatter
  • PrettyPrintFormatter
  • TextFormatter
  • WebVTTFormatter
  • SRTFormatter

다음은 formatters 모듈에서 가져오는 방법입니다.

# the base class to inherit from when creating your own formatter.
from youtube_transcript_api.formatters import Formatter

# some provided subclasses, each outputs a different string format.
from youtube_transcript_api.formatters import JSONFormatter
from youtube_transcript_api.formatters import TextFormatter
from youtube_transcript_api.formatters import WebVTTFormatter
from youtube_transcript_api.formatters import SRTFormatter

포매터 예제

대본을 검색하여 JSON 파일로 저장하려는 경우 다음과 같이 할 수 있습니다:

# your_custom_script.py

from youtube_transcript_api import YouTubeTranscriptApi
from youtube_transcript_api.formatters import JSONFormatter

ytt_api = YouTubeTranscriptApi()
transcript = ytt_api.fetch(video_id)

formatter = JSONFormatter()

# .format_transcript(transcript) turns the transcript into a JSON string.
json_formatted = formatter.format_transcript(transcript)

# Now we can write it out to a file.
with open('your_filename.json', 'w', encoding='utf-8') as json_file:
    json_file.write(json_formatted)

# Now should have a new JSON file that you can easily read back into Python.

추가 키워드 인수 전달

JSONFormatter는 json.dumps()를 활용하므로 .format_transcript(transcript)indent=2와 같은 키워드 인수를 전달하여 파일 출력을 보기 좋게 만들 수 있습니다.

json_formatted = JSONFormatter().format_transcript(transcript, indent=2)

사용자 정의 포매터 예제

자신만의 포매터 클래스를 구현할 수 있습니다. Formatter 기본 클래스를 상속받고 format_transcript(self, transcript: FetchedTranscript, **kwargs) -> strformat_transcripts(self, transcripts: List[FetchedTranscript], **kwargs) -> str 메서드를 구현하기만 하면 됩니다. 이 메서드는 최종적으로 포매터 인스턴스에서 호출될 때 문자열을 반환해야 합니다.

class MyCustomFormatter(Formatter):
    def format_transcript(self, transcript: FetchedTranscript, **kwargs) -> str:
        # Do your custom work in here, but return a string.
        return 'your processed output data as a string.'

    def format_transcripts(self, transcripts: List[FetchedTranscript], **kwargs) -> str:
        # Do your custom work in here to format a list of transcripts, but return a string.
        return 'your processed output data as a string.'

CLI

동영상 ID를 매개변수로 사용하여 CLI 스크립트를 실행하면 결과가 명령줄에 출력됩니다:

youtube_transcript_api <first_video_id> <second_video_id> ...  

CLI는 또한 선호하는 언어 목록을 제공할 수 있는 옵션을 제공합니다:

youtube_transcript_api <first_video_id> <second_video_id> ... --languages de en  

자동 생성된 자막이나 수동 생성된 자막을 제외할지 여부를 지정할 수도 있습니다:

youtube_transcript_api <first_video_id> <second_video_id> ... --languages de en --exclude-generated
youtube_transcript_api <first_video_id> <second_video_id> ... --languages de en --exclude-manually-created

결과를 파일에 쓰거나 다른 애플리케이션으로 파이프하려면 다음 줄을 사용하여 결과를 json으로 출력할 수도 있습니다:

youtube_transcript_api <first_video_id> <second_video_id> ... --languages de en --format json > transcripts.json

CLI를 사용하여 대본을 번역하는 것도 가능합니다:

youtube_transcript_api <first_video_id> <second_video_id> ... --languages en --translate de

주어진 동영상에 대해 어떤 언어가 사용 가능한지 확실하지 않은 경우 다음을 호출하여 사용 가능한 모든 대본을 나열할 수 있습니다:

youtube_transcript_api --list-transcripts <first_video_id>

동영상 ID가 하이픈으로 시작하는 경우 CLI가 이를 인수 이름으로 오해하지 않도록 \를 사용하여 하이픈을 마스킹해야 합니다. 예를 들어 ID가 -abc123인 동영상의 대본을 가져오려면 다음과 같이 실행하세요:

youtube_transcript_api "\-abc123"

CLI를 사용하여 IP 차단 우회

YouTube가 IP를 차단하여 ReqestBlocked 또는 IpBlocked 오류가 발생하는 경우 IP 차단 우회에서 설명한 대로 주거용 프록시를 사용하여 이를 우회할 수 있습니다. CLI를 통해 Webshare "Residential" 프록시를 사용하려면 Webshare 계정을 생성하고 작업량에 적합한 "Residential" 프록시 패키지를 구매해야 합니다 ("Proxy Server" 또는 "Static Residential"을 구매하지 않도록 주의하세요!). 그런 다음 Webshare Proxy Settings에서 찾을 수 있는 "Proxy Username"과 "Proxy Password"를 사용하여 다음 명령을 실행하세요:

youtube_transcript_api <first_video_id> <second_video_id> --webshare-proxy-username "username" --webshare-proxy-password "password"

다른 프록시 솔루션을 사용하려는 경우 다음 명령을 사용하여 일반 HTTP/HTTPS 프록시를 설정할 수 있습니다:

youtube_transcript_api <first_video_id> <second_video_id> --http-proxy http://user:pass@domain:port --https-proxy https://user:pass@domain:port

CLI를 사용한 쿠키 인증

쿠키 인증에서 설명한 대로 CLI를 통해 쿠키를 사용하여 인증하려면 다음을 실행하세요:

youtube_transcript_api <first_video_id> <second_video_id> --cookies /path/to/your/cookies.txt

경고

이 코드는 YouTube 웹 클라이언트에서 호출되는 YouTube API의 문서화되지 않은 부분을 사용합니다. 따라서 YouTube가 작동 방식을 변경하면 내일 작동이 중단될 수 있다는 보장이 없습니다. 그러나 그런 일이 발생하면 가능한 한 빨리 다시 작동하도록 최선을 다할 것입니다. 따라서 작동이 중단되면 알려주세요!

기여하기

로컬에서 프로젝트를 설정하려면 다음을 실행하세요 (poetry 설치 필요):

poetry install --with test,dev

테스트, 커버리지, 린터 및 포매터를 실행하는 poe 작업이 있습니다 (빌드가 성공하려면 이 모든 것을 통과해야 합니다):

poe test
poe coverage
poe format
poe lint

코드가 빌드를 성공시키기 위해 필요한 모든 검사를 통과하는지 확인하고 싶다면 간단히 다음을 실행할 수 있습니다:

poe precommit

기부

이 프로젝트가 개발 시간을 단축하여 기쁨을 준다면, 커피 한 잔을 사주거나 이 프로젝트의 스폰서가 되어 기쁨을 나눠주세요 :)

기부하기