Il team di vendita riceve la stessa domanda da canali diversi: quali problemi stanno già cercando di risolvere i potenziali clienti? La ricerca manuale su TikTok produce una serie di video, ma è difficile ripeterla una settimana dopo, confrontare i risultati e spiegare perché un video specifico è finito nel report. Per una piccola ricerca è possibile trasformare i risultati pubblici di alcune query mirate in un flusso di dati riproducibile: salvare la risposta originale, estrarre i campi relativi al video e all’autore, rimuovere i duplicati e valutare separatamente gli indizi di intenzione d’acquisto o di scelta di un prodotto.

Di seguito è illustrato un flusso di lavoro funzionante in Python con TikTok Scraper API di jsonscraper. Può essere utile, per esempio, a un servizio di montaggio video che vuole capire come gli autori descrivono le difficoltà con sottotitoli, modelli ed esportazione. Lo script raccoglie i risultati restituiti dalla ricerca, poi un analista verifica la classificazione e decide quali formulazioni usare nello studio del pubblico. È un modo per organizzare l’osservazione dei contenuti pubblici, non per conteggiare automaticamente tutti gli utenti che intendono acquistare.
Il problema: le query del pubblico ci sono, ma è difficile ripetere la ricerca
Una ricerca manuale perde facilmente il contesto. Una persona cerca «come aggiungere i sottotitoli», un’altra «sottotitoli automatici per Reels», mentre una terza salva solo i video che le piacciono. La tabella finale mescola query, date, metriche e criteri di selezione diversi. Quando un responsabile chiede di ripetere l’analisi o confrontare due settimane, occorre ricostruire non solo i risultati, ma anche il percorso di ricerca.
È più utile definire in anticipo l’unità di osservazione: un video trovato, con testo della descrizione, identificativo, link, autore e metriche pubbliche disponibili. Per ogni video si salvano la query originale e l’ora della raccolta. In questo modo si può rispondere separatamente a domande come: quali formulazioni ricorrono, quali problemi vengono menzionati, quali video hanno ottenuto più reazioni pubbliche e cosa è cambiato tra gli snapshot salvati.
Prendiamo come esempio un’azienda che sviluppa uno strumento per creare sottotitoli e video brevi. Vuole trovare video pubblici in cui gli autori parlano esplicitamente di trascrizione manuale, errori nel riconoscimento vocale, temporizzazione dei titoli o preparazione di contenuti per più piattaforme. Non si dovrebbe attribuire all’autore l’etichetta di «lead» o «acquirente» sulla base di un solo video: un ricercatore può ordinare i contenuti in base a indizi osservabili e poi verificare manualmente le conclusioni.
Schema della soluzione: ricerca, registrazione, pulizia, valutazione
La pipeline si articola in quattro fasi. Per prima cosa il team prepara un piccolo elenco di query, ciascuna collegata a un’esigenza concreta del pubblico. Lo script richiede quindi la ricerca di video e salva la risposta JSON completa. La terza fase normalizza le diverse strutture di risposta in un’unica riga per video e rimuove i duplicati in base all’identificativo. Infine, regole o un classificatore IA separato assegnano una priorità per la verifica manuale, conservando la motivazione del punteggio.
Separare queste fasi è importante per la riproducibilità. La risposta grezza aiuta a esaminare modifiche ai campi o errori di normalizzazione. La tabella normalizzata è comoda per filtrare e visualizzare i dati. Una tabella separata per le valutazioni permette di modificare le regole senza ripetere le richieste API, se i dati salvati sono idonei a essere rielaborati e rispettano i tempi di conservazione del team.
Come query iniziali si possono usare «errori dei sottotitoli automatici», «come aggiungere i sottotitoli velocemente» e «montaggio di video brevi per le aziende». Sono solo esempi: le formulazioni vanno adattate alla lingua del pubblico e al prodotto. Le query devono essere archiviate insieme ai risultati, perché parole diverse producono campioni diversi.
Cosa offre TikTok Scraper API
Nella documentazione pubblicata da jsonscraper, la ricerca di video usa la rotta GET /searchVideo all’indirizzo base https://tiktok.evelode.com. Il parametro obbligatorio è keyword; tra i parametri aggiuntivi documentati figurano count, cursor, region, date_posted, sort_by e cache_timeout. Per esempio, sort_by accetta i valori documentati most-liked, relevance e date-posted, mentre date_posted accetta valori come this-week o all-time. L’elenco completo dei parametri e la funzione della rotta sono riportati nella guida agli endpoint di TikTok API.
La chiave viene trasmessa come parametro di query license_key. Nell’esempio seguente è letta dalla variabile d’ambiente JSONSCRAPER_TIKTOK_LICENSE_KEY, così da non inserire il segreto nel codice né stamparlo nei log. Per l’autenticazione e la selezione dei parametri, segui le condizioni attuali del tuo accesso; la pagina di TikTok Scraper API descrive il prodotto e rimanda alla demo e alla documentazione.
La risposta della ricerca va analizzata tenendo conto della struttura, senza presumere che ci sia un solo array. Nell’esempio verificato, l’API restituiva uno stato di primo livello e un oggetto tiktok; i video possono trovarsi in tiktok.aweme_list, mentre nei risultati di ricerca si incontra anche tiktok.search_item_list[].aweme_info. Controlla entrambe le forme. Negli oggetti trovati sono disponibili, se presenti, l’identificativo del video, la descrizione, il link, l’ora di pubblicazione, le informazioni sull’autore e le statistiche, per esempio visualizzazioni, like, commenti e condivisioni. Metriche e campi vanno considerati facoltativi: il codice non deve inserire zeri inventati quando un valore manca.
La paginazione della ricerca usa cursor. Se lo script continua a scorrere i risultati, deve trasmettere il valore ricevuto come token opaco per la richiesta successiva, senza calcolarlo autonomamente. Per un prototipo iniziale è ragionevole limitare la raccolta a una sola pagina per query: semplifica la verifica e rende prevedibile il carico. In seguito si può aggiungere la paginazione con un limite al numero di pagine e una protezione contro la ripetizione del cursore.
Preparazione dell’ambiente
L’esempio usa Python 3.8 o versioni successive e la libreria standard. Imposta la chiave nell’ambiente, per esempio da una shell macOS o Linux:
export JSONSCRAPER_TIKTOK_LICENSE_KEY="la_tua_chiave"
python tiktok_demand.py
In Windows PowerShell puoi impostare la variabile così:
$env:JSONSCRAPER_TIKTOK_LICENSE_KEY="la_tua_chiave"
python .\tiktok_demand.py
Lo script esegue una richiesta separata per ogni parola chiave. Controlla gli errori HTTP, la risposta JSON e lo stato esterno, quindi estrae gli oggetti da entrambe le varianti di array documentate. Le risposte grezze vengono scritte riga per riga in un file JSONL: ogni record contiene la query, l’ora dell’osservazione e la risposta originale. La seconda parte crea un CSV con campi uniformi. La chiave non è presente nel codice e il segreto non viene stampato.
Esempio: raccolta e normalizzazione dei risultati di ricerca
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 = [
"errori dei sottotitoli automatici",
"come aggiungere i sottotitoli velocemente",
"montaggio di video brevi per le aziende",
]
def extract_videos(payload):
"""Supporta entrambe le strutture osservate nella risposta di ricerca."""
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("L’API ha restituito lo stato HTTP {}".format(exc.code)) from exc
except (URLError, TimeoutError, json.JSONDecodeError) as exc:
raise RuntimeError("Impossibile completare o analizzare la richiesta API") from exc
if payload.get("status") != "ok":
raise RuntimeError("Lo stato della risposta API non è 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("Imposta JSONSCRAPER_TIKTOK_LICENSE_KEY nell’ambiente")
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("Salvati {} video unici restituiti in {}".format(len(rows), csv_path))
if __name__ == "__main__":
main()
Il valore di count indica qui la dimensione del campione richiesto per query. Lo script non presume che l’API debba restituire esattamente quel numero di elementi: il numero effettivo di righe dipende dalla risposta. La pausa tra le richieste è una semplice misura per gestire il ritmo di esecuzione, non un’affermazione sui limiti o sui requisiti del servizio. Per un’attività pianificata in produzione, aggiungi tentativi ripetuti con un limite, monitoraggio degli errori e regole sulla frequenza di richiesta consentita, in base alle condizioni del tuo piano.
Come leggere la tabella ottenuta
Nel CSV ogni riga rappresenta un video restituito e trovato tramite una delle query, senza duplicati. Il campo query indica la provenienza del record, observed_at l’ora dello snapshot e video_id funge da chiave di deduplicazione. La descrizione e il link aiutano l’analista a verificare il contesto, mentre i contatori pubblici consentono di valutare la risposta al momento della raccolta. Per confronti a lungo termine, usa osservazioni separate: non sovrascrivere lo storico delle metriche se vuoi seguirne l’andamento.
I contatori di visualizzazioni, like, commenti e condivisioni sono uno snapshot delle statistiche pubbliche restituite dall’API al momento della richiesta. Possono mancare in singoli oggetti, quindi un valore vuoto nel CSV indica che nella risposta non era presente un campo numerico. È diverso da zero e va gestito separatamente nel calcolo degli aggregati. Inoltre, i risultati trovati riflettono il campione restituito per determinate parole, regione, filtro temporale e parametri di richiesta. Descrivono i video effettivamente ottenuti, non l’intero volume di contenuti o di pubblico della piattaforma.
Per una prima valutazione della potenziale pertinenza si può creare una tabella trasparente di regole: corrispondenze con formulazioni di problemi, menzioni dello strumento usato, domande su prezzi o confronti, presenza di uno scenario di lavoro concreto. È meglio conservare gli indicatori separati e la motivazione della valutazione, anziché registrare solo un punteggio opaco. Per esempio, un video che chiede informazioni sulla precisione della trascrizione automatica può essere contrassegnato come «da verificare: si discute della qualità», mentre un video con consigli generici sui contenuti può essere indicato come «pertinenza tematica bassa».
Collegare l’IA senza farne un giudice
Una volta raccolto un campione, un modello può aiutare a classificare le descrizioni secondo uno schema prestabilito: problema, strumento menzionato, tono della domanda e presenza di un segnale di scelta del prodotto. Passa al modello solo i campi necessari, per esempio il testo della descrizione e l’identificativo del record, e chiedigli di restituire un JSON fisso con etichette e una breve motivazione. Salva la versione delle istruzioni, il modello e il risultato accanto alla riga originale, così da poter ripetere la classificazione o verificarla a campione con una persona.
Una richiesta utile al classificatore dovrebbe limitare le conclusioni agli indizi osservabili. Chiedigli di determinare se il testo contiene un problema esplicito relativo ai sottotitoli, una richiesta di raccomandazione di uno strumento o una discussione sul flusso di lavoro. Se le informazioni sono insufficienti, prevedi la categoria «contesto insufficiente». Il modello non dovrebbe dedurre l’identità dell’autore, le sue intenzioni d’acquisto o le sue caratteristiche demografiche da un singolo video pubblico. Il risultato è una coda di temi da analizzare, non un elenco di persone da contattare automaticamente.
Per valutare la qualità delle etichette, seleziona un campione casuale e assegna manualmente le stesse categorie. Confronta la concordanza per ogni etichetta e analizza gli errori: per esempio, il modello potrebbe interpretare il sarcasmo come un reclamo o un consiglio didattico come un’esperienza personale. Spesso correggere il lessico delle query e le istruzioni è più utile che rendere subito il modello più complesso. Nel report conserva testi originali e link secondo le politiche di conservazione e accesso adottate.
Automazione pianificata e controllo qualità
Dopo aver verificato l’esecuzione manuale, è possibile pianificare lo script con cron, con l’utilità di pianificazione di una piattaforma cloud o con un orchestratore come n8n. La sequenza pratica dei passaggi resta la stessa: leggere l’elenco delle query, chiamare l’API, verificare lo stato, salvare la risposta grezza, normalizzare i video, registrare i nuovi snapshot e creare un report. La chiave va trasmessa tramite il sistema di gestione dei segreti dell’ambiente di esecuzione, non in una tabella, nel testo del workflow o in un messaggio di errore.
In un’attività automatizzata sono utili quattro controlli. Primo: la richiesta è stata completata e la risposta è JSON. Secondo: lo stato esterno corrisponde al valore atteso. Terzo: il gestore comprende entrambe le varianti della struttura di ricerca e gestisce correttamente i campi mancanti. Quarto: il numero di nuovi video unici e quello degli errori vengono registrati nel log. Se all’improvviso non ci sono risultati, il report deve indicare il campione nullo come esito dell’esecuzione, invece di confonderlo con un normale report positivo senza spiegazioni.
Aggiungi la paginazione dopo aver verificato la prima pagina. Per la rotta di ricerca, la documentazione indica il parametro cursor; salva il token ricevuto e passalo senza modificarlo nella richiesta successiva. Imposta un numero massimo di pagine per termine di ricerca e interrompi il ciclo se non ci sono nuovi elementi, se manca il cursore successivo o se viene ripetuto un cursore già elaborato. Questo limite rende gestibili i tempi di esecuzione e le dimensioni della raccolta. La presenza del cursore consente di proseguire nei risultati, ma non garantisce che siano completi rispetto a tutte le pubblicazioni.
Un’esecuzione ripetuta nello stesso giorno può restituire video sovrapposti. La chiave di deduplicazione deve quindi essere un identificativo stabile del video, mentre lo storico degli snapshot va registrato separatamente con la data di osservazione. Se serve una vista riepilogativa, costruiscila a partire dagli snapshot: così si può distinguere un video trovato per la prima volta da uno apparso in più query o recuperato di nuovo in seguito.
Metriche: cosa si può confrontare correttamente
Per il monitoraggio operativo sono utili il numero di video unici trovati per query, la percentuale di video con una descrizione compilata, la distribuzione delle reazioni disponibili e la frequenza con cui compaiono determinati temi. Nel confrontare le query, mantieni fissi i parametri e il periodo di esecuzione. Se una ricerca usa this-week e un’altra this-month, la differenza nei volumi può essere dovuta alla finestra temporale e non va interpretata come un cambiamento d’interesse senza ulteriori analisi.
Per confrontare nel tempo le metriche di un singolo video occorrono più snapshot e uno schema di archiviazione uniforme. Per ogni data conserva i valori originali così come sono stati restituiti; calcola poi la differenza tra le osservazioni. Non definire la differenza come crescita giornaliera se gli intervalli tra le esecuzioni effettive erano diversi. Analogamente, ordinare per like aiuta a trovare i video più visibili nel campione raccolto, ma non misura l’efficacia commerciale dell’autore o del prodotto.
Il report finale per il team marketing può riunire tre livelli: esempi di formulazioni del pubblico con link cliccabili, gruppi tematici di problemi e una descrizione quantitativa del campione ottenuto. Ogni conclusione dovrebbe essere accompagnata dal numero di osservazioni, dalle query e dal periodo di raccolta. In questo modo il responsabile ha il contesto necessario e l’analista può ripetere il filtraggio sugli stessi dati originali.
Errori comuni e come evitarli
Considerare un campo vuoto come un valore pari a zero
Se mancano le statistiche o i dati dell’autore, il codice sopra lascia vuota la cella. In questo modo si mantiene la distinzione tra valore sconosciuto e zero misurato. Nell’analisi definisci esplicitamente come gestire i dati mancanti e indica quante righe sono state escluse da ciascun calcolo.
Presumere che la ricerca restituisca sempre un solo array
Nella risposta di ricerca si incontrano aweme_list e gli elementi annidati search_item_list[].aweme_info. Il gestore controlla entrambe le forme e ignora gli elementi di tipo non corretto. Se lo schema cambia, le risposte grezze salvate aiutano a individuare rapidamente la nuova posizione dei dati, mentre i JSON di test consentono di verificare la correzione prima dell’esecuzione successiva.
Conteggiare più volte lo stesso video come segnale distinto
Un video può corrispondere a più parole di ricerca. Nell’esempio viene incluso una sola volta nel CSV finale e il campo della query indica la prima corrispondenza nell’ordine corrente. Se è importante conservare tutte le associazioni «video — query», usa una tabella di collegamento separata o un elenco di query per ogni identificativo, anziché perdere la provenienza del record.
Confrontare campioni non omogenei
La parola, la regione, il filtro temporale, l’ordinamento e la data di esecuzione influenzano il campione. Salva i parametri insieme alla risposta e modifica un solo fattore per volta quando la ricerca confronta diverse opzioni. Questo aiuta a capire se la variazione dei risultati dipende dal comportamento dei risultati di ricerca o dalle impostazioni dell’esperimento.
Scambiare una correlazione per un’intenzione d’acquisto
Le descrizioni dei video e i contatori pubblici forniscono indizi sul contenuto e sulle reazioni del pubblico. Da soli non mostrano chi è pronto ad acquistare, se una persona ha visto una pubblicità o quale sia il tasso di conversione. Usali per formulare ipotesi, verificare temi e preparare contenuti. Valuta l’efficacia delle vendite con i dati delle tue campagne, allineandoli temporalmente e per pubblico a questa ricerca.
Come ampliare la pipeline
Quando la versione di base è stabile, puoi aggiungere un file di configurazione con l’elenco delle query e i parametri di esecuzione, così da modificare il lessico senza intervenire sul codice Python. Il passo successivo è una tabella di corrispondenza tra query e cluster tematici, per esempio «qualità del riconoscimento», «velocità di montaggio» ed «esportazione». Queste categorie devono essere definite dal team e verificate su esempi: l’API restituisce dati di ricerca, mentre lo schema semantico è stabilito dal ricercatore.
Al posto del CSV si può usare un database relazionale con una tabella delle esecuzioni, una dei video e una degli snapshot delle metriche. Un indice univoco sull’identificativo del video impedisce duplicati nel catalogo, mentre gli snapshot permettono di seguire l’evoluzione dei contatori disponibili. Conserva la data di osservazione in UTC e la versione del normalizzatore. Se cambia la logica di estrazione, puoi rielaborare l’archivio JSONL e confrontare i risultati.
In n8n la raccolta può essere pianificata, mentre il codice di normalizzazione può essere eseguito in un servizio Python separato o in un nodo, se l’ambiente scelto supporta le operazioni necessarie. Per la prima fase non è indispensabile integrare un modello: prima rendi stabile la raccolta, poi misura quanto tempo richiede la classificazione manuale e quali categorie ricorrono. L’IA è utile quando riduce un’attività ripetitiva concreta e le sue etichette possono essere verificate.
Se il quesito di lavoro riguarda il monitoraggio regolare di un account specifico, anziché la ricerca per formulazioni, la guida ufficiale include una rotta separata /getUserFeed con i parametri query, max_cursor e count. Per un hashtag è prevista /getHashtagFeed, con il parametro cursor. Sono scenari di raccolta diversi: la scelta dell’endpoint dovrebbe partire dalla domanda di ricerca, non sostituire un tipo di campione con un altro.
Risultato: un campione riproducibile al posto di una raccolta di segnalibri
Dopo l’esecuzione, il team ottiene due risorse utili: un archivio delle risposte originali e una tabella di video unici con termine di ricerca, data di osservazione, link, descrizione e metriche disponibili. Su questa base è possibile raggruppare manualmente le domande del pubblico, sottoporre i testi a una classificazione controllata, preparare un riepilogo settimanale e confrontare snapshot ripetuti. Il codice gestisce esplicitamente gli errori di richiesta, controlla lo stato esterno, distingue due varianti della struttura di ricerca e conserva le metriche mancanti come valori assenti.
Per il team, il risultato pratico è una decisione più trasparente su quali problemi verificare in un’intervista, in una landing page o in un messaggio pubblicitario. Se la ricerca richiede un altro tipo di dati, modifica le query o usa la rotta documentata appropriata. Prima di adattare la pipeline, consulta la documentazione di TikTok API; le informazioni sul prodotto e l’accesso alla demo si trovano nella pagina di TikTok Scraper API.
Questo approccio risponde al problema iniziale: trasformare la ricerca su TikTok in un processo di ricerca riproducibile. Lo script raccoglie i video effettivamente restituiti, ne conserva la provenienza e gli snapshot, mentre una persona o un classificatore verificabile trasforma i contenuti in ipotesi sulla domanda. Il team ottiene una base per decidere i passi successivi, mantenendo chiara la distinzione tra gli indizi pubblici dei contenuti e i risultati di vendita confermati.