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

并发POST请求下Puppeteer爬虫无法完整获取数据

问题:并发POST请求下Puppeteer爬虫返回不完整结果

我参考教程用Puppeteer构建了全栈网页爬虫项目,后端基于Node.js Express框架,前端通过POST请求触发爬虫任务。但当同时发起2个及以上POST请求时,服务器并发执行任务,无法返回完整的爬取结果。

具体代码

服务器文件index.js的POST方法:

app.post("/data", async (req, res) => {
  try {
    console.log("Connected");
    const result = await scrapers.scrape();
    console.log("data" + result);
    res.status(200).json(result);
  } catch (error) {
    res.status(500).json(error);
  }
});

scrapers.js中的爬虫函数:

async function scrape() {
  const browser = await puppeteer.launch({ headless: true });
  const page = await browser.newPage();

  const all_data= [];

  //traverse through first 4 pages of website
  for (i = 1; i < 5; i++) {
    await page.goto(
      "https://www.examplewebsite.com/page" + i
    );

    const data = await page.evaluate(function () {
      const events = document.querySelectorAll(".a");
      const cur_data= [];

      for (i = 0; i < events.length; i++) {
        cur_data.push(events[i].innerText);
      }
      return cur_data;
    });

    all_data.push(data);
  }

  browser.close();

  return all_data;
}

操作与结果

  • 操作:第一个请求未完成时发送第二个POST请求
  • 预期:两次请求均返回完整的爬取数据
  • 实际:返回的数据集要么部分完整,要么一个完整另一个为空

问题原因与解决方法

核心问题是循环变量i未使用let/const声明,导致成为全局变量。当多个请求并发执行时,两个请求的循环会共用同一个全局i,互相干扰循环逻辑——比如第一个请求的循环还没跑完,第二个请求的循环修改了i的值,直接破坏了遍历流程。

另外,browser.close()是异步方法,需要加上await确保浏览器关闭后再返回结果,避免资源泄漏或未完成操作就返回数据。

修复后的scrape函数:

async function scrape() {
  const browser = await puppeteer.launch({ headless: true });
  const page = await browser.newPage();

  const all_data= [];

  // 使用let声明i,避免全局污染
  for (let i = 1; i < 5; i++) {
    await page.goto(
      "https://www.examplewebsite.com/page" + i
    );

    const data = await page.evaluate(function () {
      const events = document.querySelectorAll(".a");
      const cur_data= [];

      // 同样用let声明内部的i
      for (let i = 0; i < events.length; i++) {
        cur_data.push(events[i].innerText);
      }
      return cur_data;
    });

    all_data.push(data);
  }

  // 等待浏览器关闭完成
  await browser.close();

  return all_data;
}

修改后,每个请求的循环变量都是独立的局部变量,并发执行时不会互相干扰,同时确保浏览器资源正确释放,就能得到预期的完整爬取结果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 14:15:13