youtube-transcript-api bloccata? Risolvere i ban IP su AWS/GCP

Lo script ha girato perfettamente sul tuo laptop per settimane. Poi lo hai deployato — Lambda, una macchina EC2, Cloud Run, un dyno Heroku, non importa — e ora ogni singola chiamata a youtube-transcript-api muore con qualcosa tipo:
youtube_transcript_api._errors.IpBlocked:
Could not retrieve a transcript for the video ...
YouTube is blocking requests from your IP.
Oppure la versione da browser dello stesso muro: "Sign in to confirm you're not a bot". Nulla è cambiato nel tuo codice. La libreria non è rotta. Il problema è il tuo indirizzo IP.
Perché si rompe solo in produzione
youtube-transcript-api funziona recuperando i dati dei sottotitoli nello stesso modo del player di YouTube — nessuna chiave API, solo richieste HTTP verso YouTube. YouTube lo tollera dalle connessioni residenziali, ed è per questo che lo sviluppo locale sembra andare liscio. Ma i range IP di AWS, GCP, Azure e Heroku sono di dominio pubblico, e YouTube contesta a tappeto il traffico proveniente da quegli ASN. Non importa che tu faccia tre richieste al giorno; il blocco riguarda il quartiere di rete, non il tuo comportamento. Riavvia l'istanza, prendi un nuovo elastic IP, rideploya la funzione — atterri su un altro indirizzo dello stesso pool bloccato.
Vale la pena interiorizzarlo, perché il primo istinto (aggiungere retry, aggiungere ritardi, ruotare gli user agent) non aiuta. Il segnale su cui YouTube si basa è da dove arrivano i pacchetti.
Soluzione 1: gestire i tuoi proxy residenziali
La libreria lo supporta direttamente — include WebshareProxyConfig e una GenericProxyConfig per qualsiasi provider. Instrada le richieste attraverso IP residenziali e i blocchi in gran parte cessano. Funziona davvero; è così che sopravvive chiunque faccia scraping di YouTube su larga scala.
Il conto onesto dei costi, però:
- Soldi: la banda residenziale costa all'incirca 3-8 $/GB a seconda del provider, e i provider decenti vogliono impegni mensili — realisticamente 30-100 $/mese prima di aver recuperato qualsiasi cosa. Ogni fetch di trascrizione è piccolo (qualche centinaio di KB), quindi la banda non è il dolore; lo sono i minimi contrattuali e l'overhead degli account.
- Ingegneria: la rotazione, la logica di retry al ban e il monitoraggio sono tuoi. Anche gli IP residenziali vengono contestati, solo meno spesso, quindi devi comunque rilevare i fallimenti e reinstradare.
- Attenzione continua: YouTube cambia le cose. Configurazioni proxy che funzionavano a marzo richiedono cure a giugno.
Se gestisci già un'infrastruttura proxy per altro scraping, aggiungerci questo è ragionevole. Se le trascrizioni sono l'unica cosa che ti serve, ti stai impegnando a gestire una flotta di proxy per supportare una singola chiamata di funzione.
Soluzione 2: chiamare un endpoint che combatte già questa battaglia
youtube2text.org esegue la rotazione dei proxy residenziali lato server, quindi la tua cloud function fa una noiosa richiesta HTTPS a una API normale. La migrazione è quasi un trova-e-sostituisci.
Prima:
from youtube_transcript_api import YouTubeTranscriptApi
transcript = YouTubeTranscriptApi().fetch(video_id)
text = " ".join(snippet.text for snippet in transcript)
Dopo:
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"]
Per provarlo prima di creare un account, prendi la chiave demo condivisa — curl -s https://youtube2text.org/api/demo-key — che consente 5 video al mese per IP. Gli errori tornano come JSON strutturato con codici che vale la pena gestire: TRANSCRIPT_UNAVAILABLE (404) significa che il video davvero non ha sottotitoli — non è un blocco, e nessun proxy lo risolverà; RATE_LIMIT_EXCEEDED (429) include un suggerimento di retry. C'è una guida Python più completa nella guida all'integrazione Python.
Quale soluzione è giusta per te
- Resta su youtube-transcript-api + i tuoi proxy se recuperi migliaia di trascrizioni al giorno, hai già account proxy e qualcuno che si prenda in carico la configurazione. A quel volume, il prezzo per GB può battere il prezzo per video.
- Passa a un endpoint hosted se le trascrizioni sono una feature, non il tuo prodotto. Una chiamata HTTP, JSON in uscita, e il problema dei blocchi è il cercapersone di qualcun altro.
- Nessuna delle due risolve i sottotitoli mancanti. Per i video che restituiscono
TRANSCRIPT_UNAVAILABLE, il fallback è lo speech-to-text — vedi Whisper vs sottotitoli di YouTube per capire quando vale il costo. E se stavi per provare yt-dlp al suo posto, sappi che incontra lo stesso blocco IP dagli indirizzi datacenter.
La tua chiave personale (separata dalla quota demo condivisa) richiede un accesso Google su youtube2text.org/app/keys — il piano gratuito è di 5 video al mese, i piani a pagamento vanno da 5,99 $/mese per 50 video fino a 19,99 $ illimitato. Niente numero di telefono, niente carta per il piano gratuito.