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

Node.js导出Puppeteer爬取值打印显示[object Object]问题排查

问题原因与解决方案

核心问题

你遇到的问题有两个关键原因:

  1. 异步导出时机错误:CommonJS的require是同步加载机制,你的两个模块里都把导出逻辑放在了**立即执行异步函数(IIFE)**中。当index.js执行require时,异步函数还没跑完,模块默认导出的是初始空对象,所以你拿到的priceModule和nameModule都是空对象。
  2. 对象拼接触发默认toString:就算导出成功,直接用+连接对象会自动调用toString()方法,结果必然是[object Object]。

修正方案(推荐Promise方式)

因为Puppeteer的操作本身就是异步的,所以模块应该导出Promise,再在主文件中用async/await获取结果。

1. 修改nameModule.js

const puppeteer = require("puppeteer");

const url = "https://www.sec.gov/edgar/search/#/dateRange=custom&category=custom&startdt=2017-11-05&enddt=2022-11-07&forms=4";

// 直接导出异步函数返回的Promise
module.exports = (async () => {
  let browser;
  try {
    browser = await puppeteer.launch();
    const [page] = await browser.pages();
    const $ = (...args) => page.waitForSelector(...args);
    const text = async (...args) =>
      (await $(...args)).evaluate(el => el.textContent.trim());
    await page.goto(url, {waitUntil: "domcontentloaded"});
    const info = {
      secTableEN: await text(".table td.entity-name"),
      secTableFiled: await text(".table td.filed"),
      secTableLink: await text(".table td.filetype"),
    };
    return info.secTableEN;
  } catch (err) {
    console.error(err);
    throw err; // 抛出错误让主文件捕获
  } finally {
    await browser?.close();
  }
})();

2. 修改priceModule.js

const puppeteer = require("puppeteer");

const url = "https://www.sec.gov/edgar/search/#/dateRange=custom&category=custom&startdt=2017-11-05&enddt=2022-11-07&forms=4";

// 直接导出异步函数返回的Promise
module.exports = (async () => {
  let browser;
  try {
    browser = await puppeteer.launch();
    const [page] = await browser.pages();
    const ua = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.181 Safari/537.36";
    await page.setUserAgent(ua);
    await page.goto(url, {waitUntil: "domcontentloaded", timeout: 0});
    const responseP = page.waitForResponse(res =>
      res.status() === 200 && res.url().endsWith(".xml")
    );
    const a = await page.waitForSelector(".filetype .preview-file");
    await a.click();
    const html = await (await responseP).text();
    await page.evaluate(html => document.body.outerHTML = html, html);
    const price = await page.$$eval(".FormText", els =>
      els.find(e => e.textContent.trim() === "$")
        .parentNode
        .textContent
        .trim()
    );
    return price;
  } catch (err) {
    console.error(err);
    throw err; // 抛出错误让主文件捕获
  } finally {
    await browser?.close();
  }
})();

3. 修改index.js

const priceModule = require("./price");
const nameModule = require("./name");

// 用async/await解析Promise,获取实际值后再打印
(async () => {
  try {
    const secName = await nameModule;
    const secPrice = await priceModule;
    console.log(secName, secPrice); // 或用模板字符串 `${secName} ${secPrice}`
  } catch (err) {
    console.error("加载模块失败:", err);
  }
})();

额外注意事项

  • 永远不要在异步函数内部修改module.exports,CommonJS模块加载是同步的,异步代码执行时模块已经完成加载,修改不会生效。
  • 处理异步数据时,必须等Promise解析完成后再操作,不能直接对Promise对象进行拼接或其他同步操作。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 20:55:20