Un rastreador de campañas UGC de TikTok busca videos usando el hashtag de su campaña a través de la API de búsqueda de TikTok, recopila identificadores de creadores y estadísticas de participación, y almacena instantáneas diarias para medir el alcance de la campaña a lo largo del tiempo.
Requisitos previos
- Python 3.9+
- Clave API de Scavio con acceso a TikTok
- SQLite (stdlib)
Guia paso a paso
Paso 1: Buscar vídeos de TikTok por hashtag de campaña
Utilice búsqueda/videos con su hashtag como consulta para encontrar todas las publicaciones UGC.
import requests
API_KEY = "your-scavio-api-key"
CAMPAIGN_HASHTAG = "#YourCampaign2026"
def get_campaign_videos(hashtag: str, max_pages: int = 5) -> list:
tag = hashtag.lstrip("#")
all_videos = []
cursor = 0
for _ in range(max_pages):
r = requests.post(
"https://api.scavio.dev/api/v1/tiktok/search/videos",
json={"query": f"#{tag}", "cursor": cursor, "count": 30},
headers={"Authorization": f"Bearer {API_KEY}"},
timeout=20
)
r.raise_for_status()
data = r.json()
batch = data.get("videos", [])
if not batch:
break
all_videos.extend(batch)
if not data.get("has_more"):
break
cursor = data.get("cursor", 0)
return all_videosPaso 2: Extraer datos del creador y de participación
Analice cada vídeo para conocer el identificador del creador, el recuento de vistas, el recuento de me gusta y el recuento de acciones compartidas.
def extract_video_stats(videos: list) -> list:
records = []
for v in videos:
stats = v.get("stats", {})
records.append({
"video_id": v.get("id"),
"creator": v.get("author", {}).get("uniqueId"),
"description": v.get("desc", "")[:100],
"plays": stats.get("playCount", 0),
"likes": stats.get("diggCount", 0),
"comments": stats.get("commentCount", 0),
"shares": stats.get("shareCount", 0)
})
return recordsPaso 3: Almacenar en SQLite y calcular totales
Guarde instantáneas diarias y sume la participación de toda la campaña.
import sqlite3
from datetime import date
def init_db(path="ugc_tracker.db"):
conn = sqlite3.connect(path)
conn.execute("""
CREATE TABLE IF NOT EXISTS ugc_posts (
date TEXT, video_id TEXT, creator TEXT,
plays INTEGER, likes INTEGER, comments INTEGER, shares INTEGER,
PRIMARY KEY (date, video_id)
)
""")
conn.commit()
return conn
def save_and_summarize(conn, records: list) -> dict:
today = str(date.today())
for r in records:
conn.execute("INSERT OR REPLACE INTO ugc_posts VALUES (?,?,?,?,?,?,?)",
(today, r["video_id"], r["creator"], r["plays"], r["likes"], r["comments"], r["shares"]))
conn.commit()
totals = {"posts": len(records), "total_plays": sum(r["plays"] for r in records),
"total_likes": sum(r["likes"] for r in records),
"unique_creators": len(set(r["creator"] for r in records))}
return totalsEjemplo en Python
import requests
import sqlite3
from datetime import date
API_KEY = "your-scavio-api-key"
CAMPAIGN_HASHTAG = "YourCampaign2026"
def get_campaign_videos(hashtag, max_pages=5):
all_videos, cursor = [], 0
for _ in range(max_pages):
r = requests.post("https://api.scavio.dev/api/v1/tiktok/search/videos",
json={"query": f"#{hashtag}", "cursor": cursor, "count": 30},
headers={"Authorization": f"Bearer {API_KEY}"}, timeout=20)
r.raise_for_status()
data = r.json()
batch = data.get("videos", [])
if not batch: break
all_videos.extend(batch)
if not data.get("has_more"): break
cursor = data.get("cursor", 0)
return all_videos
def extract_stats(videos):
return [{"video_id": v.get("id"), "creator": v.get("author",{}).get("uniqueId"),
"plays": v.get("stats",{}).get("playCount",0),
"likes": v.get("stats",{}).get("diggCount",0),
"shares": v.get("stats",{}).get("shareCount",0)} for v in videos]
def init_db(path="ugc_tracker.db"):
conn = sqlite3.connect(path)
conn.execute("CREATE TABLE IF NOT EXISTS ugc (date TEXT, video_id TEXT, creator TEXT, plays INTEGER, likes INTEGER, shares INTEGER, PRIMARY KEY (date, video_id))")
conn.commit()
return conn
def run_tracker():
conn = init_db()
videos = get_campaign_videos(CAMPAIGN_HASHTAG)
records = extract_stats(videos)
today = str(date.today())
for r in records:
conn.execute("INSERT OR REPLACE INTO ugc VALUES (?,?,?,?,?,?)",
(today, r["video_id"], r["creator"], r["plays"], r["likes"], r["shares"]))
conn.commit()
total_plays = sum(r["plays"] for r in records)
unique_creators = len(set(r["creator"] for r in records))
top = sorted(records, key=lambda x: x["plays"], reverse=True)[:3]
print(f"Campaign #{CAMPAIGN_HASHTAG} — {today}")
print(f"Posts: {len(records)} | Creators: {unique_creators} | Total plays: {total_plays:,}")
print("\nTop posts:")
for r in top:
print(f" @{r['creator']}: {r['plays']:,} plays")
if __name__ == "__main__":
run_tracker()Ejemplo en JavaScript
const API_KEY = 'your-scavio-api-key';
const HASHTAG = 'YourCampaign2026';
async function getCampaignVideos(hashtag, maxPages = 5) {
const videos = [];
let cursor = 0;
for (let i = 0; i < maxPages; i++) {
const res = await fetch('https://api.scavio.dev/api/v1/tiktok/search/videos', {
method: 'POST',
headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${API_KEY}` },
body: JSON.stringify({ query: `#${hashtag}`, cursor, count: 30 })
});
const data = await res.json();
const batch = data.videos ?? [];
if (!batch.length) break;
videos.push(...batch);
if (!data.has_more) break;
cursor = data.cursor ?? 0;
}
return videos;
}
const videos = await getCampaignVideos(HASHTAG);
const totalPlays = videos.reduce((s, v) => s + (v.stats?.playCount ?? 0), 0);
const creators = new Set(videos.map(v => v.author?.uniqueId)).size;
console.log(`Posts: ${videos.length} | Creators: ${creators} | Total plays: ${totalPlays.toLocaleString()}`);Salida esperada
Campaign #YourCampaign2026 - 2026-05-22
Posts: 147 | Creators: 89 | Total plays: 4,821,032
Top posts:
@topcreatora: 892,441 plays
@creatorb: 441,209 plays
@creatorc: 312,887 plays