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

Puppeteer爬取脚本无法将抓取数据保存到本地文件的问题排查

Puppeteer脚本问题排查

你的脚本存在多处API误用和逻辑错误,具体如下:

  • 并发配置传参位置错误:concurrency: 3是bluebird.map的配置项,你错把它当成参数传给了page.evaluate,既没有实现预期的并发控制,还向页面上下文注入了无用参数。
  • DOM取值逻辑完全错误:
    1. document.querySelectorAll返回的是DOM节点的类数组集合,直接访问集合的href属性永远拿不到值;且目标元素是img标签,资源地址存放在src属性下,不存在href属性。
    2. 没有做元素存在性校验,只要目标选择器匹配不到元素,直接访问属性就会抛出空引用错误,中断整个爬取流程。
  • 回调无返回值:bluebird.map的处理回调没有return爬取到的数据,最终results数组会全是undefined。
  • 资源泄漏问题:脚本开头提前创建了1个从未使用的page实例,循环内新建的page实例爬取完成后也没有关闭,会持续占用内存。
  • 冗余等待拖慢效率:已经通过waitForSelector监听目标元素加载,额外固定等待60秒属于无意义阻塞,会把爬取速度拉低数十倍。
  • 执行顺序不合理:setViewport调用放在page.goto之后,不符合正常浏览器的访问逻辑,可能导致页面渲染尺寸异常。
  • 存储格式不匹配:爬取结果是结构化JSON数据,保存为.html后缀的文件不利于后续读取解析。
修正后可运行代码
const puppeteer = require('puppeteer');
const fs = require('fs');
const bluebird = require("bluebird");

(async() => {
  const browser = await puppeteer.launch({ headless: 'new' });
  const urls = ['/news/england/', '/news/wales/'];

  const results = await bluebird.map(urls, async(url) => {
    const page = await browser.newPage();
    try {
      await page.setDefaultNavigationTimeout(0);
      // 跳转页面前先设置视口
      await page.setViewport({
        width: 1920,
        height: 1080,
        deviceScaleFactor: 1,
      });
      await page.setUserAgent('Mozilla/5.0 (Windows NT 10.0; rv:78.0) Gecko/20100101 Firefox/78.0');
      await page.goto('https://www.bbc.com' + url, {
        waitUntil: 'domcontentloaded'
      });
      await page.waitForSelector('#topos-component');
      const pageData = await page.evaluate(() => {
        const titleEl = document.querySelector("a.gel-paragon-bold");
        const coverEl = document.querySelector(".gs-o-responsive-image--lead > img:nth-child(1)");
        return {
          title: titleEl ? titleEl.innerText.trim() : null,
          cover: coverEl ? coverEl.src : null
        };
      });
      return {
        targetUrl: 'https://www.bbc.com' + url,
        ...pageData
      };
    } catch (err) {
      console.error(`爬取路径${url}失败:`, err.message);
      return {
        targetUrl: 'https://www.bbc.com' + url,
        error: err.message
      };
    } finally {
      // 用完页面实例及时关闭,释放内存
      await page.close();
    }
  }, {
    concurrency: 3 // 并发配置正确传给bluebird.map
  });

  // 保存为标准JSON格式文件
  fs.writeFileSync('crawl_result.json', JSON.stringify(results, null, 2));
  await browser.close();
})();
修改说明
  • 移除了所有未使用的依赖引入和冗余代码
  • 增加了错误捕获逻辑,单个页面爬取失败不会中断整体任务
  • 调整了API调用顺序,删除无意义的硬等待
  • 增加了DOM元素空值判断,避免空引用报错
  • 修正了DOM属性取值逻辑,爬取结果带上对应页面地址方便溯源
  • 每个页面实例爬取完成后自动关闭,避免内存泄漏

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 18:39:27