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

Async/await场景下MySQL回调中向Puppeteer传参异常问题求助

问题根因
  • 异步变量闭包陷阱:你在cluster.task的回调中直接引用了for循环内定义的dt、cpf变量,这些变量在每次循环时都会被覆盖,而异步任务的实际执行时机晚于for循环遍历完成的时间,因此所有任务拿到的都是最后一轮循环的变量值。
  • Puppeteer-cluster使用逻辑错误:cluster.task(任务定义)、cluster.idle()(等待所有任务完成)、cluster.close()(关闭集群)都被错误放在for循环内部,导致每遍历一条数据就重复定义任务、关闭集群,完全不符合集群批量处理的设计逻辑,还会进一步放大变量共享问题。
修复方案

调整代码逻辑,将集群相关的初始化、任务定义移到循环外,提交任务时把当前行的cpf、dt和url一起作为参数传入任务,避免引用外层循环变量,所有任务提交完成后再统一等待执行、关闭集群。
修正后代码如下:

const mysql = require('mysql');
const { Cluster } = require('puppeteer-cluster');

const sql = "select an.id_clientes, ano, c.nome, c.cpf, c.dt_nasc from clientes_anos an inner join clientes c on an.id_clientes = c.id limit 3";
db.query(sql, async (err, result) => {
    if (err) throw err; // 建议新增错误处理

    // 集群初始化、全局配置移到循环外,仅执行一次
    const cluster = await Cluster.launch({
        concurrency: Cluster.CONCURRENCY_CONTEXT,
        maxConcurrency: 2,
        puppeteerOptions: {
            headless: false
        },
        timeout: 90000,
    });

    // 全局错误监听仅注册一次
    cluster.on('taskerror', (err, data) => {
        console.log(`任务执行失败 ${data.url}: ${err.message}`);
    });

    // 任务定义仅写一次,参数从传入的data中取,不引用外层变量
    await cluster.task(async ({ page, data }) => {
        const { url, cpf, dt } = data;
        console.log('当前执行参数', dt, cpf);
        await page.goto(url);
        await page.type('#data_nascimento', dt);
        await page.type('input[name=CPF]', cpf);
        // 注:原逻辑中waitForNavigation位置有误,type操作不会触发跳转,若你后续有点击提交按钮的逻辑,需把该方法放在点击操作前后配合使用,避免超时
        await page.waitForNavigation();

        try{
            const msg = await page.$eval(
            `#rfb-main-container table tbody tr:nth-of-type(1) td:nth-of-type(1)`, divs => divs.innerText.trim()
            );
    
            if(msg.includes('Resultado encontrado: Saldo inexistente de imposto a pagar ou a restituir.')){
                console.log('situação: '+ msg);
            }else{
                console.log('0');
            }
    
        }catch(exception){
            console.log('Error', exception.message);
        }
    });

    // 循环仅做参数处理、任务提交
    for (const elem of result){
        const cpf = elem.cpf;
        const dt = elem.dt_nasc.toLocaleDateString('pt-BR'); // 建议指定区域,避免不同环境日期格式不一致
        const url = `https://servicos.receita.fazenda.gov.br/Servicos/ConsRest/Atual.app/paginas/index.asp?cpf=${cpf}&dtnasc=${dt}`;
        console.log('提交任务', url);
        // 提交任务时把三个参数一起传入
        await cluster.queue({ url, cpf, dt });
    }

    // 所有任务提交完成后,再等待全部执行完成、关闭集群
    await cluster.idle();
    await cluster.close();
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.19 11:27:02