使用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
相关产品推荐
相关产品推荐

