🥳Tham gia Cộng đồng Scrapelessnhận thử nghiệm miễn phí của bạn để truy cập Bộ công cụ Web Scraping mạnh mẽ của chúng tôi!
Quay lại blog

Làm thế nào để tạo một trình theo dõi xu hướng Google trên Pipedream?

Emily Chen
Emily Chen

Advanced Data Extraction Specialist

05-Jun-2025

Trong lĩnh vực tiếp thị kỹ thuật số, SEO và phân tích xu hướng mới nổi, việc cập nhật thường xuyên với các thay đổi trong Google Trends là điều cần thiết. Tuy nhiên, việc kiểm tra thủ công và tổng hợp dữ liệu xu hướng từ khóa mất nhiều thời gian, dễ gây ra lỗi và không hiệu quả. Để giải quyết vấn đề này, chúng tôi đã xây dựng một hệ thống báo cáo tự động tích hợp Pipedream, Scrapeless API và Discord Webhook để đơn giản hóa toàn bộ quy trình — từ việc thu thập từ khóa và xử lý dữ liệu đến việc gửi kết quả.

Bài viết này sẽ hướng dẫn bạn chi tiết về các thành phần và cách triển khai hệ thống tự động này.

Tính Năng Chính

  • Phân Tích Xu Hướng Từ Khóa Tự Động: Lấy dữ liệu xu hướng trong tháng qua bằng Scrapeless.

  • Tính Điểm Thông Minh & Xử Lý: Tự động tính toán mức độ phổ biến trung bình và biến động xu hướng cho mỗi từ khóa.

  • Báo Cáo Phân Tích Hình Ảnh: Tạo báo cáo có cấu trúc với hình ảnh và gửi trực tiếp đến Discord.


Điều Kiện Tiên Quyết

  1. Đăng ký trên Scrapeless và nhận API Key của bạn.
  2. Tìm vị trí API Token của bạn và sao chép nó để sử dụng sau.
Tìm vị trí API Token của bạn

⚠️ Lưu Ý: Giữ API Token của bạn an toàn và không chia sẻ với người khác.


  1. Đăng nhập vào Pipedream
  2. Nhấn "+ New Workflow" để tạo một quy trình làm việc mới.
+ New Workflow

Cấu Trúc Quy Trình

Tên Bước Loại Chức Năng
trigger Lịch Trình Kích hoạt quy trình làm việc theo lịch trình (ví dụ, mỗi giờ)
http Mã Node.js Gửi yêu cầu quét tới Scrapeless và lấy kết quả
code_step Mã Node.js Phân tích và xử lý dữ liệu đã được quét
discord_notify Mã Node.js Gửi kết quả phân tích tới Discord qua webhook

Bước 1: Kích Hoạt Theo Lịch Trình

Chọn loại kích hoạt là Lịch Trình và đặt thời gian kích hoạt tự động thực hiện quy trình làm việc này vào mỗi Chủ Nhật lúc 16:00 theo giờ UTC.

Chọn loại kích hoạt

Bước 2 - http (yêu cầu Scrapeless quét xu hướng từ khóa)

http (yêu cầu Scrapeless quét xu hướng từ khóa)
  1. Thêm một bước mã Node.js. Dưới đây là một ví dụ mã tích hợp logic gọi API của Scrapeless
Copy
import { axios } from "@pipedream/platform"

export default defineComponent({
  async run({ steps, $ }) {
    const keywords = ["AI", "Machine Learning", "Data Science"];
    const allResults = {};
    
    for (const keyword of keywords) {
      console.log(`Đang xử lý từ khóa: ${keyword}`);
      
      const payload = {
        actor: "scraper.google.trends",
        input: {
          q: keyword,
          date: "today 1-m",
          data_type: "interest_over_time",
          hl: "en",
          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': 'Scrapeless API KEY'
          },
          data: payload
        });
        
        console.log(`Phản hồi cho ${keyword}:`, response);
        
        if (response.job_id) {
          console.log(`Công việc được tạo cho ${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': 'Scrapeless API KEY'
                }
              });
              
              console.log(`Cố gắng ${attempts} cho ${keyword}:`, resultResponse);
              
              if (resultResponse.status === 'completed') {
                jobResult = resultResponse.result;
```javascript
console.log(`Công việc đã hoàn thành cho ${keyword}:`, jobResult);
                break;
              } else if (resultResponse.status === 'failed') {
                console.error(`Công việc thất bại cho ${keyword}:`, resultResponse);
                break;
              } else {
                console.log(`Công việc vẫn đang chạy cho ${keyword}, trạng thái: ${resultResponse.status}`);
              }
            } catch (error) {
              console.error(`Lỗi khi kiểm tra trạng thái công việc cho ${keyword}:`, error);
            }
          }
          
          if (jobResult) {
            allResults[keyword] = jobResult;
          } else {
            allResults[keyword] = { 
              error: `Công việc đã hết thời gian hoặc thất bại sau ${attempts} lần thử`,
              job_id: response.job_id 
            };
          }
          
        } else {
          allResults[keyword] = response;
        }
        
      } catch (error) {
        console.error(`Lỗi cho ${keyword}:`, error);
        allResults[keyword] = { 
          error: `Yêu cầu thất bại: ${error.message}` 
        };
      }
    }
    
    console.log("Kết quả cuối:", JSON.stringify(allResults, null, 2));
    return allResults;
  },
})
json Copy
{
  "từ khóa": {
    "trung bình": 0,
    "xu hướng": 0,
    "xu hướng hàng tuần": 0,
    "giá trị": [],
    "tối đa": 0,
    "tối thiểu": 0,
    "điểm dữ liệu": 0,
    "một phần": false,
    "lỗi": "Không tìm thấy dữ liệu dòng thời gian",
    "trạng thái": "lỗi",
    "các khóa có sẵn": data ? Object.keys(data) : []
  }
}

const tóm tắt = {
  thời gian: timestamp,
  tổng số từ khóa: Object.keys(processedData).length,
  số từ khóa thành công: Object.values(processedData).filter(d => d.status === 'success').length,
  thời gian: "hôm nay 1-m",
  dữ liệu: processedData
};

console.log("Dữ liệu đã xử lý cuối cùng:", JSON.stringify(summary, null, 2));
return summary;
},

---

Nó sẽ tính toán các chỉ số sau dựa trên dữ liệu được trả về từ Scrapeless:

* **Giá trị trung bình**
* **Thay đổi xu hướng hàng tuần** (7 ngày cuối so với 7 ngày trước)
* **Giá trị tối đa / tối thiểu**
* **Biến động**

**Lưu ý:**

* Mỗi từ khóa sẽ tạo ra một đối tượng phân tích chi tiết, giúp dễ dàng cho việc trực quan hóa và thông báo thêm.

### Bước 4 - thông báo discord (Đẩy báo cáo phân tích đến Discord)

1. Thêm bước Node.js cuối cùng, mã sau là ví dụ mã

import { axios } from "@pipedream/platform"

export default defineComponent({
async run({ steps, $ }) {
const processedData = steps.Code_step.$return_value;

Copy
const discordWebhookUrl = "https://discord.com/api/webhooks/1380448411299614821/MXzmQ14TOPK912lWhle_7qna2VQJBjWrdCkmHjdEloHKhYXw0fpBrp-0FS4MDpDB8tGh";

console.log("Xử lý dữ liệu cho Discord:", JSON.stringify(processedData, null, 2));

const currentDate = new Date().toLocaleString('en-US');

const từ khóa = Object.values(processedData.data);
const thành công = keywords.filter(k => k.status === 'success');

let người thực hiện tốt nhất = null;
let người thực hiện tệ nhất = null;
let xu hướng mạnh nhất = null;

if (thành công.length > 0) {
  người thực hiện tốt nhất = thành công.reduce((max, curr) => curr.average > max.average ? curr : max);
  người thực hiện tệ nhất = thành công.reduce((min, curr) => curr.average < min.average ? curr : min);
  xu hướng mạnh nhất = thành công.reduce((max, curr) => Math.abs(curr.weeklyTrend) > Math.abs(max.weeklyTrend) ? curr : max);
}

const thông điệp discord = {
  nội dung: `📊 **Báo cáo Xu hướng Google** - ${currentDate}`,
  nhúng: [
    {
      tiêu đề: "🔍 Phân tích Xu hướng",
      màu: 3447003,
      thời gian: new Date().toISOString(),
      trường: [
        {
          tên: "📈 Tóm tắt",
          giá trị: `**Thời gian:** Tháng trước\n**Từ khóa phân tích:** ${processedData.totalKeywords}\n**Thành công:** ${processedData.successfulKeywords}/${processedData.totalKeywords}`,
          inline: false
        }
      ]
    }
  ]
};

if (thành công.length > 0) {
  const chi tiết từ khóa = thành công.map(data => {
    const biểu tượng xu hướng = data.weeklyTrend > 5 ? '🚀' : 
                               data.weeklyTrend > 0 ? '📈' : 
                               data.weeklyTrend < -5 ? '📉' : 
                               data.weeklyTrend < 0 ? '⬇️' : '➡️';
    
    const biểu tượng hiệu suất = data.average > 70 ? '🔥' : 
                                 data.average > 40 ? '✅' : 
                                 data.average > 20 ? '🟡' : '🔴';
    
    return {
      tên: `${biểu tượng hiệu suất} ${data.keyword}`,
      giá trị: `**Điểm:** ${data.average}/100\n**Xu hướng:** ${biểu tượng xu hướng} ${data.weeklyTrend > 0 ? '+' : ''}${data.weeklyTrend}\n**Phạm vi:** ${data.min}-${data.max}`,
      inline: true
    };
  });
  
  thông điệp discord.embeds[0].fields.push(...chi tiết từ khóa);
}

if (người thực hiện tốt nhất && thành công.length > 1) {
  thông điệp discord.embeds.push({
    tiêu đề: "🏆 Điểm Nổi Bật",
    màu: 15844367,
    trường: [
      {
        tên: "🥇 Người Thực Hiện Tốt Nhất",
        giá trị: `**${người thực hiện tốt nhất.keyword}** (${người thực hiện tốt nhất.average}/100)`,
        inline: true
      },
      {
        tên: "📊 Điểm Thấp Nhất",
        giá trị: `**${người thực hiện tệ nhất.keyword}** (${người thực hiện tệ nhất.average}/100)`,
        inline: true
      },
      {
        tên: "⚡ Xu hướng Mạnh Nhất",
        giá trị: `**${xu hướng mạnh nhất.keyword}** (${xu hướng mạnh nhất.weeklyTrend > 0 ? '+' : ''}${xu hướng mạnh nhất.weeklyTrend})`,
        inline: true
      }
    ]
  });
}

const thất bại = từ khóa.filter(k => k.status === 'error');
if (thất bại.length > 0) {
  thông điệp discord.embeds.push({
    tiêu đề: "❌ Lỗi",
    màu: 15158332,
    trường: thất bại.map(data => ({
      tên: data.keyword,
      giá trị: data.error || "Lỗi không xác định",
      inline: true
    }))
  });
}

}

Copy
```vi
}

console.log("Tin nhắn Discord để gửi:", JSON.stringify(discordMessage, null, 2));

try {
  const response = await axios($, {
    method: 'POST',
    url: discordWebhookUrl,
    headers: {
      'Content-Type': 'application/json'
    },
    data: discordMessage
  });
  
  console.log("Phản hồi webhook Discord:", response);
  
  return {
    webhook_sent: true,
    platform: "discord",
    message_sent: true,
    keywords_analyzed: processedData.totalKeywords,
    successful_keywords: processedData.successfulKeywords,
    timestamp: currentDate,
    discord_response: response
  };
  
} catch (error) {
  console.error("Lỗi webhook Discord:", error);
  
  const simpleMessage = {
    content: `📊 **Báo cáo Google Trends - ${currentDate}**\n\n` +
            `📈 **Kết quả (${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❌ **Lỗi:** ${failed.map(d => d.keyword).join(', ')}` : '')
  };
  
  try {
    const fallbackResponse = await axios($, {
      method: 'POST',
      url: discordWebhookUrl,
      headers: {
        'Content-Type': 'application/json'
      },
      data: simpleMessage
    });
    
    return {
      webhook_sent: true,
      platform: "discord",
      message_sent: true,
      fallback_used: true,
      discord_response: fallbackResponse
    };
    
  } catch (fallbackError) {
    console.error("Lỗi dự phòng Discord:", fallbackError);
    
    return {
      webhook_sent: false,
      platform: "discord",
      error: error.message,
      fallback_error: fallbackError.message,
      data_summary: {
        keywords: processedData.totalKeywords,
        successful: processedData.successfulKeywords,
        best_performer: bestPerformer?.keyword,
        best_score: bestPerformer?.average
      }
    };
  }
}
},
  1. Thay thế ĐỊA CHỈ WEBHOOK DISCORD CỦA BẠN bằng địa chỉ Webhook của riêng bạn.
  2. Nhấn Deploy để chạy quy trình làm việc của bạn và nhận thông tin theo thời gian thực.

Bạn có thể nhận dữ liệu để kiểm tra từ khóa trực tiếp trên Discord:

Bước 5 - Nhận thông tin Google Trends theo thời gian thực

Dưới đây là sơ đồ liên kết hoàn chỉnh:

Dưới đây là sơ đồ liên kết hoàn chỉnh

✅ Đang hoạt động: Tích hợp chính thức của Scrapeless trên Pipedream

Scrapeless hiện đã có mặt chính thức trên trung tâm tích hợp của Pipedream! Chỉ với vài cú nhấp chuột, bạn có thể gọi API Google Trends mạnh mẽ của chúng tôi trực tiếp từ các quy trình làm việc trên Pipedream—không cần cài đặt, không cần máy chủ.

Dù bạn đang xây dựng bảng điều khiển theo thời gian thực, tự động hóa trí thông minh marketing, hay cung cấp phân tích tùy chỉnh, tích hợp này mang đến cho bạn con đường nhanh nhất để theo dõi xu hướng ở cấp độ sản xuất.

👉 Bắt đầu xây dựng ngay: pipedream.com/apps/scrapeless
Kéo, thả và triển khai quy trình làm việc sẵn sàng cho xu hướng tiếp theo của bạn—ngày hôm nay.

Hoàn hảo cho các nhà phát triển, nhà phân tích và các nhóm tăng trưởng cần thông tin có thể hành động, nhanh chóng.

Tóm tắt

Thông qua sự kết hợp mạnh mẽ giữa Pipedream, API Scrapeless và Discord, chúng tôi đã xây dựng một hệ thống báo cáo Google Trends không cần can thiệp thủ công và sẽ được thực hiện tự động hàng ngày. Điều này không chỉ cải thiện đáng kể hiệu suất công việc mà còn làm cho các quyết định tiếp thị dựa trên dữ liệu hơn.

Nếu bạn cũng cần xây dựng một hệ thống phân tích tự động dữ liệu tương tự, bạn có thể thử nghiệm kết hợp công nghệ này!


Scrapeless hoạt động hoàn toàn tuân thủ các luật và quy định áp dụng, chỉ truy cập dữ liệu công khai theo điều khoản dịch vụ của nền tảng. Giải pháp này được thiết kế cho mục đích trí thông minh kinh doanh hợp pháp và nghiên cứu.

Tại Scrapless, chúng tôi chỉ truy cập dữ liệu có sẵn công khai trong khi tuân thủ nghiêm ngặt các luật, quy định và chính sách bảo mật trang web hiện hành. Nội dung trong blog này chỉ nhằm mục đích trình diễn và không liên quan đến bất kỳ hoạt động bất hợp pháp hoặc vi phạm nào. Chúng tôi không đảm bảo và từ chối mọi trách nhiệm đối với việc sử dụng thông tin từ blog này hoặc các liên kết của bên thứ ba. Trước khi tham gia vào bất kỳ hoạt động cạo nào, hãy tham khảo ý kiến ​​cố vấn pháp lý của bạn và xem xét các điều khoản dịch vụ của trang web mục tiêu hoặc có được các quyền cần thiết.

Bài viết phổ biến nhất

Danh mục