Buscando contenido específico en Netflix con Python

Luis Ch enero 02, 2025 #api #python #proyectos

Intro

Durante estas vacaciones quise aprovechar el tiempo libre para completar al menos una serie de TV. Evitando series inconclusas, ya que no quiero volver a engancharme a series que terminan siendo canceladas. En esta ocasión buscaremos en la plataforma de Netflix, la cual como bien sabemos tiene la fama de cancelar muchas de las series que produce.

Solución

Vamos a filtrar el contenido para encontrar series de TV que tengan como estatus Ended (finalizada). En el sitio web de TMDB podemos ver informacion completa sobre series y películas. Nos permite filtrar el contenido por plataformas y hasta por regiones, pero lamentablemente no permite filtrar por estatus. Sin embargo, desde su API, podemos acceder a una gran cantidad de filtros y entre ellos, podemos filtrar por estatus.

TMDB API

Descubrir Series de TV

Iniciamos sesión en el portal de desarrolladores de TMDB, y vamos a la sección Descubrir series. En dicha sección podremos ver un listado de los endpoints[1] disponibles, la documentación de estos y una pequeña interfaz para probar la API.

En esta última sección podremos usar directamente la API, y también nos muestra el código para realizar la consulta en distintos lenguajes de programación. Copia la API key que puedes ver en al campo "Credentials" o en el código de ejemplo.

En la documentación del endpoint encontraremos una larga lista de filtros, pero sólo usaremos algunos de ellos.

Los valores mencionados actualmente fueron extraidos del contenido detallado, de una serie original de Netflix, obtenidos desde la API de TMDB.

En el caso del estatus para series de TV no se especifica en la documentación, pero sí hay una clara referencia en el foro de TMDB.

Preparamos el código

Comenzamos creando la estructura base del proyecto. Desde Linux lo hacemos con los siguientes comandos.

# Creamos un directorio para el proyecto y entramos
mkdir project1
cd project1

# Creamos el entorno virtual de Python y lo activamos
python3 -m venv venv
source ./venv/bin/activate

# Actualizamos pip e instalamos los requerimientos del proyecto
pip install --upgrade pip
pip install requests rich python-dotenv

# Creamos los archivos de python que luego escribiremos
touch models.py main.py

Ahora creamos un módulo de python con los modelos de los objetos que obtendremos de la API, basados en los resultados de la función discover.

models.py:

"""Models"""

from pydantic import BaseModel, Field


class MediaContent(BaseModel):
    """Media Content class"""

    id_: int = Field(alias="id")
    vote_average: float
    

class TVshow(MediaContent):
    """TV show content"""

    original_name: str
    name: str
    first_air_date: str


class TmdbApiSearchResponse(BaseModel):
    """Response from TMDB API"""
    page: int
    results: list[TVshow | Movie]
    total_pages: int
    total_results: int

Ahora creamos el módulo principal (discover.py), donde importaremos el modulo models.py y escribiremos toda la funcionalidad. Es necesario crear un archivo llamado .env dentro de nuestro proyecto, donde vamos a almacenar nuestra API key como una variable de entorno.

.env:

TMDB_API_KEY= coloca aqui tu clave secreta

Importamos todos los módulos necesarios, declaramos las constantes y cargamos la variable de entorno con nuestra clave secreta.

discover.py:

"""Module to discover content in TMDB"""

import os

import requests
from dotenv import load_dotenv
from rich.console import Console
from rich.table import Table
from typer import Typer

from models import TmdbApiSearchResponse

load_dotenv()
TMDB_API_KEY = os.environ["TMDB_API_KEY"]

app = Typer()

# CONSTANTS
COUNTRY: str = "VE"
NETFLIX_ID: int = 8
NETFLIX_NETWORK_ID: int = 213
STATUS_ENDED: int = 3
CONTENT_URL: str = "https://themoviedb.org/tv/"

...

Ahora, en el mismo módulo vamos a crear la función "obtener series".

discover.py:

...

def get_ended_tv_shows(netflix_originals: bool = False):
    """Funcion que retorna los resultados de la API de TMDB."""

    api_discover = "https://api.themoviedb.org/3/discover/tv"

    headers = {
        "accept": "application/json", 
        "Authorization": f"Bearer {TMDB_API_KEY}"
    }
    params = {
        "include_adult": True,
        "watch_region": COUNTRY,
        "language": "en-US",
        "with_status": STATUS_ENDED,
        "with_watch_providers": NETFLIX_ID,
        "with_original_language": "en",
    }
    if netflix_originals:
        params["with_networks"] = NETFLIX_NETWORK_ID

    response = requests.get(
        url=api_discover, headers=headers, params=params, timeout=30
    )
    return response.json()

...

Y por último, vamos a modelar esos datos y presentarlos en una tabla.

discover.py:

...

@app.command()
def discover_netflix_series(original: bool = False):
    """Función principal"""
    response = TmdbApiSearchResponse(
        **get_ended_tv_shows(netflix_originals=original)
    )
    title = "TOP series completas en Netflix"
    if originals:
        title += " (originales)"
    table = Table(title=title, show_header=True, header_style="bold")
    table.add_column("Nombre", style="italic")
    table.add_column("Puntuación", justify="center")
    table.add_column("Enlace")

    for item in response.results:
        table.add_row(
            item.name,
            f"{item.vote_average:.1f}",
            CONTENT_URL + str(item.id_),
        )

    console = Console()
    console.print(table)


if __name__ == "__main__":
    app()

Resultado

Estos son los principales resultados de TMDB, de series completas en Netflix disponibles para Venezuela.

$ python discover.py 
                        TOP series completas en Netflix                          
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
 Nombre                         ┃ Puntuación ┃ Enlace                          ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
 The Blacklist                  │    7.6     │ https://themoviedb.org/tv/46952 │
 Brooklyn Nine-Nine             │    8.2     │ https://themoviedb.org/tv/48891 │
 The Flash                      │    7.8     │ https://themoviedb.org/tv/60735 │
 Prison Break                   │    8.1     │ https://themoviedb.org/tv/2288  │
 Lucifer                        │    8.5     │ https://themoviedb.org/tv/63174 │
 Dexter                         │    8.2     │ https://themoviedb.org/tv/1405  │
 House                          │    8.6     │ https://themoviedb.org/tv/1408  │
 Breaking Bad                   │    8.9     │ https://themoviedb.org/tv/1396  │
 Arrested Development           │    8.0     │ https://themoviedb.org/tv/4589  │
 Suits                          │    8.2     │ https://themoviedb.org/tv/37680 │
 Vikings                        │    8.1     │ https://themoviedb.org/tv/44217 │
 Lost                           │    7.9     │ https://themoviedb.org/tv/4607  │
 Star Trek: The Next Generation │    8.4     │ https://themoviedb.org/tv/655   │
 Peaky Blinders                 │    8.5     │ https://themoviedb.org/tv/60574 │
 The Crown                      │    8.2     │ https://themoviedb.org/tv/65494 │
 Better Call Saul               │    8.7     │ https://themoviedb.org/tv/60059 │
 Arcane                         │    8.8     │ https://themoviedb.org/tv/94605 │
 Billions                       │    7.7     │ https://themoviedb.org/tv/62852 │
 Riverdale                      │    8.4     │ https://themoviedb.org/tv/69050 │
 The Walking Dead               │    8.1     │ https://themoviedb.org/tv/1402  │
└────────────────────────────────┴────────────┴─────────────────────────────────┘

Y acá filtramos para obtener series originales de Netflix.

$ python discover.py --original
                    TOP series completas originales de Netflix                           
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
 Nombre                         ┃ Puntuación ┃ Enlace                           ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
 Lucifer                        │    8.5     │ https://themoviedb.org/tv/63174  │
 Arrested Development           │    8.0     │ https://themoviedb.org/tv/4589   │
 The Crown                      │    8.2     │ https://themoviedb.org/tv/65494  │
 Arcane                         │    8.8     │ https://themoviedb.org/tv/94605  │
 Narcos: Mexico                 │    7.9     │ https://themoviedb.org/tv/80968  │
 The Umbrella Academy           │    8.5     │ https://themoviedb.org/tv/75006  │
 Sex Education                  │    8.2     │ https://themoviedb.org/tv/81356  │
 The Last Kingdom               │    8.3     │ https://themoviedb.org/tv/63333  │
 BoJack Horseman                │    8.6     │ https://themoviedb.org/tv/61222  │
 Lost in Space                  │    7.5     │ https://themoviedb.org/tv/75758  │
 Ozark                          │    8.2     │ https://themoviedb.org/tv/69740  │
 No Good Deed                   │    5.6     │ https://themoviedb.org/tv/241112 │
 Vikings: Valhalla              │    7.7     │ https://themoviedb.org/tv/116135 │
 Chilling Adventures of Sabrina │    8.2     │ https://themoviedb.org/tv/79242  │
 Inspector Gadget               │    6.0     │ https://themoviedb.org/tv/62508  │
 Grace and Frankie              │    7.7     │ https://themoviedb.org/tv/62320  │
 Unbreakable Kimmy Schmidt      │    7.2     │ https://themoviedb.org/tv/61671  │
 Dragons: Race to the Edge      │    8.3     │ https://themoviedb.org/tv/78173  │
 Orange Is the New Black        │    7.7     │ https://themoviedb.org/tv/1424   │
 The Madness                    │    6.5     │ https://themoviedb.org/tv/220056 │
└────────────────────────────────┴────────────┴──────────────────────────────────┘  

Conclusiones

De esta forma he podido encontrar series completas en la plataforma de Netflix. Además, ajustando los filtros podemos obtener diferentes resultados por ejemplo, buscar contenido en multiples plataformas o en alguna otra plataforma específica como Apple TV.

Esta versión del código la escribí hace tiempo, actualmente estoy creando una versión con interfaz web (Web UI), para facilitar el acceso a todo tipo de usuarios, ya que esta version funciona desde la línea de comandos (CLI).

Además, en este caso obtenemos los primeros 20 resultados, luego implementaremos paginación.

Y por supuesto, puedes acceder al código completo en este repositorio.



  1. Definición de endpoint, según Cloudflare