TikTok est l'une des plus grandes sources de données de vidéos courtes publiques sur le web, et les tendances, hashtags et chiffres d'engagement qu'il expose sont véritablement utiles pour la recherche de marché, la stratégie de contenu et le suivi des tendances. C'est aussi l'une des surfaces les plus difficiles à lire par programmation : les pages se rendent côté client avec JavaScript, la plateforme challenge le trafic automatisé, et une requête HTTP simple vers une URL de recherche ou de profil retourne généralement une coquille quasi vide sans aucune des données visibles dans un navigateur.
Ce guide vous montre comment scraper des données TikTok publiques avec Python d'une façon qui fonctionne réellement, tout en restant strictement dans le domaine public et agrégé. Tout est limité aux résultats de recherche publics, aux fils de hashtags publics et aux vidéos de profils publics : légendes, nombres de likes, commentaires et partages, URLs des vidéos, et dates de publication. Il ne couvre rien derrière une connexion, les comptes privés, ni les données personnelles d'individus. Lisez la section juridique en fin d'article avant de pointer ceci vers quoi que ce soit de réel, et pour un usage en production, préférez l'API officielle de TikTok.
Ce que vous allez construire
Un petit script Python qui prend une URL de recherche ou de hashtag TikTok publique, récupère la page entièrement rendue via la Crawling API avec un token JavaScript, et analyse une poignée de champs publics et agrégés de chaque carte vidéo :
- Légende le texte public affiché sur la carte vidéo.
- Nombres de likes, commentaires et partages les chiffres d'engagement agrégés qu'une carte affiche, et non les personnes derrière.
- URL de la vidéo le permalien public de chaque vidéo.
- Date de publication la date d'upload affichée sur la carte.
- Hashtags les tags publics attachés à chaque vidéo.
Remarquez ce qui est délibérément absent : pas de listes d'abonnés, pas d'identités de commentateurs, pas de contenu de comptes privés, pas de coordonnées. Ce sont des données personnelles d'individus, et leur collecte est hors de portée ici, délibérément. Nous traitons les noms d'utilisateur comme contexte accessoire pour une vidéo publique, pas comme un profil à enrichir.
Pourquoi une requête classique échoue sur TikTok
Demandez une URL de recherche ou de hashtag TikTok avec un client HTTP basique et vous obtenez une réponse techniquement réussie et pratiquement inutile. Le body est une coquille JavaScript : le vrai contenu, les cartes vidéo, les légendes et les comptages, n'apparaît qu'après que les scripts de la page s'exécutent dans un navigateur et récupèrent des données depuis des endpoints internes. En plus de cela, TikTok signale rapidement le trafic automatisé. Les plages d'IP de datacenter, les comportements de navigateur manquants et les patterns de requêtes répétitifs sont challengés ou limités en débit bien avant que le contenu intéressant se charge jamais.
Un scraper TikTok fonctionnel a donc besoin de deux choses dans la même requête : un vrai navigateur qui rend la page, et une adresse IP que la plateforme perçoit comme un visiteur ordinaire. Vous pouvez construire cela vous-même avec un navigateur headless et un pool de proxies résidentiels rotatifs, mais maintenir cette pile opérationnelle représente la majeure partie du travail. La Crawling API regroupe les deux en un seul appel. Vous lui envoyez une URL avec un token JavaScript, elle rend la page derrière une IP résidentielle de confiance, et elle retourne le HTML finalisé que vous pouvez analyser. Pour le contexte plus approfondi, consultez notre guide sur comment crawler des sites JavaScript.
Crawlbase propose deux types de tokens. Le token normal récupère le HTML statique ; le token JavaScript (JS) rend d'abord la page dans un vrai navigateur. TikTok est rendu côté client, donc vous avez besoin du token JS ici. Le token normal retourne la même coquille qu'un simple fetch, sans rien d'utile à en extraire.
Prérequis
Quelques éléments à mettre en place d'abord. Aucun ne prend longtemps.
Notions de base en Python. Vous devez être à l'aise pour exécuter un script et installer des packages avec pip. Si vous débutez avec l'analyse HTML, notre primer sur comment utiliser BeautifulSoup en Python couvre le côté extraction.
Python 3.8 ou supérieur. Confirmez avec python --version et pip --version. Si vous ne l'avez pas, installez-le depuis python.org.
Un compte Crawlbase et un token JS. Inscrivez-vous, ouvrez votre tableau de bord et copiez votre token JavaScript (JS). Vous obtenez jusqu'à 20 000 requêtes gratuites, sans carte bancaire. Traitez le token comme un mot de passe : il authentifie vos requêtes, donc gardez-le hors du contrôle de version.
Configurer le projet
Créez un environnement virtuel isolé, puis installez les bibliothèques dont le scraper a besoin.
python --version python -m venv tiktok_env source tiktok_env/bin/activate pip install crawlbase beautifulsoup4
Sous Windows, activez avec tiktok_env\Scripts\activate au lieu de la ligne source. Deux dépendances font le travail : crawlbase est le client officiel pour la Crawling API, et beautifulsoup4 analyse le HTML retourné pour que vous puissiez extraire des champs individuels par sélecteur.
Étape 1 : récupérer la page rendue
Commencez par obtenir la page finalisée. Importez CrawlingAPI, initialisez-la avec votre token JS et demandez une URL de recherche ou de hashtag publique. TikTok charge le contenu de façon asynchrone, donc passez ajax_wait et page_wait pour laisser la page se stabiliser avant la capture. Vérifiez le statut avant d'analyser pour que les échecs restent visibles plutôt que silencieux.
from crawlbase import CrawlingAPI import urllib.parse api = CrawlingAPI({"token": "YOUR_CRAWLBASE_TOKEN"}) options = { "ajax_wait": "true", "page_wait": 10000, "user_agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36", } def crawl(page_url): response = api.get(page_url, options) if response["headers"]["cb_status"] == "200": return response["body"].decode("utf-8") print(f"Request failed. Crawlbase status: {response['headers']['cb_status']}") return None if __name__ == "__main__": query = urllib.parse.quote("cooking recipes") url = f"https://www.tiktok.com/search/video?q={query}" html = crawl(url) print(html[:500] if html else "No HTML returned")
Les options d'attente sont importantes pour une cible rendue côté client. ajax_wait demande à l'API d'attendre que le contenu asynchrone termine de se charger, et page_wait maintient un délai fixe en millisecondes après le chargement pour que les cartes à rendu tardif apparaissent avant la capture de la page. Dix secondes est un bon point de départ pour TikTok ; augmentez si les cartes reviennent vides. L'exemple interroge un sujet (recettes de cuisine) précisément parce qu'il est impersonnel et public. Exécutez le script et vous devriez voir le vrai balisage de la page, ce qui confirme que le rendu fonctionne avant d'écrire un seul sélecteur.
TikTok nécessite une page rendue derrière une IP de confiance, en un seul appel. La Crawling API prend un token JS, exécute la page dans un vrai navigateur pour que ajax_wait et page_wait aient quelque chose à attendre, fait tourner les IPs résidentielles côté serveur et vous restitue le HTML finalisé, vous évitant d'avoir à gérer une flotte de navigateurs headless et un pool de proxies. Pointez-la sur une requête de recherche publique avec le niveau gratuit d'abord.
Étape 2 : trouver les cartes vidéo dans le listing de recherche
Avec le HTML rendu en main, chargez-le dans BeautifulSoup et localisez le listing de recherche, le conteneur qui regroupe tous les résultats de la page. TikTok marque les éléments clés avec des attributs data-e2e, bien plus stables que ses classes CSS profondément imbriquées et fréquemment renommées. Les résultats de recherche se trouvent sous div[data-e2e='search_video-item-list'], et chaque enfant direct est une carte vidéo.
from bs4 import BeautifulSoup def find_video_cards(html): soup = BeautifulSoup(html, "html.parser") return soup.select("div[data-e2e='search_video-item-list'] > div")
Cela retourne une liste d'éléments de carte. Chaque carte est autonome : la légende, les chiffres d'engagement, le lien de la vidéo, la date de publication et les hashtags se trouvent tous à l'intérieur, donc le reste de l'analyse opère sur une carte à la fois.
Étape 3 : analyser les champs vidéo publics
De chaque carte, extrayez les champs publics et agrégés. La légende se trouve sous data-e2e='search-card-video-caption', le lien de la vidéo sous data-e2e='search_video-item', la date de publication dans un élément dont la classe contient DivTimeTag, et le nombre d'engagements sous data-e2e='search-card-like-container'. Chaque sélecteur ci-dessous est enveloppé pour qu'un élément manquant retourne None au lieu de faire planter l'exécution, car TikTok ne rend pas chaque champ sur chaque carte.
def text_of(card, selector): el = card.select_one(selector) return el.text.strip() if el else None def scrape_video_details(card): link = card.select_one("div[data-e2e='search_video-item'] a") return { "caption": text_of(card, "div[data-e2e='search-card-video-caption'] > div > span"), "video_url": link["href"].strip() if link and link.has_attr("href") else None, "posted_date": text_of(card, "div[class*='DivTimeTag']"), "like_count": text_of(card, "div[data-e2e='search-card-like-container'] > strong"), }
Cela extrait uniquement des champs agrégés et non personnels : le texte de la légende, l'URL publique de la vidéo, la date de publication et le nombre de likes public. Les nombres de likes, commentaires et partages sont des chiffres ; les personnes derrière ne vous appartiennent pas à collecter. Nous ne lisons pas les commentaires individuels ni qui a aimé la vidéo, et cette retenue est ce qui rend le travail défendable.
TikTok modifie son balisage sans préavis, c'est pourquoi ce code s'appuie sur les attributs data-e2e plutôt que sur des classes imbriquées fragiles. Quand un champ revient en None, ré-inspectez la page live dans les outils de développement de votre navigateur et mettez à jour le sélecteur. La maintenance périodique est normale pour tout scraper de production, ce n'est pas le signe que quelque chose est cassé.
Étape 4 : analyser les hashtags
Les hashtags sont des tags publics qui décrivent le sujet d'une vidéo, ce qui en fait le signal agrégé le plus utile de la page pour le travail de tendances. Ils se trouvent dans leurs propres ancres sous data-e2e='search-common-link'. Collectez-les dans une liste par carte.
def scrape_hashtags(card): tags = card.select("a[data-e2e='search-common-link'] > strong") return {"hashtags": [t.text.strip() for t in tags]}
Agréger les hashtags sur une recherche ou un fil de hashtag vous donne une distribution thématique sans toucher un seul individu identifiable. C'est le type d'analyse pour lequel cette approche est conçue : comptages, tendances et co-occurrences plutôt que des profils.
Étape 5 : tout assembler
Câblez maintenant la récupération et l'analyse dans un script fonctionnel. Il récupère une page de recherche publique, parcourt chaque carte vidéo, fusionne les champs vidéo avec les hashtags et affiche une liste JSON propre.
from crawlbase import CrawlingAPI from bs4 import BeautifulSoup import urllib.parse import json api = CrawlingAPI({"token": "YOUR_CRAWLBASE_TOKEN"}) options = { "ajax_wait": "true", "page_wait": 10000, "user_agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36", } def crawl(page_url): response = api.get(page_url, options) if response["headers"]["cb_status"] == "200": return response["body"].decode("utf-8") print(f"Request failed. Crawlbase status: {response['headers']['cb_status']}") return None def text_of(card, selector): el = card.select_one(selector) return el.text.strip() if el else None def scrape_video_details(card): link = card.select_one("div[data-e2e='search_video-item'] a") return { "caption": text_of(card, "div[data-e2e='search-card-video-caption'] > div > span"), "video_url": link["href"].strip() if link and link.has_attr("href") else None, "posted_date": text_of(card, "div[class*='DivTimeTag']"), "like_count": text_of(card, "div[data-e2e='search-card-like-container'] > strong"), } def scrape_hashtags(card): tags = card.select("a[data-e2e='search-common-link'] > strong") return {"hashtags": [t.text.strip() for t in tags]} def scrape_search(url): html = crawl(url) if not html: return [] soup = BeautifulSoup(html, "html.parser") cards = soup.select("div[data-e2e='search_video-item-list'] > div") results = [] for card in cards: video = scrape_video_details(card) video.update(scrape_hashtags(card)) results.append(video) return results def main(): query = urllib.parse.quote("cooking recipes") url = f"https://www.tiktok.com/search/video?q={query}" results = scrape_search(url) print(json.dumps(results, indent=2, ensure_ascii=False)) if __name__ == "__main__": main()
Le même script fonctionne pour un fil de hashtag public : remplacez l'URL de recherche par une URL de hashtag telle que https://www.tiktok.com/tag/cooking et ajustez le sélecteur de carte si la structure de la page diffère. La forme de la sortie reste la même, ce qui est l'intérêt de garder l'analyse sur une carte à la fois.
À quoi ressemble la sortie
Exécutez le script complet et vous obtenez un enregistrement propre des champs publics par vidéo, prêt à écrire en JSON, CSV ou dans une base de données.
[ { "caption": "Crispy potato snacks recipe", "video_url": "https://www.tiktok.com/@artofcooking.example/video/7344763014572182789", "posted_date": "3-10", "like_count": "8.7M", "hashtags": ["#potatosnacks", "#snacks", "#foryou", "#fyp"] }, { "caption": "Crispy potato bread rolls", "video_url": "https://www.tiktok.com/@recipesoftheworld.example/video/7155082128521186587", "posted_date": "2022-10-16", "like_count": "6.6M", "hashtags": ["#breadroll", "#snacks", "#foodie", "#streetfood"] } ]
Les comptages arrivent comme des chaînes d'affichage telles que 8.7M plutôt que des entiers bruts, car c'est ce que TikTok rend. Si vous en avez besoin comme nombres pour l'agrégation, normalisez-les dans une petite étape de post-traitement (développez les suffixes K et M) avant de les stocker.
Gérer la pagination
TikTok utilise la pagination par défilement : de nouvelles cartes se chargent à mesure que l'utilisateur fait défiler vers le bas plutôt que sur des pages numérotées. La Crawling API peut simuler ce défilement pour vous. Ajoutez scroll défini à true, et optionnellement scroll_interval pour contrôler le temps d'attente entre les défilements (en millisecondes). Cela charge plus de cartes dans le HTML avant qu'il soit retourné, donc une seule requête donne un ensemble de résultats plus profond.
options = { "ajax_wait": "true", "page_wait": 10000, "scroll": "true", "scroll_interval": 10000, "user_agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36", }
Gardez scroll_interval généreux. Un défilement agressif sur une cible fortement défendue est le moyen le plus rapide de déclencher une limite de débit. Récupérez un échantillon raisonnable et arrêtez plutôt que d'essayer de faire défiler un fil entier en une seule exécution.
Sauvegarder en CSV
Une fois les enregistrements obtenus, les écrire en CSV facilite leur chargement dans un tableur ou un notebook pour l'analyse agrégée. Aplatissez la liste des hashtags en une seule chaîne délimitée pour que chaque ligne reste sur une ligne.
import csv def save_to_csv(rows, filename): fieldnames = ["caption", "video_url", "posted_date", "like_count", "hashtags"] with open(filename, "w", newline="", encoding="utf-8") as f: writer = csv.DictWriter(f, fieldnames=fieldnames) writer.writeheader() for row in rows: row = {**row, "hashtags": " ".join(row.get("hashtags", []))} writer.writerow(row)
Appelez save_to_csv(results, "tiktok_data.csv") avec la liste du script principal. Vous disposez maintenant d'un tableau ordonné de métadonnées vidéo publiques que vous pouvez analyser pour les tendances sans stocker quoi que ce soit de personnel.
Rester non bloqué
Même avec le rendu géré par la Crawling API, TikTok surveille le trafic ressemblant à un scraper. Quelques habitudes maintiennent une exécution saine, et elles s'appliquent à toute cible difficile et fortement défendue.
- Cadencez vos requêtes. Marteler les pages en boucle serrée est le moyen le plus rapide d'être limité en débit. Ajoutez de vrais délais entre les requêtes et résistez à l'envie de paralléliser agressivement.
- Misez sur la rotation. Un pool d'IPs résidentielles répartit les requêtes sur de nombreuses adresses d'utilisateurs réels pour qu'aucune seule ne déclenche une limite de débit. La Crawling API s'en charge pour vous ; si vous construisez votre propre stack, c'est la partie à maîtriser.
- Lisez les codes de statut. Une exécution qui commence à retourner des challenges ou des erreurs vous signale que le débit actuel ou le niveau d'IP n'est plus suffisant. Ralentissez plutôt que de forcer davantage.
- Gardez le volume bas et les cibles variées. La recherche de tendances agrégée ne nécessite pas de crawler l'historique entier d'un hashtag. Échantillonnez ce dont vous avez besoin et arrêtez.
Pour le guide complet, consultez comment scraper des sites web sans se faire bloquer. Si vous souhaitez uniquement le texte d'engagement public plutôt que les métadonnées vidéo, notre guide sur comment scraper les commentaires TikTok couvre cette surface, et si vous préférez choisir un outil prêt à l'emploi, notre comparatif des meilleurs scrapers TikTok compare les options.
Est-il légal de scraper TikTok ?
C'est la section à lire avant d'écrire du code de production. Les Conditions d'utilisation de TikTok restreignent l'accès automatisé et la collecte de données, et le scraping peut aller à l'encontre de ces conditions quel que soit le soin apporté à vos outils. Aucun code ci-dessus ne change cela ; il rend simplement la partie technique fonctionnelle. Lisez les Conditions d'utilisation de TikTok et son fichier robots.txt, respectez les limites de débit que ces signaux impliquent, et traitez les deux comme la frontière de ce que vous collectez. Le scraping est une zone grise juridique qui tourne nettement selon les données que vous prenez et ce que vous en faites, donc quand un projet est commercial ou à grande échelle, obtenez votre propre conseil juridique.
Les règles honnêtes et restrictives à respecter. Collectez uniquement des données publiques et agrégées : légendes publiques, nombres de likes, commentaires et partages publics, URLs de vidéos publiques, dates de publication et hashtags que quiconque peut voir sans se connecter. Ne scrapez jamais de comptes privés, de contenu derrière connexion, de messages directs ou de listes d'abonnés. Ne construisez pas de profils d'individus identifiables : traitez les noms d'utilisateur, les pseudonymes et les commentaires écrits par les utilisateurs comme des données personnelles, agrégez autant que possible (comptages, tendances, distributions de hashtags), et ne republiez pas le contenu d'une personne lié à son identité. Quand des données personnelles sont impliquées, les lois sur la confidentialité comme le RGPD et le CCPA s'appliquent : vous avez besoin d'une base légale pour les traiter et devez honorer les demandes de suppression. Ce sont des lignes rouges, et ce guide reste du côté agrégé et public de toutes par conception.
Pour tout usage réel ou commercial, le bon outil est l'API officielle TikTok. TikTok propose des API pour développeurs pour un accès sanctionné au contenu et aux métriques, avec une structure sur laquelle vous pouvez compter et des conditions dans lesquelles vous pouvez rester. Cet article est un tutoriel technique limité étroitement aux données publiques et agrégées. Ce n'est pas une approbation de la collecte massive de données personnelles, et il ne couvre rien derrière une connexion. Si votre projet a besoin de plus qu'un petit échantillon de champs publics, l'API officielle ou un accord de données formel est la bonne voie, pas un scraper plus sophistiqué.
Points clés
- TikTok est rendu côté client et défendu contre les bots. Une requête simple retourne une coquille vide, vous devez donc rendre la page avant de l'analyser.
-
Le rendu et une IP de confiance appartiennent à un seul appel. La Crawling API avec un token JS fait les deux ;
ajax_waitetpage_waitcontrôlent le temps d'attente du contenu, etscrollgère le fil infini de TikTok. -
Analysez des signaux stables. Les attributs
data-e2ede TikTok sont bien plus durables que ses classes imbriquées fréquemment renommées. - Agrégats publics uniquement. Récupérez les légendes, les nombres de likes, commentaires et partages, les URLs de vidéos, les dates de publication et les hashtags ; jamais de contenu privé, de listes d'abonnés ou de profils d'individus.
- Cadencez, faites tourner et préférez l'API officielle. Gardez le volume bas, misez sur la rotation résidentielle et utilisez l'API officielle de TikTok pour tout usage réel ou commercial.
Foire aux questions
Pourquoi une requête simple ne retourne-t-elle aucune donnée depuis TikTok ?
Parce que TikTok rend son contenu de recherche, de hashtag et de profil côté client avec JavaScript. Le HTML initial est une coquille qui ne se remplit qu'après que les scripts de la page s'exécutent dans un navigateur, donc une requête HTTP brute retourne un body quasi vide. Pour obtenir des données publiques réelles, vous devez d'abord rendre la page, ce que le token JS de la Crawling API gère pour vous.
Ai-je besoin du token normal ou du token JS pour TikTok ?
Le token JS. Le token normal récupère le HTML statique, qui sur TikTok est la même coquille vide qu'une requête simple retourne. Le token JS rend la page dans un vrai navigateur avant de restituer le HTML, donc les cartes vidéo publiques sont présentes quand BeautifulSoup les analyse.
Quelles données TikTok est-il sûr de scraper ?
Uniquement des données publiques et agrégées : légendes publiques, nombres de likes, commentaires et partages publics sous forme de chiffres, URLs de vidéos publiques, dates de publication et hashtags que quiconque peut voir sans se connecter. Les comptes privés, le contenu derrière connexion, les messages directs, les listes d'abonnés et les identités ou contenus d'individus sont hors limites. Ce sont des données personnelles, et leur collecte va à l'encontre des conditions de TikTok et, dans de nombreux endroits, de la législation sur la confidentialité.
Comment gérer le défilement infini de TikTok ?
Définissez l'option scroll de la Crawling API à true et ajustez scroll_interval pour contrôler le temps d'attente entre les défilements. L'API simule le défilement vers le bas de la page pour que plus de cartes vidéo se chargent dans le HTML avant qu'il soit retourné. Gardez l'intervalle généreux et récupérez un échantillon raisonnable plutôt que d'essayer de faire défiler un fil entier en une seule requête.
Devrais-je utiliser l'API officielle TikTok ou scraper le site ?
Pour tout usage réel, continu ou commercial, utilisez l'API officielle TikTok. C'est la voie sanctionnée, elle fournit une structure fiable et vous maintient dans les conditions de TikTok. Scraper un petit échantillon de champs publics et agrégés avec l'approche présentée ici convient à la recherche légère de données publiques sans accès API en place, à condition de respecter les conditions, le robots.txt et les limites de débit.
Comment éviter d'être bloqué en scrapant TikTok ?
Gardez votre taux de requêtes par IP bas, ajoutez de vrais délais entre les requêtes, variez vos cibles plutôt que de crawler l'historique complet d'un hashtag, et routez via des IPs résidentielles rotatives pour qu'aucune adresse unique ne déclenche une limite de débit. La Crawling API gère la rotation et un pool d'IPs de confiance pour vous. Surveillez les codes de statut et ralentissez dès que vous commencez à voir des challenges.
Crawlez n'importe quel site à grande échelle, sans combattre l'infrastructure.
Crawlbase gère les proxies, les empreintes et les CAPTCHA afin que votre équipe livre des pipelines de données au lieu de maintenir la plomberie de crawl. 1 000 requêtes gratuites, sans carte requise.
