jsonscraper
Mercados

Cómo evaluar la calidad de los leads de TikTok a partir de vídeos públicos: un flujo paso a paso en Python

Recopila una muestra mediante palabras clave, detecta posibles señales de demanda y entrega datos verificables a un analista o a un clasificador de IA

Política editorial Informar de un error

El equipo de ventas recibe la misma pregunta por distintos canales: ¿qué problemas intentan resolver ya los clientes potenciales? Buscar manualmente en TikTok produce un conjunto disperso de vídeos, pero es difícil repetir la búsqueda una semana después, comparar resultados y explicar por qué un vídeo concreto apareció en el informe. Para una investigación pequeña, se pueden convertir los resultados públicos de varias consultas específicas en un flujo de datos reproducible: guardar la respuesta original, extraer los campos del vídeo y del autor, eliminar duplicados y evaluar por separado las señales explícitas de intención de compra o de elección de un producto.

Artículo: Cómo evaluar la calidad de los leads de TikTok a partir de vídeos públicos: un flujo paso a paso en Python
Resumen: Una guía práctica para profesionales del marketing y desarrolladores: buscar vídeos públicos de TikTok con consultas de la audiencia mediante TikTok Scraper API, guardar las respuestas originales, eliminar duplicados y ordenarlos según reglas explícitas. Incluye un script de Python que procesa dos estructuras de respuesta y transmite la clave de API de forma segura.
Función de la imagen: portada: la idea central
Sección: 
Tema visual: primer plano editorial
© jsonscraper · Ilustración generada por IA

A continuación se muestra un flujo funcional en Python con TikTok Scraper API de jsonscraper. Puede servir, por ejemplo, a un servicio de edición de vídeo que quiera conocer cómo describen los creadores las dificultades con los subtítulos, las plantillas y la exportación. El script recopila los resultados de búsqueda devueltos, y después un analista revisa la clasificación y decide qué expresiones conviene usar en la investigación de audiencia. Es una forma de organizar el seguimiento de contenido público, no un recuento automático de todos los usuarios con intención de compra.

El problema: hay consultas de la audiencia, pero cuesta repetir la investigación

La investigación manual pierde fácilmente el contexto. Un empleado busca «cómo añadir subtítulos», otro «subtítulos automáticos para Reels» y un tercero solo guarda los vídeos que le gustan. La tabla final mezcla consultas, fechas, métricas y criterios de selección distintos. Cuando un responsable pide repetir el análisis o comparar dos semanas, hay que reconstruir tanto los resultados como el proceso de búsqueda.

Es más útil definir de antemano la unidad de observación: un vídeo encontrado, con el texto de su descripción, identificador, enlace, autor y métricas públicas disponibles. Para cada vídeo se guardan la consulta original y la hora de recopilación. Así se pueden responder por separado preguntas como qué expresiones aparecen, qué problemas se mencionan, qué vídeos recibieron más reacciones públicas y qué cambió entre las capturas guardadas.

Como ejemplo, pensemos en una empresa que desarrolla una herramienta para crear subtítulos y vídeos cortos. Le interesa encontrar vídeos públicos en los que los creadores hablen directamente de la transcripción manual, los errores del reconocimiento de voz, la sincronización de los subtítulos o la preparación de contenido para varias plataformas. No se debe etiquetar al autor como «lead» o «comprador» por un solo vídeo: el investigador puede ordenar el contenido según señales observables y después comprobar las conclusiones manualmente.

Esquema de la solución: búsqueda, registro, limpieza y evaluación

El flujo consta de cuatro etapas. Primero, el equipo crea un pequeño diccionario de consultas, cada una asociada a una tarea concreta de la audiencia. A continuación, el script solicita una búsqueda de vídeos y guarda la respuesta JSON completa. La tercera etapa normaliza distintas estructuras de respuesta en una fila única por vídeo y elimina duplicados por identificador. Por último, unas reglas o un clasificador de IA independiente asignan una prioridad para la revisión manual y conservan el motivo de la evaluación.

Separar estas etapas es importante para la reproducibilidad. La respuesta sin procesar ayuda a investigar cambios en los campos o errores de normalización. La tabla normalizada facilita los filtros y las visualizaciones. Una tabla de puntuaciones independiente permite cambiar las reglas sin volver a consultar la API, siempre que los datos guardados sean adecuados para ese procesamiento y respeten el plazo de conservación del equipo.

Como consultas iniciales se pueden usar «errores de subtítulos automáticos», «cómo añadir subtítulos rápidamente» y «edición de vídeos cortos para empresas». Son solo ejemplos de un diccionario: las expresiones deben adaptarse al idioma de la audiencia y al producto. Conviene guardar las consultas junto con los resultados, porque cada término genera una muestra distinta.

Qué ofrece TikTok Scraper API

La documentación publicada de jsonscraper para la búsqueda de vídeos indica la ruta GET /searchVideo en la dirección base https://tiktok.evelode.com. El parámetro obligatorio es keyword; entre los parámetros adicionales documentados están count, cursor, region, date_posted, sort_by y cache_timeout. Por ejemplo, sort_by admite los valores documentados most-liked, relevance y date-posted, mientras que date_posted acepta valores como this-week o all-time. La guía de endpoints de TikTok API describe la lista exacta de parámetros y el propósito de la ruta.

La clave se transmite como parámetro de consulta license_key. En el ejemplo de abajo se lee desde la variable de entorno JSONSCRAPER_TIKTOK_LICENSE_KEY, para no guardar el secreto en el código ni imprimirlo en el registro. Para la autenticación y la selección de parámetros, consulta las condiciones vigentes de tu acceso; la página de TikTok Scraper API describe el producto y ofrece enlaces a una demostración y a la documentación.

La respuesta de búsqueda debe procesarse atendiendo a su estructura, sin dar por hecho que existe un único array. En el ejemplo de API verificado, la respuesta incluía un estado de nivel superior y un objeto tiktok; los vídeos pueden aparecer en tiktok.aweme_list, y en los resultados de búsqueda también se encuentra tiktok.search_item_list[].aweme_info. Comprueba ambos formatos. Si están presentes, los objetos encontrados pueden incluir el identificador del vídeo, la descripción, el enlace, la hora de publicación, información del autor y estadísticas como visualizaciones, «Me gusta», comentarios y compartidos. Las métricas y los campos deben considerarse opcionales: el código no debe inventar ceros cuando falta un valor.

La paginación de búsqueda utiliza cursor. Si el script continúa con los resultados, debe transmitir el valor recibido como un token opaco para la siguiente solicitud, en lugar de calcularlo por su cuenta. Para un prototipo inicial, es razonable limitar la recopilación a una página por consulta: facilita la comprobación y mantiene la carga predecible. Después se puede añadir la paginación con un límite de páginas y protección frente a cursores repetidos.

Preparación del entorno

El ejemplo utiliza Python 3.8 o posterior y la biblioteca estándar. Define la clave en el entorno, por ejemplo, en el shell de macOS o Linux:

export JSONSCRAPER_TIKTOK_LICENSE_KEY="tu_clave"
python tiktok_demand.py

En Windows PowerShell puedes definir la variable así:

$env:JSONSCRAPER_TIKTOK_LICENSE_KEY="tu_clave"
python .\tiktok_demand.py

El script realiza una solicitud independiente por cada palabra clave. Comprueba los errores HTTP, la respuesta JSON y el estado externo; después extrae objetos de las dos estructuras de array confirmadas. Las respuestas originales se escriben línea por línea en un archivo JSONL: cada registro contiene la consulta, la hora de observación y la respuesta original. La segunda parte genera un CSV con campos unificados. El código no contiene la clave y el secreto no se imprime.

Ejemplo: recopilar y normalizar resultados de búsqueda

import csv
import json
import os
import time
from datetime import datetime, timezone
from pathlib import Path
from urllib.error import HTTPError, URLError
from urllib.parse import urlencode
from urllib.request import Request, urlopen

BASE_URL = "https://tiktok.evelode.com/searchVideo"
QUERIES = [
    "errores de subtítulos automáticos",
    "cómo añadir subtítulos rápidamente",
    "edición de vídeos cortos para empresas",
]


def extract_videos(payload):
    """Admite las dos estructuras de respuesta de búsqueda observadas."""
    tiktok = payload.get("tiktok") or {}
    videos = []

    aweme_list = tiktok.get("aweme_list") or []
    if isinstance(aweme_list, list):
        videos.extend(item for item in aweme_list if isinstance(item, dict))

    search_items = tiktok.get("search_item_list") or []
    if isinstance(search_items, list):
        for item in search_items:
            if not isinstance(item, dict):
                continue
            video = item.get("aweme_info")
            if isinstance(video, dict):
                videos.append(video)

    return videos


def fetch(query, license_key):
    params = {
        "keyword": query,
        "count": 20,
        "sort_by": "relevance",
        "date_posted": "this-month",
        "region": "US",
        "license_key": license_key,
    }
    url = BASE_URL + "?" + urlencode(params)
    request = Request(url, headers={"Accept": "application/json"})

    try:
        with urlopen(request, timeout=45) as response:
            payload = json.loads(response.read().decode("utf-8"))
    except HTTPError as exc:
        raise RuntimeError("La API devolvió el estado HTTP {}".format(exc.code)) from exc
    except (URLError, TimeoutError, json.JSONDecodeError) as exc:
        raise RuntimeError("No se pudo completar o interpretar la solicitud a la API") from exc

    if payload.get("status") != "ok":
        raise RuntimeError("El estado de la respuesta de la API no fue ok")
    return payload


def metric(statistics, key):
    value = statistics.get(key)
    return value if isinstance(value, (int, float)) else ""


def main():
    license_key = os.environ.get("JSONSCRAPER_TIKTOK_LICENSE_KEY")
    if not license_key:
        raise SystemExit("Define JSONSCRAPER_TIKTOK_LICENSE_KEY en el entorno")

    raw_path = Path("tiktok_raw.jsonl")
    csv_path = Path("tiktok_videos.csv")
    seen_ids = set()
    rows = []

    with raw_path.open("a", encoding="utf-8") as raw_file:
        for query in QUERIES:
            observed_at = datetime.now(timezone.utc).isoformat()
            payload = fetch(query, license_key)
            raw_file.write(json.dumps({
                "query": query,
                "observed_at": observed_at,
                "response": payload,
            }, ensure_ascii=False) + "\n")

            for video in extract_videos(payload):
                video_id = video.get("aweme_id")
                if not video_id or video_id in seen_ids:
                    continue
                seen_ids.add(video_id)

                author = video.get("author") or {}
                stats = video.get("statistics") or {}
                rows.append({
                    "query": query,
                    "observed_at": observed_at,
                    "video_id": video_id,
                    "created_at": video.get("create_time", ""),
                    "description": video.get("desc", ""),
                    "share_url": video.get("share_url", ""),
                    "author_username": author.get("unique_id", ""),
                    "author_nickname": author.get("nickname", ""),
                    "views": metric(stats, "play_count"),
                    "likes": metric(stats, "digg_count"),
                    "comments": metric(stats, "comment_count"),
                    "shares": metric(stats, "share_count"),
                })
            time.sleep(1)

    columns = [
        "query", "observed_at", "video_id", "created_at", "description",
        "share_url", "author_username", "author_nickname", "views",
        "likes", "comments", "shares",
    ]
    with csv_path.open("w", newline="", encoding="utf-8") as csv_file:
        writer = csv.DictWriter(csv_file, fieldnames=columns)
        writer.writeheader()
        writer.writerows(rows)

    print("Se guardaron {} vídeos únicos devueltos en {}".format(len(rows), csv_path))


if __name__ == "__main__":
    main()

El valor de count se establece aquí como el tamaño de muestra solicitado por consulta. El script no da por hecho que la API tenga que devolver exactamente ese número de elementos: la cantidad real de filas depende de la respuesta. La pausa entre solicitudes es una medida sencilla para regular el ritmo de ejecución, no una afirmación sobre los límites o requisitos del servicio. Para una programación de producción, añade reintentos limitados, supervisión de errores y reglas sobre la frecuencia permitida de solicitudes, de acuerdo con las condiciones de tu plan.

Cómo interpretar la tabla obtenida

En el CSV, cada fila representa un vídeo único devuelto y encontrado mediante una de las consultas. El campo query indica el origen del registro, observed_at señala la hora de la captura y video_id sirve como clave de deduplicación. La descripción y el enlace permiten al analista comprobar el contexto, mientras que los contadores públicos ayudan a evaluar la respuesta en el momento de la recopilación. Para comparar a largo plazo, usa observaciones independientes: no sobrescribas el historial de métricas si quieres ver cómo cambian.

Los contadores de visualizaciones, «Me gusta», comentarios y compartidos son una captura de las estadísticas públicas devueltas por la API en el momento de la solicitud. Pueden faltar en algunos objetos, por lo que un valor vacío en el CSV indica que la respuesta no incluía un campo numérico. No es lo mismo que cero y debe tratarse por separado al calcular agregados. Además, los resultados encontrados representan la muestra obtenida con términos, región, filtro temporal y parámetros específicos. Describen esos vídeos concretos, no todo el contenido ni toda la audiencia de la plataforma.

Para una primera evaluación de la posible relevancia, se puede crear una tabla transparente de reglas: coincidencias con expresiones sobre problemas, menciones de herramientas utilizadas, preguntas sobre precios o comparaciones, y presencia de un caso de uso concreto. Es mejor guardar señales independientes y una explicación de la puntuación que registrar solo una cifra opaca. Por ejemplo, un vídeo con una pregunta sobre la precisión de la transcripción automática se puede marcar como «revisar: se habla de calidad», y uno con consejos generales sobre contenido como «baja relevancia temática».

Integrar IA sin convertirla en juez

Una vez reunida una muestra, un modelo puede ayudar a etiquetar las descripciones según un esquema predefinido: problema, herramienta mencionada, tono de la pregunta y presencia de una señal de elección de producto. Proporciona al modelo solo los campos necesarios —por ejemplo, el texto de la descripción y el identificador del registro— y pídele que devuelva un JSON fijo con etiquetas y una justificación breve. Guarda la versión de las instrucciones, el modelo y el resultado junto a la fila original, para poder repetir el etiquetado o comprobarlo manualmente por muestreo.

Una instrucción útil para el clasificador debe limitar las conclusiones a señales observables. Pídele que determine si el texto contiene un problema explícito con los subtítulos, una solicitud de recomendación de herramienta o un comentario sobre un flujo de trabajo. Si los datos son insuficientes, incluye la categoría «contexto insuficiente». El modelo no debe inferir la identidad del autor, su intención de compra ni sus características demográficas a partir de un único vídeo público. El resultado es una lista de temas para analizar, no una lista de personas a las que contactar automáticamente.

Para evaluar la calidad del etiquetado, toma una submuestra aleatoria y marca manualmente las mismas categorías. Compara la concordancia de cada etiqueta y examina los errores: por ejemplo, el modelo puede confundir el sarcasmo con una queja o un consejo educativo con una experiencia personal. Corregir el diccionario de consultas y las instrucciones suele ser más útil que complicar el modelo desde el principio. Para los informes, conserva los textos originales y los enlaces de acuerdo con la política de conservación y acceso adoptada.

Automatización programada y control de calidad

Tras ejecutar el script manualmente con éxito, se puede programar con cron, con el planificador de tareas de una plataforma en la nube o con un orquestador como n8n. La secuencia práctica de nodos no cambia: leer la lista de consultas, llamar a la API, comprobar el estado, guardar la respuesta original, normalizar los vídeos, registrar nuevas capturas y generar un informe. Transmite la clave mediante el mecanismo de secretos del entorno de ejecución, no en una tabla, el texto del flujo de trabajo ni un mensaje de error.

Una tarea automatizada se beneficia de cuatro comprobaciones. La primera: la solicitud se completó correctamente y la respuesta es JSON. La segunda: el estado externo coincide con el valor esperado. La tercera: el procesador entiende las dos estructuras de búsqueda y maneja correctamente los campos ausentes. La cuarta: se registran el número de vídeos únicos nuevos y el número de errores. Si de repente no hay resultados, el informe debe mostrar la muestra vacía como estado de esa ejecución, en lugar de mezclarla con un informe normal de éxito sin explicación.

Añade la paginación después de comprobar la primera página. Para la ruta de búsqueda, la documentación indica el parámetro cursor; guarda el token recibido y pásalo sin transformarlo en la siguiente solicitud. Limita el número máximo de páginas por término de búsqueda y detén el bucle si no hay elementos nuevos, no hay un cursor siguiente o se repite uno ya procesado. Este límite permite controlar el tiempo de ejecución y el tamaño de la recopilación. La existencia de un cursor permite solicitar la continuación de los resultados, pero no garantiza que estos incluyan todas las publicaciones.

Una nueva ejecución el mismo día puede devolver vídeos que ya aparecieron. Por eso, la clave de deduplicación debe ser un identificador de vídeo estable, y cada captura histórica debe guardarse como un registro independiente con la fecha de observación. Si necesitas una vista resumida, constrúyela a partir de las capturas: así podrás distinguir un vídeo encontrado por primera vez de otro que apareció en varias consultas o volvió a obtenerse más adelante.

Métricas: qué se puede comparar correctamente

Para el seguimiento operativo, son útiles el número de vídeos únicos encontrados por consulta, la proporción de vídeos con descripción, la distribución de las interacciones disponibles y la frecuencia con la que aparecen determinados temas. Al comparar consultas, mantén los mismos parámetros y el mismo periodo de ejecución. Si una ejecución usa this-week y otra this-month, la diferencia de volumen puede deberse a la ventana temporal y no se puede interpretar como un cambio de interés sin un análisis adicional.

Comparar las métricas de un mismo vídeo a lo largo del tiempo exige varias capturas y un esquema de almacenamiento uniforme. Conserva los valores originales de cada fecha tal como se recibieron y, después, calcula las diferencias entre observaciones. No llames «crecimiento diario» a una diferencia si los intervalos entre ejecuciones reales fueron distintos. Del mismo modo, ordenar los vídeos por «Me gusta» ayuda a encontrar los más visibles dentro de la muestra, pero no mide la eficacia comercial del autor ni del producto.

El informe final para el equipo de marketing puede combinar tres niveles: ejemplos de expresiones de la audiencia con enlaces, grupos temáticos de problemas y una descripción cuantitativa de la muestra obtenida. Cada conclusión debe incluir el número de observaciones, las consultas y el periodo de recopilación. Esto proporciona contexto a los responsables y permite al analista repetir el filtrado con los mismos datos originales.

Errores habituales y cómo evitarlos

Tratar un campo vacío como si fuera cero

Si faltan las estadísticas o la información del autor, el código anterior deja vacía la celda. Esto mantiene la distinción entre un valor desconocido y un cero medido. Al hacer el análisis, define explícitamente cómo tratar los valores ausentes e indica el número de filas excluidas de cada cálculo.

Dar por hecho que la búsqueda siempre devuelve un solo array

En las respuestas de búsqueda se encuentran aweme_list y elementos anidados en search_item_list[].aweme_info. El procesador comprueba ambos formatos e ignora los elementos de tipo incorrecto. Si cambia el esquema, las respuestas originales guardadas ayudarán a detectar rápidamente la nueva ubicación de los datos, y las muestras JSON de prueba permitirán verificar la corrección antes de la siguiente ejecución.

Contar el mismo vídeo otra vez como una señal independiente

Un mismo vídeo puede coincidir con varias palabras de búsqueda. En el ejemplo se incluye una sola vez en el CSV final, y el campo de consulta indica la primera coincidencia según el orden actual. Si necesitas conservar todas las correspondencias entre vídeo y consulta, guarda una tabla de relación independiente o una lista de consultas por identificador, en lugar de eliminar la procedencia del registro.

Comparar muestras que no son equivalentes

El término, la región, el filtro temporal, el orden y la fecha de ejecución influyen en la muestra. Guarda los parámetros junto con la respuesta y cambia un solo factor cada vez que el estudio compare variantes. Así será más fácil determinar si el cambio en los resultados se debe al comportamiento de los resultados de búsqueda o a una modificación de la configuración del experimento.

Presentar una correlación como intención de compra

La descripción de un vídeo y los contadores públicos aportan señales sobre el contenido y la reacción de la audiencia. Por sí solos no indican quién está dispuesto a comprar, si alguien ha visto un anuncio o cuál es la conversión. Úsalos para formular hipótesis, comprobar temas y preparar contenido. Evalúa la eficacia de ventas con los datos propios de las campañas, alineados con este estudio en cuanto a periodo y audiencia.

Cómo ampliar el flujo

Cuando la versión básica funcione de forma estable, puedes añadir un archivo de configuración con la lista de consultas y los parámetros de ejecución para modificar el diccionario sin editar Python. El siguiente paso es una tabla de correspondencias entre las consultas y grupos temáticos, como «calidad del reconocimiento», «velocidad de edición» y «exportación». El equipo debe definir estas categorías y comprobarlas con ejemplos; la API devuelve datos de búsqueda, pero el investigador establece el esquema semántico.

En lugar de CSV, se puede usar una base de datos relacional con tablas de ejecuciones, vídeos y capturas de métricas. Un índice único para el identificador del vídeo evita duplicados en el catálogo, y las capturas permiten seguir los cambios en los contadores disponibles. Guarda la fecha de observación en UTC y la versión del normalizador. Si cambia la lógica de extracción, podrás volver a procesar el archivo JSONL y comparar el resultado.

En n8n, la recopilación se puede ejecutar según un horario, mientras que la normalización se puede realizar en un servicio independiente de Python o en un nodo, si el entorno elegido admite las operaciones necesarias. No hace falta integrar un modelo en la primera etapa: primero consigue que la recopilación sea estable; después mide cuánto tiempo lleva la clasificación manual y qué categorías se repiten. La IA tiene sentido cuando reduce una tarea concreta y repetitiva y sus etiquetas se pueden comprobar.

Si la pregunta de trabajo se refiere al seguimiento periódico de una cuenta concreta y no a la búsqueda por expresiones, la guía oficial incluye una ruta independiente, /getUserFeed, con los parámetros query, max_cursor y count. Para un hashtag existe /getHashtagFeed, con el parámetro cursor. Son escenarios de recopilación distintos: la elección del endpoint debe partir de la pregunta de investigación, no de sustituir un tipo de muestra por otro.

Resultado: una muestra reproducible en lugar de una colección de marcadores

Tras ejecutar el proceso, el equipo obtiene dos recursos útiles: un archivo de las respuestas originales y una tabla de vídeos únicos con el término de búsqueda, la fecha de observación, el enlace, la descripción y las métricas disponibles. A partir de ellos se pueden agrupar manualmente las preguntas de la audiencia, enviar textos a un proceso de clasificación controlado, preparar un resumen semanal y comparar capturas sucesivas. El código gestiona explícitamente los errores de solicitud, comprueba el estado externo, distingue dos estructuras de búsqueda y conserva como valores ausentes las métricas que no están disponibles.

El resultado práctico para el equipo es una decisión más transparente sobre qué problemas conviene validar en entrevistas, páginas de destino o mensajes publicitarios. Si la investigación requiere otro tipo de datos, cambia las consultas o utiliza la ruta documentada correspondiente. Antes de adaptar el flujo, consulta la documentación de TikTok API; la información del producto y el acceso a la demostración están en la página de TikTok Scraper API.

Este enfoque responde al reto inicial: convertir la búsqueda en TikTok en un proceso de investigación reproducible. El script recopila vídeos concretos devueltos, conserva su procedencia y las capturas, y una persona o un clasificador verificable transforma el contenido en hipótesis sobre la demanda. El equipo obtiene una base para decidir los siguientes pasos, sin confundir las señales públicas del contenido con resultados de ventas confirmados.

Gente

Aún no hay personas en la lista para este artículo.

Sigue leyendoCómo archivar resultados de búsqueda de TikTok con Python
Lee el siguiente artículo

Convierte lo que lees en una integración funcional

Explora las API de datos sociales de jsonscraper, prueba solicitudes y crea tu próximo flujo de trabajo.

Explorar APIs