HomeBlogTranscribePlansAPI Keys

youtube-transcript-api bloqué ? Corriger les bannissements d'IP sur AWS/GCP

Traceback Python montrant une erreur IpBlocked de youtube-transcript-api exécuté sur un serveur cloud

Le script a tourné parfaitement sur votre ordinateur portable pendant des semaines. Puis vous l'avez déployé — Lambda, une machine EC2, Cloud Run, un dyno Heroku, peu importe — et chaque appel à youtube-transcript-api meurt maintenant avec quelque chose comme :

youtube_transcript_api._errors.IpBlocked:
Could not retrieve a transcript for the video ...
YouTube is blocking requests from your IP.

Ou la version côté navigateur du même mur : « Sign in to confirm you're not a bot ». Rien n'a changé dans votre code. La bibliothèque n'est pas cassée. Le problème, c'est votre adresse IP.

Pourquoi ça ne casse qu'en production

youtube-transcript-api fonctionne en récupérant les données de sous-titres de la même manière que le lecteur YouTube — pas de clé API, juste des requêtes HTTP vers YouTube. YouTube tolère cela depuis les connexions résidentielles, ce qui explique pourquoi le développement local se passe bien. Mais les plages d'IP d'AWS, GCP, Azure et Heroku sont publiques, et YouTube conteste en bloc le trafic provenant de ces ASN. Peu importe que vous fassiez trois requêtes par jour ; le blocage porte sur le voisinage réseau, pas sur votre comportement. Redémarrez l'instance, prenez une nouvelle IP élastique, redéployez la fonction — vous atterrissez sur une autre adresse du même pool bloqué.

Cela mérite d'être intégré, car le premier réflexe (ajouter des reprises, des délais, faire tourner les user agents) ne sert à rien. Le signal sur lequel YouTube se base, c'est la provenance des paquets.

Solution 1 : exploiter vos propres proxies résidentiels

La bibliothèque le prend en charge directement — elle fournit WebshareProxyConfig et un GenericProxyConfig pour n'importe quel fournisseur. Faites passer les requêtes par des IP résidentielles et les blocages cessent pour l'essentiel. Ça fonctionne vraiment ; c'est ainsi que survivent tous ceux qui scrapent YouTube à grande échelle.

Le décompte honnête des coûts, cependant :

Si vous exploitez déjà une infrastructure de proxies pour d'autres scraping, greffer cela dessus est raisonnable. Si les transcriptions sont la seule chose dont vous avez besoin, vous vous engagez à opérer une flotte de proxies pour soutenir un seul appel de fonction.

Solution 2 : appeler un endpoint qui mène déjà cette bataille

youtube2text.org gère la rotation de proxies résidentiels côté serveur, donc votre fonction cloud fait une banale requête HTTPS vers une API normale. La migration est presque un chercher-remplacer.

Avant :

from youtube_transcript_api import YouTubeTranscriptApi

transcript = YouTubeTranscriptApi().fetch(video_id)
text = " ".join(snippet.text for snippet in transcript)

Après :

import requests

r = requests.get(
    "https://youtube2text.org/api/transcribe",
    params={"url": video_id},          # full URLs work too
    headers={"x-api-key": "yt_YOUR_KEY"},
)
text = r.json()["result"]["content"]

Pour l'essayer avant de créer un compte, récupérez la clé de démonstration partagée — curl -s https://youtube2text.org/api/demo-key — qui autorise 5 vidéos/mois par IP. Les erreurs reviennent en JSON structuré avec des codes qui méritent d'être gérés : TRANSCRIPT_UNAVAILABLE (404) signifie que la vidéo n'a vraiment aucun sous-titre — pas un blocage, et aucun proxy n'y changera rien ; RATE_LIMIT_EXCEEDED (429) inclut une indication de reprise. Un parcours Python plus complet se trouve dans le guide d'intégration Python.

Quelle solution pour vous

Votre propre clé (distincte du quota de démonstration partagé) demande une connexion Google sur youtube2text.org/app/keys — le niveau gratuit offre 5 vidéos/mois, les formules payantes vont de 5,99 $/mois pour 50 vidéos jusqu'à 19,99 $ en illimité. Pas de numéro de téléphone, pas de carte pour le niveau gratuit.