将 Puppeteer 部署为无服务器 API:解决方案比较

Puppeteer 是一个强大的工具,能够模拟人类与网页的交互,支持网页截图、PDF 生成、自动化测试、正常运行时间监控、网页抓取和内容跟踪等各种用例。

在云中部署 Puppeteer 有很多种情况。例如:

  • 通过 CI/CD 管道中的 API 触发自动化测试。
  • 使用 cron 作业定期检查网站可用性。
  • 运行大规模、分布式网络抓取工具。
  • 无服务器计算的按需付费和可扩展性使其成为浏览器自动化任务的绝佳选择。但是,大多数平台(如 DigitalOcean)仅提供虚拟机,迫使您为空闲时间付费(这会浪费很多钱!)。目前只有少数平台支持以无服务器方式运行 Puppeteer:、和。

    本文探讨这些平台:如何使用它们来完成典型的 Puppeteer 任务,以及它们的优缺点。

    任务

    让我们以一个常见的 Puppeteer 用例作为示例:捕获网页的屏幕截图。

    该任务涉及以下步骤:

  • 访问指定的 URL。
  • 截取页面屏幕截图。
  • 返回图像。
  • 利普赛尔

    **代码示例:**

    const puppeteer = require('puppeteer');
    const { Hono } = require('hono');
    const { serve } = require('@hono/node-server');
    
    const screenshot = async (url) => {
      const browser = await puppeteer.launch({ args: ['--single-process'] });
      const page = await browser.newPage();
      await page.goto(url);
      const img = await page.screenshot();
      await browser.close();
    
      return img;
    };
    
    const app = new Hono();
    
    app.get('/', async (c) => {
      const url = c.req.query('url');
    
      if (url) {
        const img = await screenshot(url);
        return c.body(img, { headers: { 'Content-Type': 'image/png' } });
      } else {
        return c.text('Please add an ?url=https://example.com/ parameter');
      }
    });
    
    const port = 8080;
    serve({ fetch: app.fetch, port }).on('listening', () => {
      console.log(`Server is running on port ${port}`);
    });

    Leapcell 是一个多功能平台,允许您以无服务器方式部署任何应用程序。但是,由于它不是专门为 HTTP 请求设计的,因此其设置可能稍微复杂一些 - 您需要手动创建 HTTP 请求处理程序。

    本地开发

    调试很简单。就像任何其他 Node.js 应用程序一样:`node index.js`,就完成了!

    部署

    要部署,请指定构建命令、运行命令和服务端口(如下所示)。

    Config

    一旦部署完成,您的应用程序即可在线使用。

    概括

    **✅优点:**

  • 一致的本地和云环境,使调试更容易。
  • 支持官方 Puppeteer 库。
  • **❌缺点:**

  • 设置稍微复杂一些:您必须编写自己的 HTTP 处理程序。
  • AWS Lambda

    **代码示例:**

    const chromium = require('chrome-aws-lambda');
    
    exports.handler = async (event) => {
      let browser = null;
    
      try {
        browser = await chromium.puppeteer.launch({
          args: chromium.args,
          defaultViewport: chromium.defaultViewport,
          executablePath: await chromium.executablePath,
          headless: chromium.headless,
        });
    
        const page = await browser.newPage();
        await page.goto(event.url);
    
        const screenshot = await page.screenshot();
    
        return {
          statusCode: 200,
          headers: {'Content-Type': 'image/jpeg'},
          body: screenshot.toString('base64'),
          isBase64Encoded: true,
        };
      } catch (error) {
        return {
          statusCode: 500,
          body: 'Failed to capture screenshot.',
        };
      } finally {
        if (browser !== null) {
          await browser.close();
        }
      }
    };

    AWS Lambda 需要使用 `puppeteer-core` 和第三方 Chromium 库,例如 。这是必要的,因为 AWS 对 Lambda 函数的大小施加了 250MB 的限制。与 Puppeteer 捆绑在一起的默认 Chromium 很容易超出此限制(macOS 上约 170MB,Linux 上约 282MB,Windows 上约 280MB),因此必须使用精简版 Chromium。

    本地开发

    由于运行环境不同,本地调试需要复杂的配置。如您在 `alixaxel/chrome-aws-lambda` 的指南中看到的那样。

    部署

    要部署,您需要将“node_modules”作为 ZIP 文件上传。根据您的用例,您可能还需要配置 Lambda 层。主要业务逻辑可以直接在 AWS 控制台中编写,保存后即可执行。

    概括

    **✅优点:**

  • 更简单的代码结构。
  • **❌缺点:**

  • 依赖第三方Chromium库,可能会引入潜在的风险。
  • 复杂的本地调试。
  • 繁琐的部署过程需要 ZIP 上传和可能的 Lambda 层。
  • Cloudflare 浏览器渲染

    **代码示例:**

    import puppeteer from '@cloudflare/puppeteer';
    
    export default {
      async fetch(request, env) {
        const { searchParams } = new URL(request.url);
        let url = searchParams.get('url');
        if (url) {
          url = new URL(url).toString(); // normalize
    
          const browser = await puppeteer.launch(env.MYBROWSER);
          const page = await browser.newPage();
          await page.goto(url);
          const img = await page.screenshot();
          await browser.close();
    
          return new Response(img, {
            headers: {
              'content-type': 'image/png',
            },
          });
        } else {
          return new Response('Please add an ?url=https://example.com/ parameter');
        }
      },
    };

    Cloudflare Browser Rendering 是一种相对较新的无服务器 Puppeteer 解决方案。与 AWS Lambda 类似,它不支持官方 Puppeteer 库。相反,它使用 Cloudflare 提供的 Puppeteer 版本。

    虽然 Cloudflare 的库比任何第三方选项都更安全,但其缓慢的更新周期令人沮丧——它已经五个多月没有更新了!

    此外,Cloudflare 浏览器渲染有几个限制:

  • 仅适用于 Worker Pro 用户。
  • 每个Cloudflare账号每分钟最多只能创建2个浏览器,且同时运行的浏览器数量不得超过2个。
  • 本地开发

    本地调试需要复杂的配置。

    部署

    要部署,请在线编写您的函数并保存以供运行。

    概括

    **✅优点:**

  • 更简单的代码结构。
  • **❌缺点:**

  • 依赖于Clouflare的Puppeteer库,该库的更新周期较慢。
  • 复杂的本地调试。
  • 由于付费墙和其他限制而限制访问。
  • 结论

    本文比较了三个主要的无服务器 Puppeteer 部署平台:Leapcell、AWS Lambda 和 Cloudflare Browser Rendering。每个平台都有其优点和缺点。

    您更喜欢哪一个?您还知道其他无服务器 Puppeteer 部署解决方案吗?请在评论中分享您的想法!

    如果您打算在线部署您的 Puppeteer 项目,那么与上述相比,Leapcell 将是一个不错的选择。

    有关部署指南,请访问我们的文档。

    Leapcell

    阅读我们的博客