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

GCP云函数使用Puppeteer执行长耗时爬虫任务如何后台运行

错误原因

你遇到的报错本质是GCP云函数的运行机制导致的:云函数在你调用res.json('OK')返回响应后,运行环境会立即进入冻结状态,未执行完成的异步任务(也就是你没await的scraper逻辑)会被强行终止,进程被杀死才会抛出exit code 16的错误,不存在在同一个云函数实例里「先返回响应再后台跑任务」的可行性。


最优解决方案

核心是把「接收请求返回响应」和「执行爬虫任务」两个逻辑拆分,用GCP原生的任务队列做异步解耦,完全符合GCP云函数的设计规范:

  1. 入口云函数:仅负责接收请求、校验参数、把爬虫任务参数投递到任务队列,全程耗时不超过100ms,直接返回OK给客户端,不会触发超时。
  2. 任务队列(推荐用Cloud Tasks):存储爬虫任务,自动触发工作云函数执行,支持自定义重试策略。
  3. 工作云函数:专门跑Puppeteer爬虫逻辑,超时时间可自定义设置到最高9分钟,完全覆盖你1-3分钟的爬虫耗时。

代码实现示例

1. 入口云函数代码

const {CloudTasksClient} = require('@google-cloud/tasks');
const tasksClient = new CloudTasksClient();

// 替换为你自己的GCP配置项
const PROJECT_ID = '你的GCP项目ID';
const LOCATION = '队列所在区域';
const QUEUE_NAME = '你提前创建的Cloud Tasks队列名';
const WORKER_FUNC_URL = '工作云函数的访问URL';

exports.Runner = async (req, res) => {
  // 构造爬虫任务
  const task = {
    httpRequest: {
      httpMethod: 'POST',
      url: WORKER_FUNC_URL,
      body: Buffer.from(JSON.stringify(req.body)).toString('base64'),
      headers: {'Content-Type': 'application/json'},
    },
  };

  // 投递任务到队列
  const parent = tasksClient.queuePath(PROJECT_ID, LOCATION, QUEUE_NAME);
  await tasksClient.createTask({parent, task});

  // 立即返回响应
  res.json('OK');
};

2. 工作云函数代码

const puppeteer = require('puppeteer');

async function browserPromise() {
    return await puppeteer.launch({
        args: [
            "--ignore-certificate-errors",
            "--no-sandbox",
        ],
        headless: true
    })
}

async function scraper(browser, page, formdata) { 
  // 你原有的爬虫逻辑
}

exports.ScraperWorker = async (req, res) => {
  const browser = await browserPromise();
  const page = await browser.newPage();
  await page.setViewport({width: 1200, height: 720});

  try {
    await scraper(browser, page, req.body);
    // 补充结果存入数据库的逻辑
    res.status(200).send('执行完成');
  } catch (err) {
    console.error('爬虫执行失败:', err);
    res.status(500).send('执行失败,Cloud Tasks会按配置自动重试');
  } finally {
    await browser.close();
  }
}

配置注意事项

  • 提前在GCP控制台创建Cloud Tasks队列,给入口云函数授予Cloud Tasks 任务创建者权限,给工作云函数授予Cloud Functions 调用者权限。
  • 工作云函数的超时时间设置为大于你爬虫的最长耗时,比如设置为4分钟,内存建议至少配置1GB,满足Puppeteer的运行资源需求。
  • 如果爬虫任务不需要精确的调度控制,用Pub/Sub代替Cloud Tasks也可以,整体逻辑差异不大。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 07:36:04