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

Puppeteer部署到Heroku后超时、browser未定义错误如何解决?

问题根因分析
    1. ReferenceError: browser is not defined报错:browser变量使用const声明在try块内部,属于块级作用域,catch块无法访问该变量,出错后执行await browser.close()时直接触发未定义错误。
    1. 导航超时、运行卡顿:Heroku实例本身算力、带宽资源有限,且你当前的Puppeteer配置没有做性能优化,默认等待页面全量资源加载完成,很容易触发30s超时阈值。另外你配置的unhandledRejection监听每次执行函数都会重复绑定,会导致内存泄漏进一步拖慢运行速度。
    1. 定时任务逻辑风险:当前使用setInterval每30s执行一次爬取任务,如果单次爬取耗时超过30s,会出现多个爬取任务并发执行,进一步抢占资源导致卡顿。
修复方案

1. 调整变量作用域 + 资源清理逻辑

将browser声明提到try块外部,同时用finally块统一处理浏览器实例关闭,避免重复绑定全局事件监听。

2. 优化Puppeteer配置

新增Heroku环境必需的--disable-dev-shm-usage参数,禁用不必要的资源加载,调整页面跳转的等待策略。

3. 优化定时任务逻辑

改用串行执行的定时逻辑,单次爬取完成后再间隔30s启动下一次,避免并发抢占资源。

修复后的参考代码
const puppeteer = require('puppeteer');
const express = require('express');
const app = express();
let GList = [];

// 显卡URL提前声明,避免每次执行重复创建
const GPU_URLS = [RTX3090, RTX3080TI, RTX3080, RTX3070TI, RTX3070, RTX3060TI, RTX3060, RTX2060, GTX1660TI];

async function scrapeProduct() {
  let browser = null;
  try {
    console.log('2');
    const array = [];
    browser = await puppeteer.launch({
      headless: true, // 显式开启无头模式
      args: [
        '--no-sandbox',
        '--disable-setuid-sandbox',
        '--disable-dev-shm-usage', // 适配Heroku小内存环境,避免共享内存不足
        '--disable-gpu',
        '--no-first-run',
        '--no-zygote'
      ],
    });
    const page = await browser.newPage();
    // 拦截无用资源,大幅提升加载速度
    await page.setRequestInterception(true);
    page.on('request', (req) => {
      const uselessResource = ['image', 'stylesheet', 'font', 'media', 'script'];
      if (uselessResource.includes(req.resourceType())) {
        req.abort();
      } else {
        req.continue();
      }
    });
    await page.setUserAgent('Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.212 Safari/537.36');

    for (let i = 0; i < GPU_URLS.length; i++) {
      console.log('page');
      // 只等待DOM加载完成,不等待全量资源,超时时间调整到60s,也可设为0关闭超时
      await page.goto(GPU_URLS[i], {
        waitUntil: 'domcontentloaded',
        timeout: 60000
      });
      const result = await page.evaluate(() => {
        const List = [];
        const allProduct = document.querySelectorAll("div.prod_info");
        allProduct.forEach(ele => {
          if (ele.querySelector('ul.price_box > li > span.site_btn.orderNow > button') !== null || ele.querySelector('ul.price_box > li > span.site_btn.add24hCart > button') !== null) {
            const GraphicCard = {
              'name': ele.querySelector('a').innerText,
              'price': ele.querySelector('.value').innerText,
              'link': ele.querySelector('a').href
            }
            List.push(GraphicCard);
          }
        })
        return List;
      })
      array.push(result);
    }
    console.log('3');
    return array;
  } catch (err) {
    console.log('爬取出错:', err);
    return [];
  } finally {
    // 无论成功失败都关闭浏览器实例
    if (browser) {
      await browser.close();
    }
  }
}

async function createList() {
  try {
    console.log('1');
    GList = [];
    GList.push(await scrapeProduct());
  } catch (err) {
    console.log('任务出错:', err);
  } finally {
    // 本次任务执行完成后,间隔30s再执行下一次
    setTimeout(createList, 30000);
  }
}

// 启动首次任务
createList();

app.get('/', (req, res) => {
  res.send(GList);
})

const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
  console.log(`服务运行在端口${PORT}`);
})

内容的提问来源于stack exchange,提问作者T.L

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.08 17:15:04