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 YouTube Transcript ✨

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

Il s'agit d'une API Python qui permet d'extraire les transcriptions/sous-titres d'une vidéo YouTube donnée. Elle fonctionne également avec les sous-titres générés automatiquement, prend en charge la traduction des sous-titres et ne nécessite pas de navigateur headless, contrairement aux solutions basées sur Selenium !

La maintenance de ce projet est rendue possible grâce à tous les contributeurs et sponsors. Si vous souhaitez sponsoriser ce projet et voir votre avatar ou le logo de votre entreprise apparaître ci-dessous, cliquez ici. 💖

SearchAPI        supadata        Dumpling AI

Installation

Il est recommandé d'installer ce module via pip :

pip install youtube-transcript-api

Vous pouvez soit intégrer ce module dans une application existante soit l'utiliser via une interface en ligne de commande (CLI).

API

Le moyen le plus simple d'obtenir une transcription pour une vidéo donnée est d'exécuter :

from youtube_transcript_api import YouTubeTranscriptApi

ytt_api = YouTubeTranscriptApi()
ytt_api.fetch(video_id)

Remarque : Par défaut, cette commande tentera d'accéder à la transcription anglaise de la vidéo. Si votre vidéo est dans une autre langue ou si vous souhaitez récupérer une transcription dans une autre langue, veuillez lire la section ci-dessous.

Remarque : Indiquez l'ID de la vidéo, PAS l'URL. Pour une vidéo avec l'URL https://www.youtube.com/watch?v=12345, l'ID est 12345.

Cette commande renverra un objet FetchedTranscript ressemblant à ceci :

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

Cet objet implémente la plupart des interfaces d'une 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)

Si vous préférez manipuler les données brutes de la transcription, vous pouvez appeler fetched_transcript.to_raw_data(), qui renverra une liste de dictionnaires :

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

Récupérer différentes langues

Vous pouvez ajouter le paramètre languages si vous souhaitez vous assurer que les transcriptions sont récupérées dans la langue de votre choix (par défaut en anglais).

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

Il s'agit d'une liste de codes de langue par ordre de priorité décroissante. Dans cet exemple, il tentera d'abord de récupérer la transcription allemande ('de'), puis la transcription anglaise ('en') en cas d'échec. Si vous souhaitez connaître les langues disponibles, consultez list().

Si vous ne voulez qu'une seule langue, vous devez tout de même formater l'argument languages comme une liste :

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

Préserver le formatage

Vous pouvez également ajouter preserve_formatting=True si vous souhaitez conserver les éléments de formatage HTML tels que <i> (italique) et <b> (gras).

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

Lister les transcriptions disponibles

Si vous souhaitez lister toutes les transcriptions disponibles pour une vidéo donnée, vous pouvez appeler :

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

Cette commande renverra un objet TranscriptList qui est itérable et fournit des méthodes pour filtrer la liste des transcriptions par langues et types spécifiques, comme :

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

Par défaut, ce module choisit toujours les transcriptions créées manuellement plutôt que celles générées automatiquement, si une transcription dans la langue demandée est disponible à la fois manuellement et automatiquement. L'objet TranscriptList vous permet de contourner ce comportement par défaut en recherchant des types de transcription spécifiques :

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

Les méthodes find_generated_transcript, find_manually_created_transcript, find_transcript renvoient des objets Transcript. Ils contiennent des métadonnées concernant la transcription :

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

et fournissent la méthode qui permet de récupérer les données réelles de la transcription :

transcript.fetch()

Cette commande renvoie un objet FetchedTranscript, tout comme YouTubeTranscriptApi().fetch().

Traduire une transcription

YouTube propose une fonctionnalité permettant de traduire automatiquement les sous-titres. Ce module permet également d'accéder à cette fonctionnalité. Pour ce faire, les objets Transcript fournissent une méthode translate(), qui renvoie un nouvel objet Transcript traduit :

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

Par exemple

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

Contourner les bannissements d'IP (exception RequestBlocked ou IpBlocked)

Malheureusement, YouTube a commencé à bloquer la plupart des IPs connues pour appartenir à des fournisseurs de cloud (comme AWS, Google Cloud Platform, Azure, etc.), ce qui signifie que vous rencontrerez très probablement des exceptions ReuquestBlocked ou IpBlocked lorsque vous déploierez votre code sur des solutions cloud. La même chose peut arriver à l'IP de votre solution auto-hébergée si vous effectuez trop de requêtes. Vous pouvez contourner ces bannissements d'IP en utilisant des proxies. Cependant, comme YouTube bannira les proxies statiques après une utilisation prolongée, opter pour des proxies résidentiels rotatifs est l'option la plus fiable.

Il existe différents fournisseurs qui proposent des proxies résidentiels rotatifs, mais après avoir testé différentes offres, j'ai trouvé Webshare comme étant la plus fiable et l'ai donc intégrée dans ce module pour faciliter sa configuration.

Utilisation de Webshare

Une fois que vous avez créé un compte Webshare et acheté un package de proxies "Résidentiels" adapté à votre charge de travail (assurez-vous de NE PAS acheter "Proxy Server" ou "Static Residential" !), ouvrez les Paramètres de proxy Webshare pour récupérer votre "Nom d'utilisateur proxy" et "Mot de passe proxy". Avec ces informations, vous pouvez initialiser YouTubeTranscriptApi comme suit :

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)

L'utilisation de WebshareProxyConfig utilisera par défaut des proxies résidentiels rotatifs et ne nécessite aucune configuration supplémentaire.

Notez que des liens de parrainage sont utilisés ici et tout achat effectué via ces liens soutiendra ce projet Open Source, ce qui est très apprécié ! 💖😊🙏💖

Cependant, vous êtes bien sûr libre d'intégrer votre propre solution de proxy en utilisant la classe GenericProxyConfig, si vous préférez utiliser un autre fournisseur ou implémenter votre propre solution, comme couvert dans la section suivante.

Utilisation d'autres solutions de proxy

Alternativement à Webshare, vous pouvez configurer n'importe quel proxy HTTP/HTTPS/SOCKS générique en utilisant la 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)

Sachez que l'utilisation d'un proxy ne garantit pas que vous ne serez pas bloqué, car YouTube peut toujours bloquer l'IP de votre proxy ! Par conséquent, vous devriez toujours choisir une solution qui alterne entre un pool d'adresses proxy si vous souhaitez maximiser la fiabilité.

Remplacer les valeurs par défaut des requêtes

Lors de l'initialisation d'un objet YouTubeTranscriptApi, il créera une requests.Session qui sera utilisée pour toutes les requêtes HTTP(S). Cela permet de mettre en cache les cookies lors de la récupération de plusieurs requêtes. Cependant, vous pouvez optionnellement passer un objet requests.Session dans son constructeur, si vous souhaitez partager manuellement des cookies entre différentes instances de YouTubeTranscriptApi, remplacer les valeurs par défaut, définir des en-têtes personnalisés, spécifier des certificats 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)

Authentification par cookie

Certaines vidéos sont soumises à des restrictions d'âge, ce module ne pourra donc pas y accéder sans une forme d'authentification. Malheureusement, certains changements récents de l'API YouTube ont cassé l'implémentation actuelle de l'authentification par cookie, cette fonctionnalité n'est donc pas disponible pour le moment.

Utilisation des formateurs

Les formateurs sont conçus comme une couche supplémentaire de traitement de la transcription que vous leur passez. L'objectif est de convertir un objet FetchedTranscript en une chaîne de caractères cohérente d'un "format" donné. Comme un texte basique (.txt) ou même des formats ayant une spécification définie comme JSON (.json), WebVTT (.vtt), SRT (.srt), format séparé par des virgules (.csv), etc...

Le sous-module formatters fournit quelques formateurs de base, qui peuvent être utilisés tels quels ou étendus selon vos besoins :

  • JSONFormatter
  • PrettyPrintFormatter
  • TextFormatter
  • WebVTTFormatter
  • SRTFormatter

Voici comment importer depuis le module 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

Exemple de formateur

Imaginons que nous souhaitions récupérer une transcription et la stocker dans un fichier JSON. Cela ressemblerait à ceci :

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

Passage d'arguments supplémentaires

Puisque JSONFormatter utilise json.dumps(), vous pouvez également transmettre des arguments supplémentaires dans .format_transcript(transcript), comme rendre votre fichier de sortie plus lisible en transmettant l'argument indent=2.

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

Exemple de formateur personnalisé

Vous pouvez implémenter votre propre classe de formateur. Il suffit d'hériter de la classe de base Formatter et de vous assurer d'implémenter les méthodes format_transcript(self, transcript: FetchedTranscript, **kwargs) -> str et format_transcripts(self, transcripts: List[FetchedTranscript], **kwargs) -> str qui doivent finalement renvoyer une chaîne de caractères lorsqu'elles sont appelées sur votre instance de formateur.

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

Exécutez le script CLI en utilisant les IDs des vidéos comme paramètres et les résultats seront affichés sur la ligne de commande :

youtube_transcript_api <first_video_id> <second_video_id> ...  

La CLI vous donne également la possibilité de fournir une liste de langues préférées :

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

Vous pouvez également spécifier si vous souhaitez exclure les sous-titres générés automatiquement ou créés manuellement :

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

Si vous préférez écrire dans un fichier ou rediriger vers une autre application, vous pouvez également afficher les résultats au format json en utilisant la ligne suivante :

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

La traduction des transcriptions via la CLI est également possible :

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

Si vous n'êtes pas sûr des langues disponibles pour une vidéo donnée, vous pouvez appeler, pour lister toutes les transcriptions disponibles :

youtube_transcript_api --list-transcripts <first_video_id>

Si l'ID d'une vidéo commence par un trait d'union, vous devrez masquer le trait d'union avec \ pour éviter que la CLI ne le confonde avec un nom d'argument. Par exemple, pour obtenir la transcription de la vidéo avec l'ID -abc123, exécutez :

youtube_transcript_api "\-abc123"

Contourner les bannissements d'IP via la CLI

Si vous rencontrez des erreurs ReqestBlocked ou IpBlocked parce que YouTube bloque votre IP, vous pouvez contourner cela en utilisant des proxies résidentiels comme expliqué dans Contourner les bannissements d'IP. Pour utiliser les proxies "Résidentiels" Webshare via la CLI, vous devrez créer un compte Webshare et acheter un package de proxy "Résidentiel" adapté à votre charge de travail (assurez-vous de NE PAS acheter "Proxy Server" ou "Static Residential" !). Ensuite, vous pouvez utiliser le "Nom d'utilisateur proxy" et le "Mot de passe proxy" que vous trouverez dans vos Paramètres de proxy Webshare, pour exécuter la commande suivante :

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

Si vous préférez utiliser une autre solution de proxy, vous pouvez configurer un proxy HTTP/HTTPS générique en utilisant la commande suivante :

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

Authentification par cookie via la CLI

Pour vous authentifier en utilisant des cookies via la CLI comme expliqué dans Authentification par cookie, exécutez :

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

Avertissement

Ce code utilise une partie non documentée de l'API YouTube, appelée par le client web de YouTube. Il n'y a donc aucune garantie qu'il ne cessera pas de fonctionner demain, s'ils changent le fonctionnement. Cependant, je ferai de mon mieux pour que cela fonctionne à nouveau dès que possible si cela arrive. Donc si cela cesse de fonctionner, faites-le-moi savoir !

Contribution

Pour configurer le projet localement, exécutez les commandes suivantes (nécessite l'installation de poetry) :

poetry install --with test,dev

Il y a des tâches poe pour exécuter les tests, la couverture, le linter et le formateur (vous devrez passer toutes ces étapes pour que la build réussisse) :

poe test
poe coverage
poe format
poe lint

Si vous voulez simplement vous assurer que votre code passe tous les contrôles nécessaires pour obtenir une build verte, vous pouvez simplement exécuter :

poe precommit

Dons

Si ce projet vous rend heureux en réduisant votre temps de développement, vous pouvez me rendre heureux en m'offrant une tasse de café, ou en devenant un Sponsor de ce projet :)

Donate