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

使用Puppeteer+Express构建API:多脚本执行仅返回最后结果问题

问题原因与修复方案

核心问题

你的API仅返回最后一个脚本的执行结果,主要有两个原因:

  • 脚本执行逻辑特性:如果你将多个脚本拼接成单个字符串传入page.evaluate(),JavaScript执行多语句时只会返回最后一个语句的结果,因此你只能拿到最后一个脚本的输出。
  • 代码未支持多脚本批量处理:当前接口仅读取单个req.body.script参数,没有遍历执行多个脚本并收集所有结果的逻辑,自然无法返回全部结果。

修复方案

1. 调整请求体格式

让请求体传入脚本数组,示例:

{
  "target_url": "https://example.com",
  "script_delay": 1000,
  "scripts": [
    "document.title",
    "document.querySelector('h1').textContent",
    "window.innerWidth"
  ]
}

2. 修改API代码

const express = require("express");
const app = express();
app.use(express.json())
const puppeteer = require("puppeteer");

const port = 3000;

let browser = null;

app.post('/get/script_result', async (req, res) => {
  // 初始化全局浏览器实例
  if (!browser) {
    browser = await puppeteer.launch({
      headless: false, 
      defaultViewport: null, 
      args: [
        '--disable-infobars', 
        '--disable-notifications', 
        '--disable-default-apps',
        '--no-sandbox', 
        '--mute-audio', 
        '--ignore-certificate-errors', 
        '--disable-features=LookalikeUrlNavigationSuggestionsUI'
      ], 
      ignoreHTTPSErrors: true
    });
  }

  let page = null;
  try {
    page = await browser.newPage();
    await page.goto(req.body.target_url);

    // 处理延迟:确保为有效数字
    const delay = parseInt(req.body.script_delay, 10) || 0;
    if (delay > 0) await page.waitForTimeout(delay);

    const results = [];
    const scripts = Array.isArray(req.body.scripts) ? req.body.scripts : [req.body.script];

    // 遍历执行所有脚本
    for (const script of scripts) {
      try {
        const result = await page.evaluate(script);
        results.push({
          script,
          result,
          success: true
        });
      } catch (err) {
        results.push({
          script,
          error: err.message,
          success: false
        });
      }
    }

    res.status(200).json(results);
  } catch (err) {
    console.error(err);
    res.status(500).json({ error: err.message, success: false });
  } finally {
    // 关闭页面释放资源
    if (page) await page.close();
  }
})

app.listen(port, () => {
  console.log(`app is running on port: ${port}`);
});

3. 关键优化点

  • 批量脚本处理:支持传入脚本数组,遍历执行每个脚本并收集结果。
  • 资源泄漏修复:在finally块中关闭每个请求创建的页面,避免浏览器积累大量无效页面。
  • 错误隔离:单个脚本执行失败不会导致整个请求失败,每个脚本的执行状态独立返回。
  • 参数校验:将延迟参数转为数字,避免非有效值引发错误。
  • 响应标准化:用JSON格式返回结构化结果,便于前端解析。

额外说明

如果你的“发送多个脚本”指的是多次并发请求而非单次请求中的多脚本,那当前代码本身不会导致仅返回最后一个请求结果的问题,此时需要检查前端请求处理逻辑(比如是否覆盖了之前的响应数据)。

内容的提问来源于stack exchange,提问作者Harun Ünal

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 19:27:16