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

Node.js中setInterval无报错但未按周期执行爬虫函数问题

问题根因
  • 错误引入timers/promises模块下的setInterval:该API是供异步迭代使用的工具方法,和全局环境下接收回调、按固定间隔执行的setInterval行为完全不同,是定时逻辑失效的核心原因。
  • 定时任务传参错误:setInterval(scrape(), 4000)写法会在代码运行到该行时立刻执行一次scrape(),将其返回的Promise对象作为参数传入,而非将scrape函数本身作为执行回调传入,无法触发周期执行。
  • 存在资源泄漏:每次执行scrape都会启动全新的浏览器实例,爬取完成后未关闭释放进程,运行2次后就会因为系统资源占用过高阻塞后续执行。
  • 间隔参数不匹配:需求为5秒间隔,代码中传入的4000毫秒对应4秒间隔,不符合预期。

代码仅打印2次结果的现象和上述问题完全对应:setInterval行内立刻执行1次爬取,后续手动调用scrape()再执行1次,之后因API错误、资源耗尽无后续输出。

修复后可运行代码
const puppeteer = require('puppeteer-extra');
const StealthPlugin = require('puppeteer-extra-plugin-stealth');
const cheerio = require('cheerio');
require('dotenv').config();
const accountSid = process.env.TWILIO_ACCOUNT_SID;
const authToken = process.env.TWILIO_AUTH_TOKEN;
const client = require('twilio')(accountSid,authToken);
puppeteer.use(StealthPlugin());
const oldData = "oldData";

async function scrape(){
    let browser;
    try {
        browser = await puppeteer.launch({
            headless: true,
            defaultViewport:{
                width: 1920,
                height: 1080
            }
        });

        const page = await browser.newPage();
        // 替换为实际目标页面地址
        await page.goto('page');

        const pageData = await page.evaluate(() => {
            return{
                width: document.documentElement.clientWidth,
                height: document.documentElement.clientHeight,
                html: document.documentElement.innerHTML,
            };
        });

        const $ = cheerio.load(pageData.html);
        const element = $(".accordion__header-inner:last");
        console.log(element.text());
    } catch (err) {
        // 捕获单次爬取异常,避免定时任务整体终止
        console.error('爬取执行异常:', err.message);
    } finally {
        // 无论爬取成功/失败,都关闭浏览器释放资源
        if (browser) await browser.close();
    }
};

// 首次启动立即执行一次
scrape();
// 传入函数引用,设置5秒间隔
const timerHandle = setInterval(scrape, 5000);

// 程序退出前可调用 clearInterval(timerHandle) 清理定时任务
优化建议
  • 清理冗余引入:代码中未使用的fs模块、从cheerio解构的html变量都可以直接删除,减少不必要的加载开销。
  • 可复用浏览器实例:如果爬取频率较高,不需要每次执行都重新启动浏览器、新建页面,复用同一个页面对象可以大幅降低性能消耗。
  • 避免任务堆叠:如果单次页面加载+爬取的耗时可能超过5秒,不建议直接使用固定间隔的setInterval,可以改成爬取流程结束后延迟5秒再发起下一次请求的递归写法,避免多个爬取任务同时运行占用资源。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 08:54:19