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

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 :
- Argent : la bande passante résidentielle coûte environ 3 à 8 $/Go selon le fournisseur, et les fournisseurs corrects exigent des engagements mensuels — en pratique 30 à 100 $/mois avant d'avoir récupéré quoi que ce soit. Chaque récupération de transcription est petite (quelques centaines de Ko), donc la bande passante n'est pas le problème ; ce sont les minimums et la gestion du compte.
- Ingénierie : la rotation, la logique de reprise après bannissement et la supervision sont pour vous. Les IP résidentielles se font contester aussi, juste moins souvent, donc il faut quand même détecter les échecs et rerouter.
- Attention continue : YouTube change les choses. Les configurations de proxy qui fonctionnaient en mars demandent des soins en juin.
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
- Restez sur youtube-transcript-api + vos propres proxies si vous récupérez des milliers de transcriptions par jour, avez déjà des comptes proxy et quelqu'un pour porter la configuration. À ce volume, la tarification au Go peut battre la tarification à la vidéo.
- Passez à un endpoint hébergé si les transcriptions sont une fonctionnalité, pas votre produit. Un appel HTTP, du JSON en sortie, et le problème de blocage devient l'astreinte de quelqu'un d'autre.
- Aucune des deux ne corrige les sous-titres manquants. Pour les vidéos qui renvoient
TRANSCRIPT_UNAVAILABLE, le repli est la reconnaissance vocale — voir Whisper ou sous-titres YouTube pour savoir quand cela en vaut le coût. Et si vous étiez sur le point d'essayer yt-dlp à la place, sachez qu'il subit le même blocage d'IP depuis les adresses de datacenter.
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.