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.

✨ API de Transcrição do YouTube ✨

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

Esta é uma API Python que permite recuperar a transcrição/legendas de um vídeo do YouTube. Ela também funciona com legendas geradas automaticamente, suporta tradução de legendas e não requer um navegador headless, como outras soluções baseadas em selenium!

A manutenção deste projeto é possível graças a todos os contribuidores e patrocinadores. Se deseja patrocinar este projeto e ter seu avatar ou logo da empresa aparecer abaixo clique aqui. 💖

SearchAPI        supadata        Dumpling AI

Instalação

Recomenda-se instalar este módulo usando pip:

pip install youtube-transcript-api

Você pode integrar este módulo em uma aplicação existente ou apenas usá-lo via CLI.

API

A maneira mais fácil de obter uma transcrição para um vídeo específico é executar:

from youtube_transcript_api import YouTubeTranscriptApi

ytt_api = YouTubeTranscriptApi()
ytt_api.fetch(video_id)

Nota: Por padrão, isso tentará acessar a transcrição em inglês do vídeo. Se o seu vídeo estiver em outro idioma ou se você deseja obter a transcrição em um idioma diferente, leia a seção abaixo.

Nota: Passe o ID do vídeo, NÃO a URL do vídeo. Para um vídeo com a URL https://www.youtube.com/watch?v=12345, o ID é 12345.

Isso retornará um objeto FetchedTranscript semelhante a este:

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,
)

Este objeto implementa a maioria das interfaces de uma 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)

Se preferir lidar com os dados brutos da transcrição, você pode chamar fetched_transcript.to_raw_data(), que retornará uma lista de dicionários:

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

Obter diferentes idiomas

Você pode adicionar o parâmetro languages se quiser garantir que as transcrições sejam recuperadas no idioma desejado (o padrão é inglês).

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

É uma lista de códigos de idioma em prioridade decrescente. Neste exemplo, ele tentará primeiro obter a transcrição em alemão ('de') e, se falhar, buscará a transcrição em inglês ('en'). Se quiser descobrir quais idiomas estão disponíveis primeiro, consulte list().

Se você quiser apenas um idioma, ainda precisa formatar o argumento languages como uma lista:

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

Preservar formatação

Você também pode adicionar preserve_formatting=True se quiser manter elementos de formatação HTML como <i> (itálico) e <b> (negrito).

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

Listar transcrições disponíveis

Se quiser listar todas as transcrições disponíveis para um vídeo específico, você pode chamar:

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

Isso retornará um objeto TranscriptList que é iterável e fornece métodos para filtrar a lista de transcrições por idiomas e tipos específicos, como:

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

Por padrão, este módulo sempre escolhe transcrições criadas manualmente em vez de geradas automaticamente, se uma transcrição no idioma solicitado estiver disponível em ambos os formatos. O TranscriptList permite que você ignore esse comportamento padrão, procurando por tipos específicos de transcrição:

# 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'])

Os métodos find_generated_transcript, find_manually_created_transcript, find_transcript retornam objetos Transcript. Eles contêm metadados sobre a transcrição:

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,
)

e fornecem o método que permite obter os dados reais da transcrição:

transcript.fetch()

Isso retorna um objeto FetchedTranscript, assim como YouTubeTranscriptApi().fetch() faz.

Traduzir transcrição

O YouTube possui um recurso que permite traduzir legendas automaticamente. Este módulo também possibilita acessar esse recurso. Para isso, os objetos Transcript fornecem um método translate(), que retorna um novo objeto Transcript traduzido:

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

Por exemplo

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'])

Contornando bloqueios de IP (exceção RequestBlocked ou IpBlocked)

Infelizmente, o YouTube começou a bloquear a maioria dos IPs conhecidos por pertencerem a provedores de nuvem (como AWS, Google Cloud Platform, Azure, etc.), o que significa que você provavelmente encontrará exceções RequestBlocked ou IpBlocked ao implantar seu código em qualquer solução de nuvem. O mesmo pode acontecer com o IP da sua solução self-hosted, se você fizer muitas solicitações. Você pode contornar esses bloqueios de IP usando proxies. No entanto, como o YouTube pode banir proxies estáticos após uso prolongado, optar por proxies residenciais rotativos é a opção mais confiável.

Existem diferentes provedores que oferecem proxies residenciais rotativos, mas após testar diferentes opções, descobri que o Webshare é o mais confiável e, portanto, o integrei a este módulo para facilitar sua configuração.

Usando Webshare

Depois de criar uma conta no Webshare e comprar um pacote de proxy "Residencial" adequado à sua carga de trabalho (certifique-se de NÃO comprar "Proxy Server" ou "Static Residential"!), acesse as Configurações de Proxy do Webshare para recuperar seu "Proxy Username" e "Proxy Password". Com essas informações, você pode inicializar o YouTubeTranscriptApi da seguinte forma:

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)

Usar o WebshareProxyConfig padronizará o uso de proxies residenciais rotativos e não requer configuração adicional.

Observe que links de referência são usados aqui e qualquer compra feita através desses links apoiará este projeto Open Source, o que é muito apreciado! 💖😊🙏💖

No entanto, você é livre para integrar sua própria solução de proxy usando a classe GenericProxyConfig, se preferir usar outro provedor ou implementar sua própria solução, conforme abordado na próxima seção.

Usando outras soluções de Proxy

Alternativamente ao uso do Webshare, você pode configurar qualquer proxy HTTP/HTTPS/SOCKS genérico usando a classe GenericProxyConfig:

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)

Esteja ciente de que usar um proxy não garante que você não será bloqueado, pois o YouTube pode sempre bloquear o IP do seu proxy! Portanto, você deve sempre escolher uma solução que faça rotação por um pool de endereços de proxy, se quiser maximizar a confiabilidade.

Sobrescrevendo padrões de solicitação

Ao inicializar um objeto YouTubeTranscriptApi, ele criará um requests.Session que será usado para todas as solicitações HTTP(S). Isso permite o cache de cookies ao recuperar várias solicitações. No entanto, você pode opcionalmente passar um objeto requests.Session em seu construtor, se quiser compartilhar cookies manualmente entre diferentes instâncias de YouTubeTranscriptApi, sobrescrever padrões, definir cabeçalhos personalizados, especificar certificados SSL, etc.

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)

Autenticação por Cookie

Alguns vídeos têm restrição de idade, então este módulo não poderá acessá-los sem algum tipo de autenticação. Infelizmente, algumas mudanças recentes na API do YouTube quebraram a implementação atual da autenticação baseada em cookie, então esse recurso não está disponível no momento.

Usando Formatadores

Formatadores são destinados a ser uma camada adicional de processamento da transcrição que você passa para eles. O objetivo é converter um objeto FetchedTranscript em uma string consistente de um determinado "formato". Como um texto básico (.txt) ou até formatos que têm uma especificação definida, como JSON (.json), WebVTT (.vtt), SRT (.srt), formato separado por vírgulas (.csv), etc...

O submódulo formatters fornece alguns formatadores básicos, que podem ser usados como estão ou estendidos conforme suas necessidades:

  • JSONFormatter
  • PrettyPrintFormatter
  • TextFormatter
  • WebVTTFormatter
  • SRTFormatter

Aqui está como importar do módulo 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

Exemplo de Formatador

Digamos que queremos recuperar uma transcrição e armazená-la em um arquivo JSON. Isso seria algo assim:

# 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.

Passando argumentos de palavra-chave extras

Como o JSONFormatter utiliza json.dumps(), você também pode encaminhar argumentos de palavra-chave para .format_transcript(transcript), como tornar a saída do arquivo mais legível, encaminhando o argumento indent=2.

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

Exemplo de Formatador Personalizado

Você pode implementar sua própria classe de formatador. Basta herdar da classe base Formatter e garantir que você implemente os métodos format_transcript(self, transcript: FetchedTranscript, **kwargs) -> str e format_transcripts(self, transcripts: List[FetchedTranscript], **kwargs) -> str, que devem retornar uma string quando chamados em sua instância de formatador.

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

Execute o script CLI usando os IDs dos vídeos como parâmetros e os resultados serão impressos na linha de comando:

youtube_transcript_api <first_video_id> <second_video_id> ...  

A CLI também oferece a opção de fornecer uma lista de idiomas preferidos:

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

Você também pode especificar se deseja excluir legendas geradas automaticamente ou criadas manualmente:

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

Se preferir escrever em um arquivo ou canalizar para outro aplicativo, você também pode gerar os resultados como json usando a seguinte linha:

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

Traduzir transcrições usando a CLI também é possível:

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

Se não tiver certeza de quais idiomas estão disponíveis para um determinado vídeo, você pode chamar para listar todas as transcrições disponíveis:

youtube_transcript_api --list-transcripts <first_video_id>

Se o ID de um vídeo começar com um hífen, você terá que mascarar o hífen usando \ para evitar que a CLI o confunda com um nome de argumento. Por exemplo, para obter a transcrição do vídeo com o ID -abc123, execute:

youtube_transcript_api "\-abc123"

Contornando bloqueios de IP usando a CLI

Se você estiver enfrentando erros RequestBlocked ou IpBlocked porque o YouTube bloqueou seu IP, você pode contornar isso usando proxies residenciais, conforme explicado em Contornando bloqueios de IP. Para usar proxies "Residenciais" do Webshare através da CLI, você precisará criar uma conta no Webshare e comprar um pacote de proxy "Residencial" adequado à sua carga de trabalho (certifique-se de NÃO comprar "Proxy Server" ou "Static Residential"!). Em seguida, você pode usar o "Proxy Username" e "Proxy Password", que podem ser encontrados nas suas Configurações de Proxy do Webshare, para executar o seguinte comando:

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

Se preferir usar outra solução de proxy, você pode configurar um proxy HTTP/HTTPS genérico usando o seguinte comando:

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

Autenticação por Cookie usando a CLI

Para autenticar usando cookies através da CLI, conforme explicado em Autenticação por Cookie, execute:

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

Aviso

Este código usa uma parte não documentada da API do YouTube, que é chamada pelo cliente web do YouTube. Portanto, não há garantia de que ele não deixará de funcionar amanhã, se eles mudarem como as coisas funcionam. No entanto, farei o possível para corrigir as coisas o mais rápido possível, se isso acontecer. Portanto, se parar de funcionar, me avise!

Contribuindo

Para configurar o projeto localmente, execute o seguinte (requer poetry instalado):

poetry install --with test,dev

Há tarefas poe para executar testes, cobertura, linter e formatador (você precisará passar por todos eles para que a build seja aprovada):

poe test
poe coverage
poe format
poe lint

Se você apenas quiser garantir que seu código passe em todas as verificações necessárias para obter uma build verde, pode simplesmente executar:

poe precommit

Doações

Se este projeto te deixa feliz, reduzindo seu tempo de desenvolvimento, você pode me deixar feliz me oferecendo um café ou se tornando um Patrocinador deste projeto :)

Donate