Los seguidores falsos y el fraude de participación desperdician los presupuestos de marketing de influencers. Detectar falsificaciones en TikTok requiere analizar múltiples señales: ratios de participación-seguidores, patrones de calidad de los comentarios, picos de crecimiento de seguidores y coherencia del contenido. Este tutorial crea un proceso automatizado de detección de fraude utilizando la API Scavio TikTok. Obtiene datos de perfil y videos recientes, ejecuta pruebas estadísticas para detectar anomalías y genera una puntuación de riesgo de fraude. El coste total es de 2 a 3 créditos (entre 0,01 y 0,015 dólares) por creador analizado.
Requisitos previos
- Python 3.9+ instalado
- solicita biblioteca instalada
- Una clave API de Scavio de scavio.dev
- Nombres de usuario de TikTok para analizar
Guia paso a paso
Paso 1: Obtener datos de perfil y participación
Obtenga las estadísticas del perfil del creador y los datos recientes de rendimiento del video. Ambos son necesarios para detectar inconsistencias que indiquen un compromiso falso.
import requests, os
API_KEY = os.environ['SCAVIO_API_KEY']
TIKTOK_URL = 'https://api.scavio.dev/api/v1/tiktok'
def fetch_creator_data(username: str) -> dict:
# Profile
profile_resp = requests.post(f'{TIKTOK_URL}/user/info',
headers={'Authorization': f'Bearer {API_KEY}',
'Content-Type': 'application/json'},
json={'username': username})
profile_data = profile_resp.json().get('data', {})
# Recent videos
videos_resp = requests.post(f'{TIKTOK_URL}/user/posts',
headers={'Authorization': f'Bearer {API_KEY}',
'Content-Type': 'application/json'},
json={'username': username, 'count': 30, 'cursor': 0})
videos = videos_resp.json().get('data', {}).get('videos', [])
stats = profile_data.get('stats', {})
return {
'username': username,
'followers': stats.get('followerCount', 0),
'following': stats.get('followingCount', 0),
'total_likes': stats.get('heartCount', 0),
'video_count': stats.get('videoCount', 0),
'videos': videos
}Paso 2: Verificar anomalías en la tasa de participación
Las cuentas legítimas tienen proporciones predecibles de participación por seguidor. Las cuentas con seguidores falsos muestran una participación anormalmente baja en relación con el número de seguidores.
def check_engagement_ratio(data: dict) -> dict:
followers = max(data['followers'], 1)
videos = data['videos']
if not videos:
return {'flag': 'NO_VIDEOS', 'risk': 50}
avg_likes = sum(v.get('stats', {}).get('diggCount', 0) for v in videos) / len(videos)
avg_plays = sum(v.get('stats', {}).get('playCount', 0) for v in videos) / len(videos)
likes_to_followers = (avg_likes / followers) * 100
plays_to_followers = (avg_plays / followers) * 100
# Normal ranges for TikTok:
# Likes/followers: 1-15% is typical, <0.5% suspicious, >20% suspicious (bought likes)
# Plays/followers: 10-200% is typical, <5% suspicious
engagement_risk = 0
flags = []
if likes_to_followers < 0.5:
engagement_risk += 30
flags.append(f'Very low like ratio: {likes_to_followers:.2f}%')
elif likes_to_followers > 25:
engagement_risk += 20
flags.append(f'Abnormally high like ratio: {likes_to_followers:.2f}%')
if plays_to_followers < 5:
engagement_risk += 25
flags.append(f'Very low play ratio: {plays_to_followers:.2f}%')
return {
'likes_to_followers': round(likes_to_followers, 2),
'plays_to_followers': round(plays_to_followers, 2),
'risk_score': engagement_risk,
'flags': flags
}Paso 3: Analizar la coherencia del compromiso
Las cuentas reales muestran una variación natural en el compromiso. La participación falsa a menudo parece demasiado consistente (me gusta de los bots) o tiene picos extremos (participación comprada).
import statistics
def check_engagement_consistency(data: dict) -> dict:
videos = data['videos']
if len(videos) < 5:
return {'risk_score': 10, 'flags': ['Too few videos to analyze']}
like_counts = [v.get('stats', {}).get('diggCount', 0) for v in videos]
play_counts = [v.get('stats', {}).get('playCount', 0) for v in videos]
flags = []
risk = 0
# Check if engagement is suspiciously uniform
if like_counts and statistics.mean(like_counts) > 0:
cv = statistics.stdev(like_counts) / statistics.mean(like_counts) # coefficient of variation
if cv < 0.1: # Less than 10% variation = suspiciously uniform
risk += 25
flags.append(f'Suspiciously uniform likes (CV={cv:.3f})')
# Check for sudden engagement spikes
if play_counts:
median_plays = statistics.median(play_counts)
spikes = sum(1 for p in play_counts if p > median_plays * 10)
spike_ratio = spikes / len(play_counts)
if spike_ratio > 0.3: # More than 30% of videos have 10x spikes
risk += 20
flags.append(f'{spikes}/{len(play_counts)} videos have 10x play spikes')
# Check likes-to-comments ratio (bots rarely comment)
for v in videos:
s = v.get('stats', {})
likes = s.get('diggCount', 0)
comments = s.get('commentCount', 0)
if likes > 1000 and comments < likes * 0.005: # Less than 0.5% comment rate
risk += 5
flags.append(f'Very low comment ratio on video with {likes} likes')
break # Only flag once
return {'risk_score': min(risk, 50), 'flags': flags}Paso 4: Verifique la proporción de seguidores/seguidores
Las cuentas que siguen un gran número de cuentas en relación con sus seguidores a menudo participaban en esquemas de seguimiento o utilizaban robots de seguimiento.
def check_follow_ratio(data: dict) -> dict:
followers = max(data['followers'], 1)
following = data['following']
ratio = following / followers
flags = []
risk = 0
if followers > 10000 and ratio > 1.0:
risk += 30
flags.append(f'Following > followers ({following:,} / {followers:,})')
elif followers > 10000 and ratio > 0.5:
risk += 15
flags.append(f'High follow ratio: {ratio:.2f}')
# Check if total likes seem inflated relative to video count
if data['video_count'] > 0:
likes_per_video = data['total_likes'] / data['video_count']
expected_likes = followers * 0.05 # 5% of followers per video is generous
if likes_per_video > expected_likes * 5:
risk += 15
flags.append(f'Inflated total likes: {likes_per_video:,.0f}/video vs {expected_likes:,.0f} expected')
return {'follow_ratio': round(ratio, 3), 'risk_score': risk, 'flags': flags}Paso 5: Generar el informe de fraude completo
Combine todas las señales de detección en una evaluación integral del riesgo de fraude con una puntuación de riesgo general y un desglose detallado.
def fraud_report(username: str) -> dict:
data = fetch_creator_data(username)
engagement = check_engagement_ratio(data)
consistency = check_engagement_consistency(data)
follow = check_follow_ratio(data)
total_risk = engagement['risk_score'] + consistency['risk_score'] + follow['risk_score']
all_flags = engagement.get('flags', []) + consistency.get('flags', []) + follow.get('flags', [])
verdict = 'LOW RISK' if total_risk < 20 else 'MEDIUM RISK' if total_risk < 50 else 'HIGH RISK'
report = {
'username': username,
'followers': data['followers'],
'total_risk_score': min(total_risk, 100),
'verdict': verdict,
'engagement_check': engagement,
'consistency_check': consistency,
'follow_check': follow,
'all_flags': all_flags,
'credits_used': 2
}
print(f'@{username}: {verdict} ({total_risk}/100)')
print(f' Followers: {data["followers"]:,}')
for flag in all_flags:
print(f' - {flag}')
return report
# report = fraud_report('suspicious_creator')Ejemplo en Python
import os, requests, statistics
API_KEY = os.environ['SCAVIO_API_KEY']
TT = 'https://api.scavio.dev/api/v1/tiktok'
def tt(endpoint, body):
return requests.post(f'{TT}/{endpoint}',
headers={'Authorization': f'Bearer {API_KEY}', 'Content-Type': 'application/json'},
json=body).json()
def detect_fake(username):
profile = tt('user/info', {'username': username}).get('data', {})
stats = profile.get('stats', {})
followers = stats.get('followerCount', 1)
posts = tt('user/posts', {'username': username, 'count': 20, 'cursor': 0})
videos = posts.get('data', {}).get('videos', [])
avg_likes = sum(v.get('stats', {}).get('diggCount', 0) for v in videos) / max(len(videos), 1)
ratio = (avg_likes / followers) * 100
risk = 'HIGH' if ratio < 0.5 else 'MEDIUM' if ratio < 1.0 else 'LOW'
print(f'@{username}: {risk} RISK (like ratio: {ratio:.2f}%, {followers:,} followers)')
detect_fake('example_creator')Ejemplo en JavaScript
const API_KEY = process.env.SCAVIO_API_KEY;
const TT = 'https://api.scavio.dev/api/v1/tiktok';
async function tt(endpoint, body) {
const r = await fetch(`${TT}/${endpoint}`, {
method: 'POST',
headers: { 'Authorization': `Bearer ${API_KEY}`, 'Content-Type': 'application/json' },
body: JSON.stringify(body)
});
return r.json();
}
async function detectFake(username) {
const profile = await tt('user/info', { username });
const followers = profile.data?.stats?.followerCount || 1;
const posts = await tt('user/posts', { username, count: 20, cursor: 0 });
const videos = posts.data?.videos || [];
const avgLikes = videos.reduce((s, v) => s + (v.stats?.diggCount || 0), 0) / Math.max(videos.length, 1);
const ratio = (avgLikes / followers) * 100;
console.log(`@${username}: ${ratio < 0.5 ? 'HIGH' : ratio < 1 ? 'MED' : 'LOW'} RISK (${ratio.toFixed(2)}%)`);
}
detectFake('example_creator').catch(console.error);Salida esperada
@suspicious_creator: HIGH RISK (72/100)
Followers: 500,000
- Very low like ratio: 0.31%
- Suspiciously uniform likes (CV=0.082)
- Following > followers (520,000 / 500,000)
@legitimate_creator: LOW RISK (8/100)
Followers: 85,000
(no flags)
Credits used: 2 per creator ($0.01)