¿Cómo lograr un rastreador de Google Trends en Pipedream?
Advanced Data Extraction Specialist
En los campos del marketing digital, SEO y análisis de tendencias emergentes, mantenerse actualizado con los cambios en Google Trends es esencial. Sin embargo, verificar y compilar manualmente los datos de tendencias de palabras clave consume tiempo, es propenso a errores e ineficiente. Para solucionar esto, hemos construido un sistema de informes automatizado que integra Pipedream, Scrapeless API y Discord Webhook para agilizar todo el proceso, desde la recopilación de palabras clave y el procesamiento de datos hasta la entrega de resultados.
Este artículo te guiará a través de los componentes e implementación de este sistema automatizado en detalle.
Características Clave
-
Análisis Automatizado de Tendencias de Palabras Clave: Obtiene datos de tendencias del último mes utilizando Scrapeless.
-
Puntuación y Procesamiento Inteligente: Calcula automáticamente la popularidad promedio y la fluctuación de tendencias para cada palabra clave.
-
Informes Analíticos Visuales: Genera informes estructurados con visuales y los envía directamente a Discord.
Requisitos Previos
- Regístrate en Scrapeless y obtén tu clave API.
- Localiza tu token API y cópialo para uso posterior.

⚠️ Nota: Mantén seguro tu token API y no lo compartas con otros.
- Inicia sesión en Pipedream
- Haz clic en "+ Nuevo flujo de trabajo" para crear un nuevo flujo de trabajo.

Cómo Crear un Sistema Automatizado de Informes de Google Trends (Pipedream + Scrapeless + Discord)
Estructura del Flujo de Trabajo
| Nombre del Paso | Tipo | Función |
|---|---|---|
trigger |
Programa | Activa el flujo de trabajo en un horario (por ejemplo, cada hora) |
http |
Código Node.js | Envía tareas de raspado a Scrapeless y obtiene los resultados |
code_step |
Código Node.js | Analiza y procesa los datos raspados |
discord_notify |
Código Node.js | Envía los resultados del análisis a Discord a través de webhook |
Paso 1: Activador Programado
Selecciona el tipo de activador como Programa y establece la hora del activador para ejecutar automáticamente este flujo de trabajo todos los domingos a las 16:00 UTC.

Paso 2 - http (solicitar a Scrapeless que rastree tendencias de palabras clave)

- Agrega un paso de código Node.js. El siguiente es un ejemplo de código que integra la lógica de llamada a la API de Scrapeless.
import { axios } from "@pipedream/platform"
export default defineComponent({
async run({ steps, $ }) {
const keywords = ["IA", "Aprendizaje Automático", "Ciencia de Datos"];
const allResults = {};
for (const keyword of keywords) {
console.log(`Procesando palabra clave: ${keyword}`);
const payload = {
actor: "scraper.google.trends",
input: {
q: keyword,
date: "hoy 1-m",
data_type: "interés a lo largo del tiempo",
hl: "es",
tz: "420",
geo: "",
cat: "",
property: "",
},
proxy: {
country: "",
}
};
try {
const response = await axios($, {
method: 'POST',
url: 'https://api.scrapeless.com/api/v1/scraper/request',
headers: {
'Content-Type': 'application/json',
'x-api-token': 'CLAVE API de Scrapeless'
},
data: payload
});
console.log(`Respuesta para ${keyword}:`, response);
if (response.job_id) {
console.log(`Trabajo creado para ${keyword}, ID: ${response.job_id}`);
let attempts = 0;
const maxAttempts = 12;
let jobResult = null;
while (attempts < maxAttempts) {
await new Promise(resolve => setTimeout(resolve, 10000));
attempts++;
try {
const resultResponse = await axios($, {
method: 'GET',
url: `https://api.scrapeless.com/api/v1/scraper/result/${response.job_id}`,
headers: {
'x-api-token': 'CLAVE API de Scrapeless'
}
});
console.log(`Intento ${attempts} para ${keyword}:`, resultResponse);
if (resultResponse.status === 'completed') {
jobResult = resultResponse.result;
```javascript
console.log(`Trabajo completado para ${keyword}:`, jobResult);
break;
} else if (resultResponse.status === 'failed') {
console.error(`El trabajo falló para ${keyword}:`, resultResponse);
break;
} else {
console.log(`Trabajo aún en ejecución para ${keyword}, estado: ${resultResponse.status}`);
}
} catch (error) {
console.error(`Error al comprobar el estado del trabajo para ${keyword}:`, error);
}
}
if (jobResult) {
allResults[keyword] = jobResult;
} else {
allResults[keyword] = {
error: `Tiempo de espera del trabajo agotado o falló después de ${attempts} intentos`,
job_id: response.job_id
};
}
} else {
allResults[keyword] = response;
}
} catch (error) {
console.error(`Error para ${keyword}:`, error);
allResults[keyword] = {
error: `Solicitud fallida: ${error.message}`
};
}
}
console.log("Resultados finales:", JSON.stringify(allResults, null, 2));
return allResults;
},
})
Nota:
- Este paso utiliza el actor
scraper.google.trendsde Scrapeless para recuperar los datos de "interest_over_time" para cada palabra clave. - Las palabras clave predeterminadas son:
["IA", "Aprendizaje Automático", "Ciencia de Datos"]. Puedes reemplazarlas según sea necesario. - Reemplaza
YOUR_API_TOKENcon tu token de API real.
Paso 3 - code_step (procesamiento de datos rastreados)

- Agrega otro paso de código de Node.js. Aquí tienes un ejemplo de código
export default defineComponent({
async run({ steps, $ }) {
const httpData = steps.http.$return_value;
console.log("Datos HTTP recibidos:", JSON.stringify(httpData, null, 2));
const processedData = {};
const timestamp = new Date().toISOString();
for (const [keyword, data] of Object.entries(httpData)) {
console.log(`Procesando ${keyword}:`, data);
let timelineData = null;
let isPartial = false;
if (data?.interest_over_time?.timeline_data) {
timelineData = data.interest_over_time.timeline_data;
isPartial = data.interest_over_time.isPartial || false;
} else if (data?.timeline_data) {
timelineData = data.timeline_data;
} else if (data?.interest_over_time && Array.isArray(data.interest_over_time)) {
timelineData = data.interest_over_time;
}
if (timelineData && Array.isArray(timelineData) && timelineData.length > 0) {
console.log(`Encontrados ${timelineData.length} puntos de datos para ${keyword}`);
const values = timelineData.map(item => {
const value = item.value || item.interest || item.score || item.y || 0;
return parseInt(value) || 0;
});
const validValues = values.filter(v => v >= 0);
if (validValues.length > 0) {
const average = Math.round(validValues.reduce((sum, val) => sum + val, 0) / validValues.length);
const trend = validValues.length >= 2 ? validValues[validValues.length - 1] - validValues[0] : 0;
const max = Math.max(...validValues);
const min = Math.min(...validValues);
const recentValues = validValues.slice(-7);
const earlyValues = validValues.slice(0, 7);
const recentAvg = recentValues.length > 0 ? recentValues.reduce((a, b) => a + b, 0) / recentValues.length : 0;
const earlyAvg = earlyValues.length > 0 ? earlyValues.reduce((a, b) => a + b, 0) / earlyValues.length : 0;
const weeklyTrend = Math.round(recentAvg - earlyAvg);
processedData[keyword] = {
keyword,
average,
trend,
weeklyTrend,
values: validValues,
max,
min,
dataPoints: validValues.length,
isPartial,
timestamps: timelineData.map(item => item.time || item.date || item.timestamp),
lastValue: validValues[validValues.length - 1],
firstValue: validValues[0],
volatility: Math.round(Math.sqrt(validValues.map(x => Math.pow(x - average, 2)).reduce((a, b) => a + b, 0) / validValues.length)),
status: 'success'
};
} else {
processedData[keyword] = {
keyword,
average: 0,
trend: 0,
weeklyTrend: 0,
values: [],
max: 0,
min: 0,
dataPoints: 0,
isPartial: false,
error: "No se encontraron valores válidos en los datos de la línea de tiempo",
status: 'error',
rawTimelineLength: timelineData.length
};
}
} else {
processedData[keyword] = {
json
clave,
promedio: 0,
tendencia: 0,
tendenciaSemanal: 0,
valores: [],
máximo: 0,
mínimo: 0,
puntosDeDatos: 0,
esParcial: false,
error: "No se encontraron datos de línea de tiempo",
estado: 'error',
clavesDisponibles: datos ? Object.keys(datos) : []
};
}
}
const resumen = {
marcaTemporal,
totalDeClaves: Object.keys(datosProcesados).length,
clavesExitosas: Object.values(datosProcesados).filter(d => d.estado === 'success').length,
periodo: "hoy 1-m",
datos: datosProcesados
};
console.log("Datos procesados finales:", JSON.stringify(resumen, null, 2));
return resumen;
},
})
Calculará las siguientes métricas en función de los datos devueltos por Scrapeless:
- Valor promedio
- Cambio de tendencia semanal (últimos 7 días vs. los 7 días anteriores)
- Valores máximos / mínimos
- Volatilidad
Nota:
- Cada palabra clave generará un objeto de análisis detallado, lo que facilitará la visualización y las notificaciones posteriores.
Paso 4 - discord_notify (Enviar informe de análisis a Discord)
- Agregue el último paso de Node.js, el siguiente es el ejemplo de código
import { axios } from "@pipedream/platform"
export default defineComponent({
async run({ steps, $ }) {
const datosProcesados = steps.Code_step.$return_value;
const discordWebhookUrl = "https://discord.com/api/webhooks/1380448411299614821/MXzmQ14TOPK912lWhle_7qna2VQJBjWrdCkmHjdEloHKhYXw0fpBrp-0FS4MDpDB8tGh";
console.log("Procesando datos para Discord:", JSON.stringify(datosProcesados, null, 2));
const fechaActual = new Date().toLocaleString('es-ES');
const palabrasClaves = Object.values(datosProcesados.datos);
const exitosas = palabrasClaves.filter(k => k.estado === 'success');
let mejorRendimiento = null;
let peorRendimiento = null;
let tendenciaMásFuerte = null;
if (exitosas.length > 0) {
mejorRendimiento = exitosas.reduce((max, curr) => curr.promedio > max.promedio ? curr : max);
peorRendimiento = exitosas.reduce((min, curr) => curr.promedio < min.promedio ? curr : min);
tendenciaMásFuerte = exitosas.reduce((max, curr) => Math.abs(curr.tendenciaSemanal) > Math.abs(max.tendenciaSemanal) ? curr : max);
}
const mensajeDiscord = {
content: `📊 **Informe de Google Trends** - ${fechaActual}`,
embeds: [
{
title: "🔍 Análisis de Tendencias",
color: 3447003,
timestamp: new Date().toISOString(),
fields: [
{
name: "📈 Resumen",
value: `**Periodo:** Último mes\n**Palabras clave analizadas:** ${datosProcesados.totalDeClaves}\n**Éxito:** ${datosProcesados.clavesExitosas}/${datosProcesados.totalDeClaves}`,
inline: false
}
]
}
]
};
if (exitosas.length > 0) {
const detallesDePalabrasClaves = exitosas.map(data => {
const iconoTendencia = data.tendenciaSemanal > 5 ? '🚀' :
data.tendenciaSemanal > 0 ? '📈' :
data.tendenciaSemanal < -5 ? '📉' :
data.tendenciaSemanal < 0 ? '⬇️' : '➡️';
const iconoRendimiento = data.promedio > 70 ? '🔥' :
data.promedio > 40 ? '✅' :
data.promedio > 20 ? '🟡' : '🔴';
return {
name: `${iconoRendimiento} ${data.clave}`,
value: `**Puntuación:** ${data.promedio}/100\n**Tendencia:** ${iconoTendencia} ${data.tendenciaSemanal > 0 ? '+' : ''}${data.tendenciaSemanal}\n**Rango:** ${data.mínimo}-${data.máximo}`,
inline: true
};
});
mensajeDiscord.embeds[0].fields.push(...detallesDePalabrasClaves);
}
if (mejorRendimiento && exitosas.length > 1) {
mensajeDiscord.embeds.push({
title: "🏆 Puntos Clave",
color: 15844367,
fields: [
{
name: "🥇 Mejor Rendimiento",
value: `**${mejorRendimiento.clave}** (${mejorRendimiento.promedio}/100)`,
inline: true
},
{
name: "📊 Puntuación Más Baja",
value: `**${peorRendimiento.clave}** (${peorRendimiento.promedio}/100)`,
inline: true
},
{
name: "⚡ Tendencia Más Fuerte",
value: `**${tendenciaMásFuerte.clave}** (${tendenciaMásFuerte.tendenciaSemanal > 0 ? '+' : ''}${tendenciaMásFuerte.tendenciaSemanal})`,
inline: true
}
]
});
}
const fallidos = palabrasClaves.filter(k => k.estado === 'error');
if (fallidos.length > 0) {
mensajeDiscord.embeds.push({
title: "❌ Errores",
color: 15158332,
fields: fallidos.map(data => ({
name: data.clave,
value: data.error || "Error desconocido",
inline: true
}))
});
}
console.log("Mensaje de Discord para enviar:", JSON.stringify(discordMessage, null, 2));
try {
const response = await axios($, {
method: 'POST',
url: discordWebhookUrl,
headers: {
'Content-Type': 'application/json'
},
data: discordMessage
});
console.log("Respuesta del webhook de Discord:", response);
return {
webhook_enviado: true,
plataforma: "discord",
mensaje_enviado: true,
palabras_clave_analizadas: processedData.totalKeywords,
palabras_clave_exitosas: processedData.successfulKeywords,
timestamp: currentDate,
respuesta_discord: response
};
} catch (error) {
console.error("Error del webhook de Discord:", error);
const simpleMessage = {
content: `📊 **Informe de Tendencias de Google - ${currentDate}**\n\n` +
`📈 **Resultados (${processedData.successfulKeywords}/${processedData.totalKeywords}):**\n` +
successful.map(data =>
`• **${data.keyword}**: ${data.average}/100 (${data.weeklyTrend > 0 ? '+' : ''}${data.weeklyTrend})`
).join('\n') +
(failed.length > 0 ? `\n\n❌ **Errores:** ${failed.map(d => d.keyword).join(', ')}` : '')
};
try {
const fallbackResponse = await axios($, {
method: 'POST',
url: discordWebhookUrl,
headers: {
'Content-Type': 'application/json'
},
data: simpleMessage
});
return {
webhook_enviado: true,
plataforma: "discord",
mensaje_enviado: true,
fallback_utilizado: true,
respuesta_discord: fallbackResponse
};
} catch (fallbackError) {
console.error("Error de fallback de Discord:", fallbackError);
return {
webhook_enviado: false,
plataforma: "discord",
error: error.message,
error_fallback: fallbackError.message,
resumen_datos: {
palabras_clave: processedData.totalKeywords,
exitosas: processedData.successfulKeywords,
mejor_desempeño: bestPerformer?.keyword,
mejor_puntuación: bestPerformer?.average
}
};
}
}
},
})
- Reemplaza TU URL DE WEBHOOK DE DISCORD con tu propia dirección de Webhook.
- Haz clic en Desplegar para ejecutar tu flujo de trabajo y obtener información en tiempo real.
Paso 5 - Recibe información en tiempo real de las tendencias de Google
Puedes recibir datos para verificar palabras clave directamente en Discord:

Lo siguiente es el diagrama de enlaces completo:

✅ En Vivo Ahora: Integración Oficial de Scrapeless en Pipedream
Scrapeless ahora está oficialmente disponible en el hub de integraciones de Pipedream. Con solo unos clics, puedes llamar a nuestra poderosa API de Tendencias de Google directamente desde tus flujos de trabajo de Pipedream, sin configuración, sin servidores requeridos.
Ya sea que estés construyendo tableros en tiempo real, automatizando inteligencia de marketing, o potenciando análisis personalizados, esta integración te da el camino más rápido hacia la monitorización de tendencias de calidad de producción.
👉 Comienza a construir instantáneamente: pipedream.com/apps/scrapeless
Arrastra, suelta y despliega tu próximo flujo de trabajo potenciado por tendencias, hoy.
Perfecto para desarrolladores, analistas y equipos de crecimiento que necesitan perspectivas accionables, rápido.
Resumen
A través de la combinación poderosa de Pipedream, la API de Scrapeless y Discord, construimos un sistema de informes de Tendencias de Google que no requiere intervención manual y se ejecuta automáticamente todos los días. Esto no solo mejora enormemente la eficiencia del trabajo, sino que también hace que las decisiones de marketing sean más basadas en datos.
¡Si también necesitas construir un sistema similar de análisis de automatización de datos, no dudes en probar esta combinación tecnológica!
Scrapeless opera en plena conformidad con las leyes y regulaciones aplicables, accediendo solo a datos disponibles públicamente de acuerdo con los términos de servicio de la plataforma. Esta solución está diseñada para propósitos legítimos de inteligencia empresarial e investigación.
En Scrapeless, solo accedemos a datos disponibles públicamente y cumplimos estrictamente con las leyes, regulaciones y políticas de privacidad del sitio web aplicables. El contenido de este blog es sólo para fines de demostración y no implica ninguna actividad ilegal o infractora. No ofrecemos garantías y renunciamos a toda responsabilidad por el uso de la información de este blog o enlaces de terceros. Antes de realizar cualquier actividad de scraping, consulte a su asesor legal y revise los términos de servicio del sitio web de destino u obtenga los permisos necesarios.



