L’équipe commerciale reçoit la même question par différents canaux : quels problèmes les clients potentiels cherchent-ils déjà à résoudre ? Une recherche manuelle sur TikTok renvoie une multitude de vidéos, mais il est difficile de la reproduire une semaine plus tard, de comparer les résultats et d’expliquer pourquoi une vidéo donnée figure dans le rapport. Pour une petite étude, on peut transformer les résultats publics obtenus avec quelques requêtes précises en un flux de données reproductible : enregistrer la réponse brute, extraire les champs relatifs à la vidéo et à son auteur, éliminer les doublons et évaluer séparément les signes explicites d’une intention d’acheter ou de choisir un produit.

Voici un flux de travail opérationnel en Python avec TikTok Scraper API de jsonscraper. Il peut, par exemple, servir à une entreprise de montage vidéo qui souhaite découvrir comment les créateurs décrivent les difficultés liées aux sous-titres, aux modèles et à l’exportation. Le script collecte les résultats de recherche renvoyés ; un analyste vérifie ensuite leur classification et décide quelles formulations utiliser dans l’étude de l’audience. Il s’agit d’une façon d’organiser l’observation de contenus publics, et non de compter automatiquement tous les utilisateurs ayant l’intention d’acheter.
Le problème : les requêtes de l’audience existent, mais l’étude est difficile à reproduire
Une étude manuelle perd facilement son contexte. Une personne cherche « comment ajouter des sous-titres », une autre « sous-titres automatiques pour Reels », tandis qu’une troisième n’enregistre que les vidéos qu’elle aime. Le tableau final mélange différentes requêtes, dates, métriques et règles de sélection. Lorsque la direction demande de refaire l’analyse ou de comparer deux semaines, il faut reconstituer non seulement les résultats, mais aussi le processus de recherche lui-même.
Il est plus utile de définir à l’avance l’unité d’observation : une vidéo trouvée, avec le texte de sa description, son identifiant, son lien, son auteur et les métriques publiques disponibles. On enregistre pour chaque vidéo la requête de recherche d’origine et l’heure de collecte. On peut alors répondre séparément aux questions suivantes : quelles formulations reviennent, quels problèmes sont mentionnés, quelles vidéos ont suscité le plus de réactions publiques et qu’est-ce qui a changé entre les instantanés enregistrés.
Prenons l’exemple d’une entreprise qui développe un outil de création de sous-titres et de vidéos courtes. Elle souhaite trouver des vidéos publiques dans lesquelles les créateurs parlent directement de transcription manuelle, d’erreurs de reconnaissance vocale, de synchronisation des titres ou de préparation de contenu pour plusieurs plateformes. Il ne faut pas attribuer à un auteur le statut de « prospect » ou d’« acheteur » sur la seule base d’une vidéo : un chercheur peut classer le contenu selon des indices observables, puis vérifier manuellement ses conclusions.
Le principe de la solution : recherche, archivage, nettoyage, évaluation
Le pipeline se compose de quatre étapes. D’abord, l’équipe constitue un petit lexique de requêtes, chacune correspondant à un problème précis de l’audience. Le script lance ensuite une recherche de vidéos et enregistre la réponse JSON complète. La troisième étape normalise les différentes structures de réponse sous la forme d’une ligne unique par vidéo et élimine les doublons à partir de l’identifiant. Enfin, des règles ou un classificateur IA distinct attribuent une priorité pour une vérification manuelle, tout en conservant la justification de l’évaluation.
La séparation de ces étapes est importante pour assurer la reproductibilité. La réponse brute permet d’examiner les changements de champs ou les erreurs de normalisation. Le tableau normalisé facilite le filtrage et la visualisation. Un tableau d’évaluations séparé permet de modifier les règles sans relancer l’API, si les données enregistrées se prêtent à un nouveau traitement et respectent la durée de conservation définie par l’équipe.
À titre d’exemple, on peut utiliser « erreurs des sous-titres automatiques », « comment ajouter rapidement des sous-titres » et « montage de vidéos courtes pour les entreprises ». Ce ne sont que des exemples de lexique : les formulations doivent être adaptées à la langue de l’audience et au produit. Les requêtes doivent être conservées avec les résultats, car des mots différents produisent des échantillons différents.
Ce que fournit TikTok Scraper API
La documentation publiée par jsonscraper indique, pour la recherche de vidéos, la route GET /searchVideo à l’adresse de base https://tiktok.evelode.com. Le paramètre obligatoire est keyword ; parmi les paramètres supplémentaires documentés figurent count, cursor, region, date_posted, sort_by et cache_timeout. Par exemple, sort_by accepte les valeurs documentées most-liked, relevance et date-posted, tandis que date_posted accepte des valeurs telles que this-week ou all-time. La documentation des points de terminaison TikTok API indique la liste exacte des paramètres et la fonction de la route.
La clé est transmise comme paramètre de requête license_key. Dans l’exemple ci-dessous, elle est lue dans la variable d’environnement JSONSCRAPER_TIKTOK_LICENSE_KEY, afin de ne pas conserver le secret dans le code ni l’afficher dans les journaux. Pour l’authentification et le choix des paramètres, suivez les conditions d’accès en vigueur pour votre compte ; la page de TikTok Scraper API présente le produit et donne accès à la démonstration et à la documentation.
La réponse de recherche doit être analysée en fonction de sa structure, sans supposer qu’elle contient un seul tableau. Dans l’exemple vérifié, l’API renvoyait un statut de premier niveau et un objet tiktok ; les vidéos peuvent se trouver dans tiktok.aweme_list, et les résultats de recherche peuvent aussi apparaître dans tiktok.search_item_list[].aweme_info. Vérifiez les deux formes. Dans les objets trouvés, on peut disposer, si les champs sont présents, de l’identifiant de la vidéo, de sa description, de son lien, de sa date de publication, des informations sur l’auteur et de statistiques telles que les vues, les mentions J’aime, les commentaires et les partages. Ces métriques et ces champs doivent être considérés comme facultatifs : le code ne doit pas inventer des zéros lorsque les valeurs sont absentes.
La pagination de la recherche utilise cursor. Si le script poursuit les résultats, il doit transmettre la valeur reçue comme un jeton opaque pour la requête suivante, et non la calculer lui-même. Pour un premier prototype, il est raisonnable de limiter la collecte à une page par requête : cela simplifie la vérification et rend la charge prévisible. On peut ensuite ajouter la pagination avec une limite du nombre de pages et une protection contre la répétition du curseur.
Préparation de l’environnement
L’exemple utilise Python 3.8 ou une version ultérieure, ainsi que la bibliothèque standard. Définissez la clé dans l’environnement, par exemple dans un shell macOS ou Linux :
export JSONSCRAPER_TIKTOK_LICENSE_KEY="votre_clé"
python tiktok_demand.py
Sous Windows PowerShell, vous pouvez définir la variable ainsi :
$env:JSONSCRAPER_TIKTOK_LICENSE_KEY="votre_clé"
python .\tiktok_demand.py
Le script lance une requête distincte pour chaque mot-clé. Il vérifie les erreurs HTTP, la réponse JSON et le statut externe, puis extrait les objets à partir des deux variantes confirmées du tableau. Les réponses brutes sont écrites ligne par ligne dans un fichier JSONL : chaque entrée contient la requête, l’heure d’observation et la réponse d’origine. La seconde partie crée un fichier CSV avec des champs normalisés. Le fichier ne contient pas la clé et le secret n’est pas affiché.
Exemple : collecte et normalisation des résultats de recherche
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 = [
"erreurs des sous-titres automatiques",
"comment ajouter rapidement des sous-titres",
"montage de vidéos courtes pour les entreprises",
]
def extract_videos(payload):
"""Prend en charge les deux structures de réponse observées pour la recherche."""
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 a renvoyé le statut HTTP {}".format(exc.code)) from exc
except (URLError, TimeoutError, json.JSONDecodeError) as exc:
raise RuntimeError("Impossible d’effectuer ou d’analyser la requête API") from exc
if payload.get("status") != "ok":
raise RuntimeError("Le statut de la réponse API n’était pas 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("Définissez JSONSCRAPER_TIKTOK_LICENSE_KEY dans l’environnement")
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("{} vidéos uniques renvoyées enregistrées dans {}".format(len(rows), csv_path))
if __name__ == "__main__":
main()
La valeur count correspond ici à la taille d’échantillon demandée pour chaque requête. Le script ne suppose pas que l’API renverra exactement ce nombre d’éléments : le nombre réel de lignes dépend de la réponse. La pause entre les requêtes est une simple mesure de régulation du rythme d’exécution, et non une affirmation concernant une limite ou une exigence du service. Pour une exécution en production, ajoutez une gestion des tentatives avec un nombre maximal, une surveillance des erreurs et des règles de fréquence de requêtes autorisée, en fonction des conditions de votre offre.
Comment lire le tableau obtenu
Dans le CSV, chaque ligne représente une vidéo unique renvoyée et trouvée à partir de l’une des requêtes. Le champ query indique l’origine de l’entrée, observed_at l’heure de l’instantané, et video_id sert de clé de déduplication. La description et le lien aident l’analyste à vérifier le contexte, tandis que les compteurs publics permettent d’évaluer les réactions au moment de la collecte. Pour effectuer des comparaisons à long terme, utilisez des observations distinctes : ne remplacez pas l’historique des métriques si vous souhaitez suivre leur évolution.
Les compteurs de vues, de mentions J’aime, de commentaires et de partages sont un instantané des statistiques publiques renvoyées par l’API au moment de la requête. Ils peuvent manquer dans certains objets ; une valeur vide dans le CSV signifie donc que la réponse ne contenait pas de champ numérique. Cette valeur est différente de zéro et doit être traitée séparément lors du calcul des agrégats. De plus, les résultats trouvés reflètent l’échantillon obtenu pour des mots, une région, un filtre temporel et des paramètres de requête donnés. Ils décrivent les vidéos récupérées, et non la totalité du contenu ou de l’audience de la plateforme.
Pour une première évaluation de la pertinence potentielle, on peut établir une grille de règles transparente : correspondances avec les formulations de problèmes, mentions d’un outil utilisé, questions sur le prix ou la comparaison, présence d’un scénario de travail concret. Il est préférable de stocker séparément les indices et la justification de l’évaluation, plutôt que de n’enregistrer qu’un score opaque. Par exemple, une vidéo contenant une question sur la précision de la transcription automatique peut être marquée « à vérifier : la qualité est abordée », tandis qu’une vidéo donnant des conseils généraux sur le contenu peut être marquée « faible pertinence thématique ».
Connecter l’IA sans lui confier le rôle de juge
Une fois l’échantillon constitué, un modèle peut aider à classer les descriptions selon un schéma défini à l’avance : problème, outil mentionné, tonalité de la question et présence d’un signe de choix de produit. Ne transmettez au modèle que les champs nécessaires — par exemple, le texte de la description et l’identifiant de l’entrée — et demandez-lui de renvoyer un JSON fixe contenant les étiquettes et une brève justification. Enregistrez la version de l’instruction, le modèle et le résultat à côté de la ligne d’origine afin de pouvoir refaire la classification ou la vérifier ponctuellement avec une personne.
Une consigne utile pour le classificateur doit limiter ses conclusions aux indices observables. Demandez-lui de déterminer si le texte contient un problème explicite lié aux sous-titres, une demande de recommandation d’outil ou une discussion sur un processus de travail. Si les données sont insuffisantes, prévoyez la catégorie « contexte insuffisant ». Le modèle ne doit pas déduire l’identité de l’auteur, son intention d’achat ou ses caractéristiques démographiques à partir d’une seule vidéo publique. Le résultat est une liste de sujets à analyser, pas une liste de personnes à contacter automatiquement.
Pour évaluer la qualité de l’étiquetage, sélectionnez un échantillon aléatoire et attribuez-y manuellement les mêmes catégories. Comparez la concordance pour chaque étiquette et examinez les erreurs : le modèle peut, par exemple, prendre du sarcasme pour une plainte ou un conseil éducatif pour un témoignage personnel. Corriger le lexique des requêtes et la consigne est souvent plus utile que de complexifier immédiatement le modèle. Pour le rapport, conservez les textes d’origine et les liens conformément à la politique de conservation et d’accès adoptée.
Automatisation planifiée et contrôle qualité
Après un lancement manuel réussi, le script peut être exécuté selon un calendrier avec cron, le planificateur de tâches d’une plateforme cloud ou un orchestrateur comme n8n. La séquence pratique des étapes reste la même : lire la liste des requêtes, appeler l’API, vérifier le statut, enregistrer la réponse brute, normaliser les vidéos, enregistrer les nouveaux instantanés et générer un rapport. Transmettez la clé via le mécanisme de gestion des secrets de l’environnement d’exécution, et non dans un tableau, le texte d’un workflow ou un message d’erreur.
Quatre contrôles sont utiles dans une tâche automatisée. Premièrement, la requête s’est achevée avec succès et la réponse est au format JSON. Deuxièmement, le statut externe correspond à la valeur attendue. Troisièmement, le gestionnaire comprend les deux variantes de la structure de recherche et supporte correctement les champs absents. Quatrièmement, le nombre de nouvelles vidéos uniques et celui des erreurs sont consignés. Si aucun résultat n’apparaît soudainement, le rapport doit présenter l’échantillon nul comme l’état de cette exécution, et non le confondre avec un rapport de réussite ordinaire sans explication.
Ajoutez la pagination après avoir vérifié la première page. Pour la route de recherche, la documentation indique le paramètre cursor ; conservez le jeton reçu et transmettez-le sans le modifier dans la requête suivante. Limitez le nombre maximal de pages pour chaque terme de recherche et arrêtez la boucle en l’absence de nouveaux éléments, de curseur suivant ou si un curseur déjà traité réapparaît. Cette limite permet de maîtriser la durée d’exécution et le volume de collecte. La présence d’un curseur permet de poursuivre les résultats, mais ne garantit pas l’exhaustivité par rapport à l’ensemble des publications.
Plusieurs exécutions le même jour peuvent renvoyer des vidéos qui se recoupent. La clé de déduplication doit donc être un identifiant stable de vidéo, tandis que l’historique des instantanés doit être enregistré séparément avec la date d’observation. Si vous avez besoin d’une vue synthétique, créez-la à partir des instantanés : vous pourrez ainsi distinguer une vidéo trouvée pour la première fois de celle qui apparaît dans plusieurs requêtes ou a été récupérée de nouveau ultérieurement.
Métriques : ce que l’on peut comparer correctement
Pour le suivi opérationnel, il est utile de connaître le nombre de vidéos uniques trouvées par requête, la part des vidéos dont la description est renseignée, la répartition des réactions disponibles et la fréquence d’apparition de certains thèmes. Pour comparer les requêtes, fixez les mêmes paramètres et la même période de lancement. Si une exécution utilise this-week et l’autre this-month, la différence de volume peut s’expliquer par la fenêtre temporelle ; on ne peut donc pas l’interpréter comme un changement d’intérêt sans analyse supplémentaire.
Comparer les métriques d’une vidéo dans le temps nécessite plusieurs instantanés et un schéma de stockage uniforme. Pour chaque date, conservez les valeurs d’origine telles qu’elles ont été reçues, puis calculez la différence entre les observations. Ne qualifiez pas cette différence de hausse sur une journée si les intervalles entre les exécutions réelles varient. De même, classer les vidéos en fonction des mentions J’aime permet de repérer les vidéos les plus remarquées dans l’échantillon collecté, mais ne mesure pas l’efficacité commerciale du créateur ou du produit.
Le rapport final destiné à l’équipe marketing peut réunir trois niveaux : des exemples de formulations de l’audience avec des liens cliquables, des groupes thématiques de problèmes et une description quantitative de l’échantillon obtenu. Chaque conclusion doit être accompagnée du nombre d’observations, des requêtes et de la période de collecte. La direction dispose ainsi du contexte nécessaire, et l’analyste peut refaire le filtrage à partir des mêmes données brutes.
Erreurs courantes et façons de les éviter
Considérer un champ vide comme une valeur nulle
Si les statistiques ou les informations sur l’auteur sont absentes, le code ci-dessus laisse la cellule vide. La distinction est ainsi préservée entre une valeur inconnue et un zéro mesuré. Lors de l’analyse, définissez explicitement le traitement des valeurs manquantes et indiquez le nombre de lignes exclues d’un calcul particulier.
Supposer que la recherche renvoie toujours un seul tableau
La réponse de recherche peut contenir aweme_list ou des éléments imbriqués dans search_item_list[].aweme_info. Le gestionnaire vérifie les deux formes et ignore les éléments de type inadéquat. Si le schéma change, les réponses brutes enregistrées aideront à repérer rapidement le nouvel emplacement des données, et des fichiers JSON de test permettront de vérifier la correction avant la prochaine exécution.
Compter de nouveau une même vidéo comme un signal distinct
Une même vidéo peut correspondre à plusieurs mots de recherche. Dans l’exemple, elle n’est incluse qu’une fois dans le CSV final, et le champ de requête indique la première correspondance selon l’ordre actuel. Si vous devez conserver toutes les correspondances « vidéo — requête », stockez une table de liaison distincte ou une liste de requêtes pour chaque identifiant, au lieu de supprimer la provenance de l’entrée.
Comparer des échantillons qui ne sont pas comparables
Le mot, la région, le filtre temporel, le tri et la date d’exécution influencent l’échantillon. Enregistrez les paramètres avec la réponse et ne modifiez qu’un facteur à la fois lorsque l’étude compare plusieurs variantes. Cela aide à déterminer si le changement de résultat est lié au comportement des résultats de recherche ou à une modification des paramètres de l’expérience.
Présenter une corrélation comme une intention d’achat
Les descriptions de vidéos et les compteurs publics donnent des indices sur le contenu et les réactions de l’audience. À eux seuls, ils ne révèlent pas qui est prêt à acheter, si une personne a vu une publicité ni quel est le taux de conversion. Utilisez-les pour formuler des hypothèses, vérifier des thèmes et préparer du contenu. Évaluez l’efficacité commerciale à partir des données de vos propres campagnes, rapprochées de cette étude par période et par audience.
Comment faire évoluer le pipeline
Une fois la version de base stabilisée, vous pouvez ajouter un fichier de configuration contenant la liste des requêtes et les paramètres d’exécution afin de modifier le lexique sans toucher au code Python. L’étape suivante consiste à créer une table de correspondance entre les requêtes et les groupes thématiques, par exemple « qualité de la reconnaissance », « rapidité du montage » et « exportation ». L’équipe doit définir ces catégories et les vérifier sur des exemples ; l’API renvoie les données de recherche, tandis que le chercheur définit le schéma sémantique.
Pour le stockage, une base de données relationnelle peut remplacer le CSV : une table des exécutions, une table des vidéos et une table des instantanés de métriques. Un index unique sur l’identifiant vidéo empêche la duplication dans le catalogue, tandis que les instantanés permettent de suivre l’évolution des compteurs disponibles. Enregistrez la date d’observation en UTC ainsi que la version du normaliseur. Si la logique d’extraction change, vous pourrez retraiter l’archive JSONL et comparer le résultat.
Dans n8n, la collecte peut être lancée à intervalles réguliers, et le code de normalisation peut être exécuté dans un service Python distinct ou un nœud, si l’environnement choisi prend en charge les opérations nécessaires. Il n’est pas nécessaire d’intégrer un modèle dès la première étape : commencez par stabiliser la collecte, puis mesurez le temps consacré à la classification manuelle et repérez les catégories récurrentes. L’IA est pertinente si elle réduit une tâche répétitive précise et si ses étiquettes peuvent être vérifiées.
Si la question de travail porte non pas sur une recherche par formulation, mais sur le suivi régulier d’un compte donné, la documentation officielle propose une route distincte, /getUserFeed, avec les paramètres query, max_cursor et count. Pour un hashtag, la route /getHashtagFeed utilise le paramètre cursor. Il s’agit de scénarios de collecte différents : le choix du point de terminaison doit partir de la question de recherche et non consister à remplacer un type d’échantillon par un autre.
Résultat : un échantillon reproductible plutôt qu’une collection de favoris
Après l’exécution, l’équipe dispose de deux ressources utiles : une archive des réponses d’origine et un tableau des vidéos uniques comprenant le terme de recherche, la date d’observation, le lien, la description et les métriques disponibles. À partir de ces données, elle peut regrouper manuellement les questions de l’audience, soumettre les textes à une classification contrôlée, préparer un récapitulatif hebdomadaire et comparer des instantanés successifs. Le code traite explicitement les erreurs de requête, vérifie le statut externe, distingue deux variantes de la structure de recherche et conserve les métriques absentes comme des valeurs manquantes.
Pour l’équipe, le résultat pratique est une décision plus transparente sur les problèmes à vérifier dans des entretiens, une page de destination ou un message publicitaire. Si l’étude nécessite un autre type de données, modifiez les requêtes ou utilisez la route documentée correspondante. Avant d’adapter le pipeline, consultez la documentation de TikTok API pour vérifier les paramètres ; les informations sur le produit et l’accès à la démonstration figurent sur la page de TikTok Scraper API.
Cette approche répond à la question initiale : transformer la recherche sur TikTok en un processus d’étude reproductible. Le script collecte les vidéos effectivement renvoyées, en conserve la provenance et les instantanés, tandis qu’une personne ou un classificateur vérifiable transforme leur contenu en hypothèses sur la demande. L’équipe dispose d’une base pour prendre ses prochaines décisions, tout en préservant la distinction entre les indices publics liés au contenu et les résultats commerciaux confirmés.