Netflix Leaving: quali titoli stanno per essere rimossi da Netflix?

| |

Ci ho preso evidentemente gusto con il progetto del backup della New Music Friday, l’ho rifatto con Netflix. Ho appreso in maniera casuale (e “troppo tardi“) dell’abbandono degli ultimi titoli Marvel (passati poi su Disney+, come prevedibile) quando mancava all’appello ancora The Punisher (spoiler: manca ancora), e ho deciso che bisognava fare qualcosa in merito al conoscere con quanto più anticipo possibile i piani di Netflix e dei titoli in catalogo, magari riservandomi la possibilità di un messaggio che potesse dire “ehi pirla, lo sai che questo titolo che devi ancora vedere sta per uscire dai radar?“.
La domanda è quindi “semplice“: è possibile conoscere quale titoli abbandoneranno prossimamente la piattaforma? La risposta è sì, ci sono come sempre dei ma, è qualcosa che tratteremo di seguito.

Netflix: proteggere il singolo profilo con PIN

Netflix Leaving: chi abbandona il catalogo?

La questione API di Netflix è un attimo più complicata rispetto a Spotify. Netflix ha deciso di rimuovere l’accesso pubblico alle sue API diverso tempo fa, l’ho appreso dopo qualche ricerca online, la stessa ricerca che poi mi ha portato a conoscere unogs.com (unofficial Netflix online Global Search), con le sue API messe a disposizione per chiunque lo voglia (rapidapi.com/unogs/api/unogsng).
È da qui che sono partito per imbastire quello che è diventato il repository Netflix Leaving che puoi trovare nel mio spazio GitHub all’indirizzo github.com/gioxx/netflix-leaving.

Di cosa si tratta

uNoGS mette a disposizione – tra le varie cose – una serie di informazioni relative ai cataloghi Netflix di tutto il mondo, con quel fondamentale campo che identifica la data d’uscita dalla porta di servizio, ovvero il momento in cui lo specifico titolo abbandonerà (temporaneamente o definitivamente) l’enorme libreria del gigante dello streaming californiano.
È stato necessario (e lo è tutt’ora se deciderai di cimentarti anche tu nell’opera) registrare un account su rapidapi.com; associarsi e utilizzare poi uNoGS non ti costerà alcunché a patto di tenere a bada le richieste e non superare le 100 interrogazioni del database al giorno, si pagherà poi 0,1$ per ogni successiva richiesta nell’arco delle 24 ore, si tornerà a poterne fare altre 100 gratuitamente già dal giorno dopo.

Considera che io, allo stato attuale, interrogo il database una volta al giorno. Supero la singola query (ma resto sotto le 100 senza problemi) solo quando metto mano allo script e inizio a lanciare interrogazioni per capire quali altri dettagli posso portarmi fuori, che potrebbero tornarmi utili, in pratica tutto quello che è “ricerca e sviluppo“.

Info

Quello che vado a spiegare da qui in poi ti permetterà di usare e salvare il tutto sul tuo account GitHub, ricostruisci “a casa tua” quello che ho fatto io, senza passare dal mio account. Se non sei interessato, salta tutto questo paragrafo e portati a “Per tutti gli altri“.

Al solito per chi è già un pelo preparato sull’argomento: l’invito è quello di dare un’occhiata al file README del repository GitHub. Qui è dove te lo spiego in italiano, dato che il file originale è in inglese e ho quindi preferito mantenerlo tale per raggiungere potenzialmente più interessati all’argomento nella comunità internazionale di GitHub.

Per dialogare con le API, i file Python (e quindi i Secrets di GitHub) hanno sostanzialmente bisogno di conoscere la XRAPIDAPIKEY e l’host a cui fare riferimento (io lo tengo pure lui nelle variabili d’ambiente e nei Secrets, ma non c’è nulla da nascondere in realtà). La query per ottenere i titoli in scadenza per il catalogo italiano è davvero molto semplice:

def get_titles():
    url = "https://%s/aaapi.cgi" % XRAPIDAPIHOST
    headers = {
       "x-rapidapi-host": "%s" % XRAPIDAPIHOST,
       "x-rapidapi-key": "%s" % XRAPIDAPIKEY
    }
    querystring = {
        "q":"get:exp:IT",
        "t":"ns",
        "st":"adv",
        "p":"1"
    }
    response = requests.request("GET", url, headers=headers, params=querystring)
    return response.json()

La risposta arriverà sotto forma di JSON e a quel punto sarà assai semplice memorizzare l’output e usarlo ovunque si voglia. Nei campi del JSON sono disponibili ID del video (all’interno del catalogo Netflix, campo univoco e certamente fondamentale), titolo, l’immagine di copertina, la sinossi, il voto medio, il tipo di VOD (serie televisiva o film), quando è stato rilasciato, quanto tempo dura, il codice per identificare il titolo su IMDB e – chiaramente – la scadenza, quindi la data di scadenza e uscita dal catalogo del servizio.

Se vuoi dare un’occhiata a un file JSON salvato grazie all’utilizzo delle API di uNoGS puoi puntare il browser all’indirizzo raw.githubusercontent.com/gioxx/netflix-leaving/main/2022/20220223.json (si tratta del primo file salvato dal mio script, quando ha cominciato a funzionare il tutto e lavorare grazie all’utilizzo di GitHub Actions).

Ogni giorno, un’Action si occupa di scaricare la lista aggiornata dei titoli in uscita dal catalogo e salvarne una copia all’interno di una cartella che riporta l’anno corrente. Il file JSON verrà nominato con la nomenclatura YYYYMMDD.json. A quel punto, una funzione differente penserà a costruire una pagina web che tu potrai accedere grazie a GitHub Pages all’indirizzo gioxx.github.io/netflix-leaving, accodando l’anno e poi il mese e il giorno che ti interessa, concludendo con l’estensione .html (ti spiego meglio tra brevissimo).

def makewebpage(json):
    pre = post = ""
    with open(os.path.join("include","body-pre")) as fp:
        pre = fp.read()
    with open(os.path.join("include","body-post")) as fp:
        post = fp.read()
    response = pre + "	$.getJSON('" + json + "', function(data) {" + "\n" + post
    return response
jsonfile = os.path.join(year+month+day+".json")
        html = makewebpage(jsonfile)
        with open (os.path.join(year,month+day+".html"), 'w') as fp:
            fp.write(html)

Per capirci: volendo dare un’occhiata in maniera pulita alla lista di cui ti parlavo prima (quella del 23 febbraio 2022), dovrai puntare il browser all’indirizzo gioxx.github.io/netflix-leaving/2022/0223.html.

Nella pagina HTML le immagini vengono direttamente caricate e mostrate dalla CDN di Netflix, ho notato infatti che – nonostante la scadenza titoli – queste continuano a rimanere online, presumibilmente nel caso in cui quel titolo in futuro tornasse disponibile su Netflix, ho per questo commentato il richiamo alla funzione che si occupa di scaricare le copertine dei VOD, che resta comunque disponibile nel codice Python nel caso in cui, in futuro, dovesse nascere la necessità di salvare copia di quelle immagini:

def downloadposter(posterurl, folder, filename):
    fullpath = os.path.join(folder,filename)
    response = urllib.request.urlretrieve(posterurl, fullpath)
    return response
# Download Posters
        posterfolder = os.path.join(year,month)
        for item in leavingtitles['ITEMS']:
            poster = "%s.jpg" % item['netflixid']
            print("Downloading", poster)
            downloadposter(item['image'],posterfolder,poster)

Incrociare i dati con la lista personale

Quanto fatto fino a ora è ottimo per poter mettere a disposizione di chiunque una lista di titoli aggiornata quotidianamente, che possa mettere bene in evidenza cosa sta per abbandonare il catalogo Netflix. Io però avevo bisogno di incrociare questi dati con i miei, con la mia lista titoli personali, affinché si potesse capire se qualcosa di mio interesse (ancora da guardare) ne facesse parte, permettendomi di guardare il VOD prima della scadenza della licenza.

Per farlo ho scaricato dapprima la lista dei miei contenuti preferiti (questo componente aggiuntivo disponibile per Firefox o Chrome ti sarà d’aiuto: github.com/daltonmenezes/netflix-list-exporter), quindi l’ho data in pasto a un ulteriore script Python che si occupa di confrontare i titoli contenuti nel file con quelli presenti su IMDB, tenendo traccia degli ID e impacchettando il tutto in un file JSON facilmente riutilizzabile. Per farlo ho utilizzato la libreria Cinemagoer:

exportlist_txt = "mylist-export.txt"
exportlist_jsn = "mylist-export.json"

def imdb_get(movietitle):
    ia = Cinemagoer()
    moviesearch = ia.search_movie(movietitle)
    movieid = moviesearch[0].movieID
    return movieid

netflixlist = open(exportlist_txt, 'r')
titles = netflixlist.readlines()
count = 0
json_list = []
for title in titles:
    count += 1
    imdbinfo = "tt" + imdb_get(title.strip())
    print("Title {}: {} ({})".format(count, title.strip(), imdbinfo))
    json_add = {
        "title": title.strip(),
        "imdbid": imdbinfo
    }
    json_list.append(json_add)

if count > 0:
    with open(exportlist_jsn, "w") as outfile:
        json.dump(json_list, outfile)

Così facendo, basandomi sugli ID di IMDB, è più facile fare il confronto tra la mia lista e quella quotidianamente messa a disposizione dalle API di uNoGS, un lavoro che ho destinato a un ulteriore file Python. Bisognerà dargli in pasto i due file JSON da confrontare e – per ogni titolo in scadenza – confrontarlo con la lista personale dei VOD ancora da guardare, andando a generare un ulteriore file JSON in caso di risposta affermativa (cioè almeno un titolo da guardare e in uscita dal catalogo di Netflix):

for vod in ntflxList["ITEMS"]:
    for check in mylist:
        if(vod["imdbid"] == check["imdbid"]):
            print("Found {} (Netflix ID {})".format(vod["title"], vod["netflixid"]))
            json_list.append(vod)
            count += 1

if count > 0:
    with open(exportlist_leaving, "w") as outfile:
        json.dump(json_list, outfile)
    html = make_webpage(exportlist_leaving)
    with open(exportlist_html, 'w') as fp:
        fp.write(html)
else:
    print("No titles from your list are leaving Netflix")
    try:
        env_file = os.getenv('GITHUB_ENV')
        with open(env_file, "a") as ghenv:
            ghenv.write("Expiring=None")
    except:
        print("An exception occurred, probably executed not on GitHub.")

Un’azione GitHub provvederà a eseguire questo controllo e – nel caso ci fossero titoli da guardare in scadenza – mi avviserà via Twitter (è quindi stato necessario creare un’applicazione ad-hoc su Twitter Developers e salvare in GitHub Secrets CONSUMER_API_KEY, CONSUMER_API_SECRET_KEY, ACCESS_TOKENe ACCESS_TOKEN_SECRET), chiamando direttamente in causa il mio utente, pubblicamente (anche se il feed del bot è privato e posso leggerlo solo io, almeno per ora).

Per tutti gli altri

Netflix Leaving: quali titoli stanno per essere rimossi da Netflix? 1

Per i meno avvezzi, la faccio semplice: ogni giorno un processo automatizzato creerà una pagina web contenente una lista sempre aggiornata di titoli in scadenza su Netflix, che usciranno quindi dal catalogo nei giorni / mesi successivi. Puoi controllare questa lista quando vuoi, è in funzione dal 23 febbraio 2022 e ogni giorno viene creato un file sempre nuovo. Per poterlo fare ti basterà puntare il browser all’indirizzo gioxx.github.io/netflix-leaving. Vedrai certamente la pagina principale del Repository.

Vai a modificare l’URL digitato, aggiungi uno slash /, scrivi l’anno corrente (o uno precedente / futuro, attualmente non disponibile), un altro slash / e poi il mese (due cifre) e il giorno che ti interessa (altre due cifre). Concludi con .html in coda. Ti faccio un esempio più comodo da comprendere. Ammesso tu voglia consultare la lista titoli in scadenza pubblicata il giorno 23 febbraio 2022 dovrai andare all’indirizzo gioxx.github.io/netflix-leaving/2022/0223.html.

Cambiando quel 0223.html in 0501.html potresti vedere la lista dei titoli in scadenza pubblicata il primo di maggio del 2022. Nel 2023 (ammesso il progetto sia ancora in piedi, ma non vedo perché no) chiaramente l’URL dovrà contenere /2023 prima di poter dichiarare il file del mese e giorno interessato, per esempio gioxx.github.io/netflix-leaving/2023/0101.html porterà alla lista che verrà pubblicata il primo gennaio del prossimo anno :-)

In conclusione

Mi pare di aver detto tutto.

Ho cercato di inserire nel repository GitHub (e in parte anche in questo articolo) tutto quello che c’è da sapere per poter replicare il tutto da zero, l’intenzione è però quella di rendere tutto più semplice, mettendo direttamente io a disposizione le varie informazioni raccolte nel corso del tempo.

Il codice è migliorabile? Sicuramente, ne ho piena consapevolezza. Ho dubbi sul funzionamento del confronto tra lista personale e ID IMDB (ho già avuto un paio di casi di omonimie problematiche), ho dubbi sulla pagina web che viene pubblicata, sono certo si possa ottimizzare il codice e fare di più in meno righe (magari), sto muovendo i miei primi passi in Python e tra qualche tempo probabilmente guarderò schifato questo mio codice sorgente ripensando a quanto fossi “giovane e ingenuo“, eppure tutto allo stato attuale funziona e sono contento a sufficienza del risultato finale.

Se hai dubbi o se vuoi suggerirmi un’alternativa, darmi il tuo punto di vista, contribuire all’idea (anche se in quel caso la migliore cosa è passare tramite GitHub), l’area commenti è giusto un colpo di scroll più in basso, usala :-)

#StaySafe


Immagine di copertina: besthqwallpapers.com

Correzioni, suggerimenti? Lascia un commento nell'apposita area qui di seguito o contattami privatamente.
Ti è piaciuto l'articolo? Offrimi un caffè! ☕ :-)

L'articolo potrebbe non essere aggiornato

Questo post è stato scritto più di 5 mesi fa, potrebbe non essere aggiornato. Per qualsiasi dubbio ti invito a lasciare un commento per chiedere ulteriori informazioni! :-)

Condividi l'articolo con i tuoi contatti:
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Commenti
Inline Feedbacks
View all comments