Las discusiones de Reddit contienen opiniones sin filtrar sobre productos, marcas e industrias que las encuestas y los sitios de reseñas pasan por alto. Hacer un seguimiento manual de las opiniones en los subreddits no es práctico: los hilos se mueven rápidamente y abarcan cientos de comunidades. Este tutorial crea un agente de Python que utiliza la API de Scavio para buscar en Reddit publicaciones relacionadas con la marca, aplica un clasificador de opiniones simple basado en palabras clave y agrega los resultados en un informe diario con puntuación de opinión general, hilos positivos principales, hilos negativos principales y preocupaciones de tendencia. El enfoque no utiliza modelos de aprendizaje automático, solo puntuación de palabras clave ponderadas por expresiones regulares que se ejecuta instantáneamente y no cuesta nada más allá de las llamadas a la API.
Requisitos previos
- Python 3.8 o superior instalado
- solicita biblioteca instalada
- Una clave API de Scavio de scavio.dev
- Palabras clave de marca o nombres de productos para realizar un seguimiento
Guia paso a paso
Paso 1: Definir palabras clave de marca y léxico de sentimientos
Configure los términos de marca a buscar y un léxico de palabras clave ponderado simple para la clasificación de sentimientos. Las palabras positivas y negativas tienen cada una una puntuación.
BRAND_QUERIES = [
"scavio api",
"scavio search",
"scavio mcp"
]
POSITIVE_WORDS = ["love", "great", "fast", "reliable", "cheap", "easy", "best", "solid", "recommend", "impressed"]
NEGATIVE_WORDS = ["slow", "expensive", "broken", "hate", "worst", "terrible", "buggy", "unreliable", "scam", "overpriced"]Paso 2: Obtenga publicaciones de Reddit a través de la API de Scavio
Busque en Reddit a través del punto final de Scavio usando el parámetro de plataforma. Recopile el título de la publicación, el fragmento, el enlace y el subreddit de cada resultado.
import os
import requests
API_KEY = os.environ.get("SCAVIO_API_KEY", "your_scavio_api_key")
def search_reddit(query: str) -> list[dict]:
r = requests.post(
"https://api.scavio.dev/api/v1/search",
headers={"x-api-key": API_KEY},
json={"query": query, "platform": "reddit"}
)
r.raise_for_status()
return r.json().get("organic_results", [])Paso 3: Puntuación de sentimiento para cada publicación
Aplique el léxico de palabras clave al título y fragmento de cada publicación. Sume las visitas positivas y negativas para producir una puntuación de sentimiento neta por publicación.
def score_sentiment(text: str) -> dict:
text_lower = text.lower()
pos = sum(1 for w in POSITIVE_WORDS if w in text_lower)
neg = sum(1 for w in NEGATIVE_WORDS if w in text_lower)
net = pos - neg
if net > 0:
label = "positive"
elif net < 0:
label = "negative"
else:
label = "neutral"
return {"positive": pos, "negative": neg, "net": net, "label": label}
def analyze_post(post: dict) -> dict:
text = f"{post.get('title', '')} {post.get('snippet', '')}"
sentiment = score_sentiment(text)
return {
"title": post.get("title", ""),
"link": post.get("link", ""),
"subreddit": post.get("source", ""),
"sentiment": sentiment
}Paso 4: Generar el informe de sentimiento diario
Agregue sentimientos en todas las publicaciones, identifique los principales temas positivos y negativos y escriba un informe resumido.
import json
from datetime import date
def generate_report(brand_queries: list[str]) -> dict:
all_posts = []
for query in brand_queries:
results = search_reddit(query)
analyzed = [analyze_post(p) for p in results]
all_posts.extend(analyzed)
total = len(all_posts)
positive = [p for p in all_posts if p["sentiment"]["label"] == "positive"]
negative = [p for p in all_posts if p["sentiment"]["label"] == "negative"]
neutral = [p for p in all_posts if p["sentiment"]["label"] == "neutral"]
report = {
"date": str(date.today()),
"total_posts": total,
"positive": len(positive),
"negative": len(negative),
"neutral": len(neutral),
"sentiment_ratio": round(len(positive) / total, 2) if total else 0,
"top_positive": sorted(positive, key=lambda p: p["sentiment"]["net"], reverse=True)[:3],
"top_negative": sorted(negative, key=lambda p: p["sentiment"]["net"])[:3]
}
with open(f"reddit_sentiment_{report['date']}.json", "w") as f:
json.dump(report, f, indent=2)
print(f"Report: {total} posts, {len(positive)} positive, {len(negative)} negative")
return report
generate_report(BRAND_QUERIES)Ejemplo en Python
import os
import json
import requests
from datetime import date
API_KEY = os.environ.get("SCAVIO_API_KEY", "your_scavio_api_key")
ENDPOINT = "https://api.scavio.dev/api/v1/search"
POSITIVE = ["love", "great", "fast", "reliable", "cheap", "easy", "best", "solid", "recommend", "impressed"]
NEGATIVE = ["slow", "expensive", "broken", "hate", "worst", "terrible", "buggy", "unreliable", "scam", "overpriced"]
def search_reddit(query: str) -> list[dict]:
r = requests.post(
ENDPOINT,
headers={"x-api-key": API_KEY},
json={"query": query, "platform": "reddit"}
)
r.raise_for_status()
return r.json().get("organic_results", [])
def score(text: str) -> dict:
t = text.lower()
pos = sum(1 for w in POSITIVE if w in t)
neg = sum(1 for w in NEGATIVE if w in t)
net = pos - neg
label = "positive" if net > 0 else "negative" if net < 0 else "neutral"
return {"pos": pos, "neg": neg, "net": net, "label": label}
def track_sentiment(queries: list[str]) -> dict:
posts = []
for q in queries:
for result in search_reddit(q):
text = f"{result.get('title', '')} {result.get('snippet', '')}"
posts.append({
"title": result.get("title", ""),
"link": result.get("link", ""),
"sentiment": score(text)
})
total = len(posts)
pos_count = sum(1 for p in posts if p["sentiment"]["label"] == "positive")
neg_count = sum(1 for p in posts if p["sentiment"]["label"] == "negative")
report = {
"date": str(date.today()),
"total": total,
"positive": pos_count,
"negative": neg_count,
"neutral": total - pos_count - neg_count,
"ratio": round(pos_count / total, 2) if total else 0,
"top_positive": sorted([p for p in posts if p["sentiment"]["label"] == "positive"],
key=lambda x: x["sentiment"]["net"], reverse=True)[:3],
"top_negative": sorted([p for p in posts if p["sentiment"]["label"] == "negative"],
key=lambda x: x["sentiment"]["net"])[:3]
}
output = f"reddit_sentiment_{report['date']}.json"
with open(output, "w") as f:
json.dump(report, f, indent=2)
print(f"{total} posts: {pos_count} positive, {neg_count} negative")
return report
if __name__ == "__main__":
track_sentiment(["scavio api", "scavio search"])Ejemplo en JavaScript
const fs = require("fs");
const API_KEY = process.env.SCAVIO_API_KEY || "your_scavio_api_key";
const ENDPOINT = "https://api.scavio.dev/api/v1/search";
const POSITIVE = ["love", "great", "fast", "reliable", "cheap", "easy", "best", "solid", "recommend"];
const NEGATIVE = ["slow", "expensive", "broken", "hate", "worst", "terrible", "buggy", "unreliable"];
async function searchReddit(query) {
const res = await fetch(ENDPOINT, {
method: "POST",
headers: { "x-api-key": API_KEY, "Content-Type": "application/json" },
body: JSON.stringify({ query, platform: "reddit" })
});
const data = await res.json();
return data.organic_results || [];
}
function score(text) {
const t = text.toLowerCase();
const pos = POSITIVE.filter(w => t.includes(w)).length;
const neg = NEGATIVE.filter(w => t.includes(w)).length;
const net = pos - neg;
return { pos, neg, net, label: net > 0 ? "positive" : net < 0 ? "negative" : "neutral" };
}
async function trackSentiment(queries) {
const posts = [];
for (const q of queries) {
const results = await searchReddit(q);
for (const r of results) {
const text = `${r.title || ""} ${r.snippet || ""}`;
posts.push({ title: r.title, link: r.link, sentiment: score(text) });
}
}
const pos = posts.filter(p => p.sentiment.label === "positive").length;
const neg = posts.filter(p => p.sentiment.label === "negative").length;
console.log(`${posts.length} posts: ${pos} positive, ${neg} negative`);
const today = new Date().toISOString().split("T")[0];
fs.writeFileSync(`reddit_sentiment_${today}.json`, JSON.stringify({ date: today, total: posts.length, positive: pos, negative: neg }, null, 2));
}
trackSentiment(["scavio api", "scavio search"]).catch(console.error);Salida esperada
{
"date": "2026-05-17",
"total": 24,
"positive": 9,
"negative": 4,
"neutral": 11,
"ratio": 0.38,
"top_positive": [
{
"title": "Scavio is the best cheap alternative to SerpApi",
"link": "https://reddit.com/r/webdev/comments/abc123",
"sentiment": { "pos": 2, "neg": 0, "net": 2, "label": "positive" }
}
],
"top_negative": [
{
"title": "Any search APIs that are not slow and overpriced?",
"link": "https://reddit.com/r/artificial/comments/def456",
"sentiment": { "pos": 0, "neg": 2, "net": -2, "label": "negative" }
}
]
}