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

请求优化Node.js+Puppeteer代码:按TXT行串行/限并发执行任务

Node.js Puppeteer 串行/限并发优化方案

原代码的问题在于lineReader.eachLine会并行触发回调,导致同时启动大量浏览器实例,既不符合串行/限并发要求,也容易触发目标网站的反爬机制。以下是针对性的优化方案:

一、基础问题修正

  • 修复变量名冲突:将var Date改为const targetDate,避免覆盖内置Date对象
  • 补上缺失的puppeteer模块引入
  • 移除process.setMaxListeners(Infinity),优化后不再需要此配置

二、串行处理方案

先一次性读取所有账号,再逐个处理每个账号,完成后等待15秒再执行下一个任务:

const puppeteer = require('puppeteer');
const fs = require('fs').promises;
const targetDate = '2022-10-12';

// 通用等待函数
const wait = (ms) => new Promise(resolve => setTimeout(resolve, ms));

async function processAccount(line) {
  console.log(`开始处理账号: ${line}`);
  const url = `https://mining.alienworlds.tools/?account=${line}&date=${targetDate}&skip=0`;
  
  try {
    const browser = await puppeteer.launch({
      headless: true,
      args: ['--user-agent=Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36']
    });
    
    const page = await browser.newPage();
    await page.setViewport({ width: 1920, height: 500 });
    await page.goto(url, { waitUntil: 'networkidle2' });
    
    // 等待目标元素加载完成
    const element = await page.waitForSelector("#__layout > div > div > div > div.row > div.col-lg-6.col-account > div > div:nth-child(3) > div"); 
    const value = await element.evaluate(el => el.textContent.trim());
    console.log(`${line} - ${value}`);
    
    await browser.close();
    console.log(`账号${line}处理完成,等待15秒后继续`);
    await wait(15000);
  } catch (error) {
    console.error(`处理账号${line}出错:`, error);
    // 出错后仍等待15秒,避免频繁请求触发反爬
    await wait(15000);
  }
}

async function main() {
  try {
    // 读取所有账号并过滤空行
    const content = await fs.readFile('accounts.txt', 'utf8');
    const lines = content.split('\n').filter(line => line.trim());
    
    // 串行遍历处理每个账号
    for (const line of lines) {
      await processAccount(line);
    }
    
    console.log('所有账号处理完成');
  } catch (error) {
    console.error('读取账号文件出错:', error);
  }
}

main();

三、限制2-3个并发的方案

如果需要同时运行2-3个浏览器实例,可采用批次并行处理的方式:

const puppeteer = require('puppeteer');
const fs = require('fs').promises;
const targetDate = '2022-10-12';
const CONCURRENCY_LIMIT = 2; // 可根据需求改为3

const wait = (ms) => new Promise(resolve => setTimeout(resolve, ms));

async function processAccount(line) {
  console.log(`开始处理账号: ${line}`);
  const url = `https://mining.alienworlds.tools/?account=${line}&date=${targetDate}&skip=0`;
  
  try {
    const browser = await puppeteer.launch({
      headless: true,
      args: ['--user-agent=Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36']
    });
    
    const page = await browser.newPage();
    await page.setViewport({ width: 1920, height: 500 });
    await page.goto(url, { waitUntil: 'networkidle2' });
    
    const element = await page.waitForSelector("#__layout > div > div > div > div.row > div.col-lg-6.col-account > div > div:nth-child(3) > div"); 
    const value = await element.evaluate(el => el.textContent.trim());
    console.log(`${line} - ${value}`);
    
    await browser.close();
    console.log(`账号${line}处理完成`);
  } catch (error) {
    console.error(`处理账号${line}出错:`, error);
  }
}

async function main() {
  try {
    const content = await fs.readFile('accounts.txt', 'utf8');
    const lines = content.split('\n').filter(line => line.trim());
    
    // 按并发限制分批处理
    for (let i = 0; i < lines.length; i += CONCURRENCY_LIMIT) {
      const batch = lines.slice(i, i + CONCURRENCY_LIMIT);
      // 并行处理当前批次的账号
      await Promise.all(batch.map(line => processAccount(line)));
      // 非最后一批处理完成后等待15秒
      if (i + CONCURRENCY_LIMIT < lines.length) {
        console.log('当前批次处理完成,等待15秒后继续');
        await wait(15000);
      }
    }
    
    console.log('所有账号处理完成');
  } catch (error) {
    console.error('读取账号文件出错:', error);
  }
}

main();

关键改动说明

  • 改用fs.promises.readFile一次性读取所有账号,便于控制执行顺序
  • 提取processAccount函数封装单账号处理逻辑,代码结构更清晰
  • 串行方案通过for...of结合await确保任务逐个执行,每个任务完成后等待15秒
  • 限并发方案通过Promise.all处理批次任务,批次间等待15秒控制请求频率
  • 增加全局错误捕获,避免单个账号处理失败导致整个程序崩溃
  • 移除原代码中冗余的waitFor(1000),page.goto的networkidle2已足够确保页面加载完成

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 16:55:35