Savoir ce que vos concurrents publient sur TikTok et comment leur audience réagit révèle des opportunités à saisir. Ce tutoriel construit un pipeline de surveillance concurrentielle qui suit la fréquence de publication, les thématiques de contenu, les styles de vidéos les plus performants et les indicateurs d'engagement pour une liste de comptes concurrents. Chaque vérification de profil coûte 0,005 $ et chaque récupération de publication coûte 0,005 $ via l'API Scavio TikTok avec authentification par jeton Bearer.
Prérequis
- Python 3.9+ installé
- bibliothèque requests installée
- Une clé API Scavio depuis scavio.dev
- Une liste de noms d'utilisateur TikTok de concurrents
Parcours
Étape 1: Configurer la liste des concurrents et récupérer les profils
Définissez vos concurrents et extrayez leurs statistiques de profil pour établir des indicateurs de base.
import os, requests, json, time
from datetime import datetime
SCAVIO_KEY = os.environ['SCAVIO_API_KEY']
TT_URL = 'https://api.scavio.dev/api/v1/tiktok'
TT_H = {'Authorization': f'Bearer {SCAVIO_KEY}', 'Content-Type': 'application/json'}
COMPETITORS = ['competitor1', 'competitor2', 'competitor3']
def get_competitor_profile(username: str) -> dict:
resp = requests.post(f'{TT_URL}/profile', headers=TT_H,
json={'username': username})
data = resp.json().get('data', {})
stats = data.get('stats', {})
return {
'username': username,
'followers': stats.get('followerCount', 0),
'total_likes': stats.get('heartCount', 0),
'video_count': stats.get('videoCount', 0),
'sec_user_id': data.get('user', {}).get('secUid', ''),
}
for c in COMPETITORS:
profile = get_competitor_profile(c)
print(f'@{c}: {profile["followers"]:,} followers, {profile["video_count"]} videos')
time.sleep(0.3)Étape 2: Récupérer et analyser les habitudes de publication des concurrents
Récupérez les publications récentes de chaque concurrent et analysez la fréquence de publication, les taux d'engagement typiques et les thématiques de contenu.
def analyze_competitor(username: str, sec_user_id: str) -> dict:
resp = requests.post(f'{TT_URL}/user/posts', headers=TT_H,
json={'sec_user_id': sec_user_id, 'count': 30})
posts = resp.json().get('data', {}).get('videos', [])
if not posts:
return {'username': username, 'error': 'No posts found'}
engagement_rates = []
view_counts = []
descriptions = []
for p in posts:
stats = p.get('stats', {})
views = stats.get('playCount', 0)
likes = stats.get('diggCount', 0)
comments = stats.get('commentCount', 0)
if views > 0:
engagement_rates.append((likes + comments) / views)
view_counts.append(views)
descriptions.append(p.get('desc', '').lower())
# Posting frequency
timestamps = sorted([p.get('createTime', 0) for p in posts if p.get('createTime')])
if len(timestamps) >= 2:
days_span = (timestamps[-1] - timestamps[0]) / 86400
posts_per_week = len(timestamps) / max(days_span / 7, 1)
else:
posts_per_week = 0
return {
'username': username,
'posts_analyzed': len(posts),
'avg_engagement': sum(engagement_rates) / len(engagement_rates) if engagement_rates else 0,
'avg_views': sum(view_counts) / len(view_counts) if view_counts else 0,
'posts_per_week': posts_per_week,
'top_video_views': max(view_counts) if view_counts else 0,
}Étape 3: Générer un rapport d'analyse comparative concurrentielle
Compilez toutes les données des concurrents dans un rapport d'analyse comparative qui montre votre position par rapport à eux et identifie les lacunes de contenu.
def competitor_report(competitors: list) -> dict:
results = []
for username in competitors:
profile = get_competitor_profile(username)
time.sleep(0.3)
if profile.get('sec_user_id'):
analysis = analyze_competitor(username, profile['sec_user_id'])
analysis['followers'] = profile['followers']
results.append(analysis)
time.sleep(0.3)
print('Competitor Benchmark Report')
print('=' * 70)
for r in sorted(results, key=lambda x: x.get('avg_views', 0), reverse=True):
print(f' @{r["username"]:15s} | {r["followers"]:>10,} followers | '
f'{r.get("avg_engagement", 0):5.1%} eng | '
f'{r.get("posts_per_week", 0):4.1f}/wk | '
f'{r.get("avg_views", 0):>10,.0f} avg views')
# Averages
avg_eng = sum(r.get('avg_engagement', 0) for r in results) / len(results) if results else 0
avg_freq = sum(r.get('posts_per_week', 0) for r in results) / len(results) if results else 0
print(f'\n Benchmark avg: {avg_eng:.1%} engagement, {avg_freq:.1f} posts/week')
print(f' Cost: ${len(competitors) * 0.010:.3f} ({len(competitors)} competitors x 2 calls)')
return {'results': results, 'avg_engagement': avg_eng, 'avg_frequency': avg_freq}
competitor_report(COMPETITORS)Exemple Python
import os, requests, time
SCAVIO_KEY = os.environ['SCAVIO_API_KEY']
TT_H = {'Authorization': f'Bearer {SCAVIO_KEY}', 'Content-Type': 'application/json'}
def monitor_competitor(username):
resp = requests.post('https://api.scavio.dev/api/v1/tiktok/profile', headers=TT_H,
json={'username': username})
data = resp.json().get('data', {})
stats = data.get('stats', {})
uid = data.get('user', {}).get('secUid', '')
time.sleep(0.3)
resp2 = requests.post('https://api.scavio.dev/api/v1/tiktok/user/posts', headers=TT_H,
json={'sec_user_id': uid, 'count': 10})
posts = resp2.json().get('data', {}).get('videos', [])
views = [v.get('stats', {}).get('playCount', 0) for v in posts]
avg = sum(views) / len(views) if views else 0
print(f'@{username}: {stats.get("followerCount", 0):,} followers, {avg:,.0f} avg views')
for c in ['competitor1', 'competitor2']:
monitor_competitor(c)
time.sleep(0.3)Exemple JavaScript
const SCAVIO_KEY = process.env.SCAVIO_API_KEY;
const TT_H = { Authorization: `Bearer ${SCAVIO_KEY}`, 'Content-Type': 'application/json' };
async function monitorCompetitor(username) {
const profile = await fetch('https://api.scavio.dev/api/v1/tiktok/profile', {
method: 'POST', headers: TT_H, body: JSON.stringify({ username })
}).then(r => r.json());
const stats = profile.data?.stats || {};
const uid = profile.data?.user?.secUid || '';
const posts = await fetch('https://api.scavio.dev/api/v1/tiktok/user/posts', {
method: 'POST', headers: TT_H, body: JSON.stringify({ sec_user_id: uid, count: 10 })
}).then(r => r.json());
const views = (posts.data?.videos || []).map(v => v.stats?.playCount || 0);
const avg = views.length ? views.reduce((a, b) => a + b, 0) / views.length : 0;
console.log(`@${username}: ${(stats.followerCount || 0).toLocaleString()} followers, ${avg.toLocaleString()} avg views`);
}
(async () => { for (const c of ['competitor1', 'competitor2']) { await monitorCompetitor(c); } })();Sortie attendue
Competitor Benchmark Report
======================================================================
@competitor1 | 250,000 followers | 6.2% eng | 4.5/wk | 890,000 avg views
@competitor2 | 180,000 followers | 7.8% eng | 3.2/wk | 650,000 avg views
@competitor3 | 120,000 followers | 5.1% eng | 5.0/wk | 320,000 avg views
Benchmark avg: 6.4% engagement, 4.2 posts/week
Cost: $0.030 (3 competitors x 2 calls)