Les faux abonnés et l'engagement gonflé coûtent des millions aux marques en dépenses d'influenceurs gaspillées. Ce scoreur analyse les schémas de performance vidéo d'un créateur TikTok pour estimer la qualité de son audience. Il vérifie la cohérence de l'engagement, le ratio vues/j'aime et la qualité des commentaires. Chaque analyse de créateur coûte 0,005 $.
Prérequis
- Python 3.8+
- bibliothèque requests
- Une clé API Scavio depuis scavio.dev
- Noms d'utilisateur des créateurs TikTok à évaluer
Parcours
Étape 1: Collecter les données de performance des créateurs
Extraire plusieurs vidéos pour analyser les schémas d'engagement dans le temps.
import os, requests, json, statistics
from datetime import datetime
API_KEY = os.environ['SCAVIO_API_KEY']
TH = {'Authorization': f'Bearer {API_KEY}', 'Content-Type': 'application/json'}
def get_creator_stats(username):
data = requests.post('https://api.scavio.dev/api/v1/tiktok/user/videos',
headers=TH, json={'username': username}).json()
videos = data.get('videos', data.get('data', {}).get('videos', []))
stats = []
for v in videos:
s = v.get('stats', {})
plays = s.get('playCount', 0)
likes = s.get('diggCount', 0)
comments = s.get('commentCount', 0)
shares = s.get('shareCount', 0)
if plays > 0:
stats.append({
'plays': plays,
'likes': likes,
'comments': comments,
'shares': shares,
'like_rate': likes / plays,
'comment_rate': comments / plays,
'share_rate': shares / plays,
'engagement_rate': (likes + comments + shares) / plays,
})
return stats
CREATORS = ['charlidamelio', 'khaby.lame', 'addisonre']
creator_data = {}
for username in CREATORS:
stats = get_creator_stats(username)
creator_data[username] = stats
if stats:
avg_plays = statistics.mean(s['plays'] for s in stats)
avg_er = statistics.mean(s['engagement_rate'] for s in stats)
print(f' @{username:20} | {len(stats)} videos | Avg plays: {avg_plays:,.0f} | Avg ER: {avg_er*100:.1f}%')
print(f'\nCost: ${len(CREATORS) * 0.005:.3f}')Étape 2: Calculer les signaux de qualité d'audience
Analyser les schémas d'engagement pour détecter les problèmes de qualité comme les faux abonnés.
def score_audience_quality(username, stats):
if not stats or len(stats) < 3:
return {'username': username, 'score': 0, 'reason': 'Insufficient data'}
signals = {}
# 1. Engagement consistency (real audiences have some variance, bots are too consistent)
er_values = [s['engagement_rate'] for s in stats]
er_cv = statistics.stdev(er_values) / statistics.mean(er_values) if statistics.mean(er_values) > 0 else 0
# Healthy CV is 0.3-0.8. Too low = bot-like, too high = bought views
if 0.2 <= er_cv <= 1.0:
signals['consistency'] = 25
elif er_cv < 0.2:
signals['consistency'] = 5 # Suspiciously consistent
else:
signals['consistency'] = 10 # Too erratic
# 2. Like-to-view ratio (healthy: 3-15%)
avg_like_rate = statistics.mean(s['like_rate'] for s in stats)
if 0.03 <= avg_like_rate <= 0.15:
signals['like_ratio'] = 25
elif avg_like_rate < 0.01:
signals['like_ratio'] = 5 # Views but no likes = bought views
else:
signals['like_ratio'] = 15
# 3. Comment-to-like ratio (healthy: 1-5%)
avg_comment_to_like = statistics.mean(s['comments'] / s['likes'] if s['likes'] > 0 else 0 for s in stats)
if 0.01 <= avg_comment_to_like <= 0.05:
signals['comment_quality'] = 25
elif avg_comment_to_like < 0.005:
signals['comment_quality'] = 5 # Likes but no comments = suspicious
else:
signals['comment_quality'] = 15
# 4. Share rate (real engagement drives shares)
avg_share_rate = statistics.mean(s['share_rate'] for s in stats)
signals['share_quality'] = min(25, int(avg_share_rate * 2500))
total = sum(signals.values())
return {
'username': username,
'score': total,
'signals': signals,
'avg_er': statistics.mean(er_values),
'er_cv': er_cv,
'avg_like_rate': avg_like_rate,
}
print(f'\n=== Audience Quality Scores ===')
scores = []
for username, stats in creator_data.items():
result = score_audience_quality(username, stats)
scores.append(result)
grade = 'A' if result['score'] >= 80 else 'B' if result['score'] >= 60 else 'C' if result['score'] >= 40 else 'F'
print(f' @{username:20} | Score: {result["score"]:3}/100 | Grade: {grade}')
if result.get('signals'):
for signal, value in result['signals'].items():
print(f' {signal:20} {value:3}/25')Étape 3: Générer un rapport de qualité d'audience
Compiler les scores dans un rapport de comparaison pour la sélection d'influenceurs.
def audience_quality_report(scores):
print(f'\n{"=" * 60}')
print(f' TIKTOK AUDIENCE QUALITY REPORT')
print(f' Date: {datetime.now().strftime("%Y-%m-%d")}')
print(f'{"=" * 60}')
scores.sort(key=lambda x: x['score'], reverse=True)
for i, s in enumerate(scores, 1):
grade = 'A' if s['score'] >= 80 else 'B' if s['score'] >= 60 else 'C' if s['score'] >= 40 else 'F'
status = 'RECOMMENDED' if grade in ['A', 'B'] else 'CAUTION' if grade == 'C' else 'AVOID'
print(f'\n {i}. @{s["username"]} - Grade {grade} ({s["score"]}/100) - {status}')
if s.get('avg_er'):
print(f' Engagement Rate: {s["avg_er"]*100:.1f}%')
print(f' Engagement Variance: {s.get("er_cv", 0):.2f} (0.3-0.8 is healthy)')
print(f' Like Rate: {s.get("avg_like_rate", 0)*100:.1f}% (3-15% is healthy)')
# Summary
recommended = sum(1 for s in scores if s['score'] >= 60)
caution = sum(1 for s in scores if 40 <= s['score'] < 60)
avoid = sum(1 for s in scores if s['score'] < 40)
print(f'\n Summary:')
print(f' Recommended: {recommended}')
print(f' Caution: {caution}')
print(f' Avoid: {avoid}')
print(f'\n Cost: ${len(scores) * 0.005:.3f}')
print(f' vs. HypeAuditor: $299/mo for audience quality reports')
audience_quality_report(scores)Exemple Python
import os, requests, statistics
TH = {'Authorization': f'Bearer {os.environ["SCAVIO_API_KEY"]}', 'Content-Type': 'application/json'}
def quality_score(username):
data = requests.post('https://api.scavio.dev/api/v1/tiktok/user/videos',
headers=TH, json={'username': username}).json()
videos = data.get('videos', data.get('data', {}).get('videos', []))
ers = [(v.get('stats', {}).get('diggCount', 0) / max(v.get('stats', {}).get('playCount', 1), 1)) for v in videos]
avg = statistics.mean(ers) if ers else 0
print(f'@{username}: Avg like rate {avg*100:.1f}%')
quality_score('charlidamelio')
print('Cost: $0.005')Exemple JavaScript
const TH = { 'Authorization': `Bearer ${process.env.SCAVIO_API_KEY}`, 'Content-Type': 'application/json' };
const data = await fetch('https://api.scavio.dev/api/v1/tiktok/user/videos', {
method: 'POST', headers: TH, body: JSON.stringify({ username: 'charlidamelio' })
}).then(r => r.json());
const videos = data.videos || data.data?.videos || [];
const avgER = videos.reduce((s, v) => s + (v.stats?.diggCount || 0) / Math.max(v.stats?.playCount || 1, 1), 0) / Math.max(videos.length, 1);
console.log(`Avg like rate: ${(avgER * 100).toFixed(1)}%`);Sortie attendue
@charlidamelio | 15 videos | Avg plays: 3,000,000 | Avg ER: 8.5%
@khaby.lame | 12 videos | Avg plays: 10,000,000 | Avg ER: 6.2%
@addisonre | 10 videos | Avg plays: 2,500,000 | Avg ER: 7.8%
=== Audience Quality Scores ===
@charlidamelio | Score: 82/100 | Grade: A
consistency 22/25
like_ratio 25/25
comment_quality 20/25
share_quality 15/25
============================================================
TIKTOK AUDIENCE QUALITY REPORT
Date: 2026-05-21
============================================================
1. @charlidamelio - Grade A (82/100) - RECOMMENDED
Engagement Rate: 8.5%
Cost: $0.015
vs. HypeAuditor: $299/mo for audience quality reports