You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Node.js中实现按周期分批执行每日项目数据抓取任务?

实现按日期分配的循环抓取任务

核心方案

用定时任务库每日触发执行,结合星期判断匹配对应项目列表,从MongoDB拉取项目配置后执行抓取,同时控制并发避免负载过高。

具体实现步骤

1. 依赖选择

用Node.js生态里的定时任务库,比如node-schedule(语法更直观)或node-cron(类似Linux cron表达式),二选一即可。同时确保你已经集成了MongoDB驱动(比如mongoose或官方mongodb包)。

2. 定义日期-项目映射规则

先把你的抓取规则写成配置对象,注意不同库的星期编号:

  • node-schedule中,周日是0,周一1,周二2,周四4,周五5
  • node-cron中,周日是0或7,周一1,依此类推

示例规则:

const scheduleRules = {
  1: ['Proj-1', 'Proj-2'], // 周一
  4: ['Proj-1', 'Proj-2'], // 周四
  2: ['Proj-3', 'Proj-4'], // 周二
  5: ['Proj-3', 'Proj-4']  // 周五
};

3. 配置每日定时任务

以node-schedule为例,设置每天凌晨2点触发任务(可根据业务调整时间):

const schedule = require('node-schedule');
const mongoose = require('mongoose');

// 连接MongoDB(假设你的项目模型是Project)
mongoose.connect('mongodb://localhost:27017/your-db-name');
const Project = mongoose.model('Project', {
  name: String,
  crawlConfig: Object, // 存储抓取所需的URL、参数等
  lastCrawled: Date
});

// 每天凌晨2点执行
const job = schedule.scheduleJob('0 0 2 * * *', async () => {
  const today = new Date();
  const dayOfWeek = today.getDay(); // 0=周日,1=周一...

  // 匹配当天要抓取的项目列表
  const targetProjects = scheduleRules[dayOfWeek];
  if (!targetProjects) {
    console.log('今日无抓取任务');
    return;
  }

  try {
    // 从MongoDB查询目标项目
    const projects = await Project.find({ name: { $in: targetProjects } });
    if (projects.length === 0) {
      console.log('未找到匹配的项目配置');
      return;
    }

    // 并发执行抓取(控制并发数,避免负载过高)
    const concurrencyLimit = 2; // 同时跑2个抓取任务,可调整
    for (let i = 0; i < projects.length; i += concurrencyLimit) {
      const batch = projects.slice(i, i + concurrencyLimit);
      await Promise.all(batch.map(async (proj) => {
        console.log(`开始抓取 ${proj.name}`);
        // 调用你的抓取函数,比如await crawlProject(proj.crawlConfig);
        // 抓取完成后更新最后抓取时间
        await Project.updateOne({ _id: proj._id }, { lastCrawled: new Date() });
        console.log(`${proj.name} 抓取完成`);
      }));
    }
  } catch (err) {
    console.error('抓取任务执行失败:', err);
    // 可选:发送告警邮件/消息
  }
});

4. 关键细节处理

  • 并发控制:用分批+Promise.all限制同时运行的抓取任务数,避免服务器负载过高。
  • 错误处理:给每个抓取任务加try-catch,单个项目失败不影响其他任务;全局捕获异常记录日志或告警。
  • 时区问题:如果服务器时区和业务时区不一致,创建Date对象时要指定时区,比如用new Date(new Date().toLocaleString('en-US', { timeZone: 'Asia/Shanghai' }))转换。
  • 幂等性:抓取前检查lastCrawled,避免同一天重复抓取(如果任务意外重启)。
  • 日志与监控:记录每个任务的执行状态、耗时,方便排查问题。

替代方案:用cron表达式直接配置

如果用node-cron,可以直接为不同日期配置独立的cron任务,比如:

const cron = require('node-cron');

// 周一、周四凌晨2点执行Proj1、2
cron.schedule('0 2 * * 1,4', async () => {
  await runCrawl(['Proj-1', 'Proj-2']);
});

// 周二、周五凌晨2点执行Proj3、4
cron.schedule('0 2 * * 2,5', async () => {
  await runCrawl(['Proj-3', 'Proj-4']);
});

// 封装通用抓取函数
async function runCrawl(projectNames) {
  const projects = await Project.find({ name: { $in: projectNames } });
  // 后续抓取逻辑和上面一致
}

这种方式更直观,适合规则简单的场景。

内容的提问来源于stack exchange,提问作者Abhishek Solanki

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 00:55:20