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

为何Puppeteer异步函数scrapeEbay内的数组无法在外部访问?

问题原因与解决方案

核心原因

没错,问题完全是异步函数的执行顺序导致的。scrapeEbay是异步函数,调用它时如果不添加await,JavaScript会直接继续执行后续代码,不会等待这个函数里的所有异步操作(比如页面跳转、数据抓取、数组填充)完成。

你的main函数里,for循环只是触发了两次scrapeEbay调用,但没有等待它们执行完毕,所以循环结束后立刻执行的console.log会在scrapeEbay完成数据填充前运行,这时候outputItems和outputPrices自然是空数组。

修复方案

1. 等待异步任务完成(快速修复)

在main的循环里给scrapeEbay调用加上await,确保每个抓取任务完成后再继续下一个:

async function main(inputArray) {
  for (let i = 0; i < inputArray.length; i++) {
    await scrapeEbay(inputArray[i]); // 加上await等待任务完成
  }
  console.log(outputItems, outputPrices); // 此时数组已被填充
}

2. 更优方案:避免全局变量(推荐)

全局变量容易引发状态混乱,建议让scrapeEbay直接返回抓取结果,在main里统一收集:

// 修改scrapeEbay,返回单条抓取结果
async function scrapeEbay(inputString) {
  const browser = await puppeteer.launch({ headless: false });
  const page = await browser.newPage();

  // 原有页面操作逻辑不变
  await page.goto("https://ebay.com/sch/ebayadvsearch");
  await page.type("#_nkw", inputString);
  await page.click("#LH_Sold");
  await page.click("#LH_ItemConditionUsed");
  await page.click("#LH_LocatedInRadio");
  await page.click("#searchBTNLowerLnk");

  await page.waitForSelector("span.s-item__price");
  const scrapedPrices = await page.$$eval("span.s-item__price", (spans) => {
    return [...spans].slice(1).map((span) => {
      var slicedNumber = span.innerHTML.slice(24, -7);
      var splitNumber = slicedNumber.replace(",", "");
      return parseFloat(splitNumber);
    });
  });

  const medianPrice = median(scrapedPrices);
  await browser.close();
  
  return { item: inputString, price: medianPrice }; // 返回当前项的结果
}

// 修改main,统一收集所有结果
async function main(inputArray) {
  // 并行执行所有抓取任务(效率更高)
  const results = await Promise.all(inputArray.map(item => scrapeEbay(item)));
  
  // 提取所需的数组
  const outputItems = results.map(r => r.item);
  const outputPrices = results.map(r => r.price);
  
  console.log(outputItems, outputPrices);
  return { outputItems, outputPrices }; // 可将结果返回给调用者
}

main(["i7 6700k", "gtx 970"]);

补充说明

  • 如果不需要严格按顺序抓取,Promise.all并行执行多个任务的效率远高于顺序await。
  • 去掉全局变量后,代码的可维护性和可读性会大幅提升,也避免了多个异步任务同时修改全局数组可能引发的冲突。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 19:50:44