Puppeteer Web 抓取:使用 Browserless 的 Docker

Docker 镜像介绍

Docker 镜像是用于在 Docker 容器中执行代码的文件。它类似于构建 Docker 容器的指令集,就像一个模板。换句话说,它们相当于虚拟机环境中的快照。

Docker 镜像包含运行容器所需的所有库、依赖项和文件,使其成为容器的独立可执行文件。这些镜像可以在多个位置共享和部署,因此具有高度的可移植性。

什么是 Browserless?

Nstbrowser 的 Browserless 是一种无头 Chrome 云服务,可以在没有图形用户界面的情况下操作在线应用程序并自动化脚本。对于诸如网页抓取和其他自动化操作之类的任务,它尤其有用。

你对网页抓取和 Browserless 有任何奇妙的想法或疑问吗?

让我们看看其他开发者在 DiscordTelegram 上分享了什么吧!

在 Docker 中使用 Puppeteer 的好处是什么?

在 Docker 中使用 Puppeteer 至少有以下三个好处:

  • 确保环境一致性。
  • 简化依赖项管理。
  • 提高可扩展性并增强安全性。

此外,通过在 Docker 容器中运行 Puppeteer,您可以确保所有开发、测试和生产环境中的操作系统和浏览器版本一致。这还可以简化 Chrome 浏览器及其依赖项的安装过程,并轻松扩展容器实例以处理大规模任务。

此外,Docker 容器提供了一个隔离的环境,减少了潜在的安全风险。

在 Docker 中使用 Puppeteer 抓取动态网站

现在,我将向您展示如何基于 Nstbrowser 的 Docker 镜像使用 Puppeteer 抓取动态网站,并带您一步步完成一个简单的示例。

第一步:确定抓取目标

首先,我们要做的是确定我们想要抓取的信息。在这个示例中,我们选择抓取 Semrush 博客 中所有 H2 标签内容,并将其打印到控制台。

第二步:编写 Puppeteer 脚本

接下来,我们需要编写一个 Puppeteer 脚本来抓取目标信息。以下是 Puppeteer 进入目标页面并获取 H2 标签内容的代码:

javascript 复制代码
const page = await browser.newPage();

// 进入目标页面
await page.goto('https://www.semrush.com/blog/seo-best-practices/');

// 获取 h2 标签内容
const h2s = await page.evaluate(() => {
  const h2s = Array.from(document.querySelectorAll('h2'));
   return h2s.map(h2 => h2.textContent);
});

// 打印 h2 标签内容
console.log(h2s);

第三步:项目初始化

在实施这一步之前,请执行以下命令初始化一个新项目:

bash 复制代码
cd ~
makedir puppeteer-docker
cd puppeteer-docker

做得好!接下来我们需要做什么?只需用我们的代码创建以下三个文件:

  • index.mjs
javascript 复制代码
import puppeteer from 'puppeteer-core';

async function execPuppeteer(browserWSEndpoint) {
  try {
    const browser = await puppeteer.connect({
      browserWSEndpoint: browserWSEndpoint,
      defaultViewport: null,
    });
    const page = await browser.newPage();

    // 导航到目标 URL
    await page.goto('https://www.semrush.com/blog/seo-best-practices/');

    // 获取 h2 标签内容
    const h2s = await page.evaluate(() => {
      const h2s = Array.from(document.querySelectorAll('h2'));
      return h2s.map((h2) => h2.textContent);
    });

    // 打印 h2 标签内容
    console.log(h2s);

    // 关闭浏览器
    await browser.close();
  } catch (err) {
    console.error('launch', err);
  }
}

async function launchAndConnectToBrowser() {
  const host = 'host.docker.internal:8848';
  const config = {
    once: true,
    headless: true, // 设置无头模式
    autoClose: true,
    args: { '--disable-gpu': '', '--no-sandbox': '' }, // 浏览器参数应为字典
    fingerprint: {
      name: '',
      platform: 'mac',
      kernel: 'chromium',
      kernelMilestone: 124,
      hardwareConcurrency: 8,
      deviceMemory: 8,
    },
  };
  const browserWSEndpoint = `ws://${host}/ws/connect?${encodeURIComponent(
    JSON.stringify(config)
  )}`;
  await execPuppeteer(browserWSEndpoint);
}

launchAndConnectToBrowser().then();
  • Dockerfile

    FROM node:18-alpine AS base

    仅在需要时安装依赖项

    FROM base AS deps
    RUN set -eux && sed -i 's/dl-cdn.alpinelinux.org/mirrors.ustc.edu.cn/g' /etc/apk/repositories
    RUN apk add --no-cache libc6-compat

    RUN npm config set registry https://registry.npmmirror.com/
    RUN npm install -g pnpm

    设置工作目录

    WORKDIR /app

    复制 package.json 并安装依赖项

    COPY package*.json pnpm-lock.yaml ./

    RUN pnpm install

    WORKDIR /app
    COPY --link ./ .

    FROM base AS runner

    复制依赖项

    COPY --from=deps /app/node_modules ./node_modules

    复制应用代码

    COPY --from=deps /app .

    默认启动命令

    CMD ["node", "index.mjs"]

  • package.json

javascript 复制代码
{
  "name": "docker-puppeteer",
  "version": "1.0.0",
  "main": "index.mjs",
  "dependencies": {
    "puppeteer-core": "^23.1.0"
  },
  "scripts": {
    "start": "node index.mjs"
  }
}

做得好!我们已经创建了我们需要的三个文件!只剩下最后一个准备工作:安装项目依赖项

bash 复制代码
pnpm install

第四步:构建并运行 Docker 镜像

准备好了吗?我们终于可以构建并抓取 Docker 镜像了:

  • 打开控制台
  • 进入项目目录
  • 运行以下脚本命令构建 Docker 镜像
bash 复制代码
docker build -t puppeteer-docker.

完成了吗?请执行以下脚本运行我们的 puppeteer-docker 镜像。它将自动运行我们的 Puppeteer 脚本以执行抓取操作:

bash 复制代码
docker run --rm --network="host" puppeteer-docker

最终,您将看到如下输出结果。我们抓取了目标网页中所有 H2 标题内容:

优化 Docker 中 Puppeteer 的性能

在 Docker 环境中优化 Puppeteer 性能需要采取几项关键策略,以确保浏览器自动化任务高效运行。

1. 减少容器大小

选择轻量级的基础镜像,例如 node:alpinenode:slim,以减少镜像的大小。

删除不必要的依赖项和文件,通过使用 .dockerignore 文件和选择性地包含所需文件来保持镜像的简洁。

2. 启用无头模式

启用 Puppeteer 的无头模式({ headless: true }),这将使浏览器在没有图形用户界面的情况下运行,从而减少资源消耗并提高性能。

3. 适当分配资源

请确保 Docker 容器获得足够的 CPU 和内存资源,以成功完成浏览器自动化任务。

您可以使用 Docker 的资源限制功能(例如 --cpus--memory)来管理容器的资源使用,并防止多容器环境中的资源竞争。

4. 优化 Dockerfile

减少 Dockerfile 中的层数,并将多个命令合并到单个 RUN 指令中,以缩短镜像的构建时间。

使用多阶段构建来分离构建阶段和运行阶段的依赖关系,从而生成更简化的最终镜像。

通过合理安排 Dockerfile 命令来利用构建缓存,从而提高构建效率并缩短后续构建时间。

5. 调整浏览器启动选项

自定义 Puppeteer 的浏览器启动参数,例如 argsexecutablePathignoreDefaultArgs,以优化浏览器行为和资源使用。

调整 Chromium 启动标志以禁用不必要的功能或启用性能增强选项,例如通过 --disable-gpu 关闭 GPU 加速。

6. 容器编排

将 Puppeteer 应用程序部署在 Docker Swarm 或 Kubernetes 等容器编排平台上,利用这些平台提供的自动扩展、负载均衡和资源管理功能。

实现水平扩展,将负载分布到多个容器中,并在高流量条件下提高性能。

7. 监控和调优性能

使用 Docker 的监控工具(例如 Docker Stats、Docker Events 和 Docker Healthchecks)来监控容器的资源使用和健康状况。

实施应用性能监控(APM)解决方案(例如 Prometheus、Grafana 或 Datadog),以跟踪和分析响应时间、吞吐量和错误率等关键性能指标,识别和解决性能瓶颈。

最终想法

在 Docker 环境中运行 Puppeteer 为开发者带来了更多便利!它为浏览器自动化任务提供了灵活且可扩展的解决方案。

在本博客中,我们讨论了:

  • Docker 镜像的含义和功能
  • 使用 Puppeteer-Docker 爬取页面的具体步骤
  • 确保 Puppeteer 在 Docker 中高效运行的 7 条提示
相关推荐
极简网络科技26 分钟前
Docker、Wsl 打包迁移环境
运维·docker·容器
杨浦老苏31 分钟前
轻量级Docker管理工具Docker Switchboard
运维·docker·群晖
江湖有缘34 分钟前
【Docker管理工具】部署Docker可视化管理面板Dpanel
运维·docker·容器
難釋懷39 分钟前
Vue解决开发环境 Ajax 跨域问题
前端·vue.js·ajax
特立独行的猫a44 分钟前
Nuxt.js 中的路由配置详解
开发语言·前端·javascript·路由·nuxt·nuxtjs
一加一等于二1 小时前
docker部署postgresql17,并且安装插件
docker·postgresql
咸虾米1 小时前
在uniCloud云对象中定义dbJQL的便捷方法
前端·javascript
梨子同志1 小时前
JavaScript Proxy 和 Reflect
前端·javascript
汤圆炒橘子1 小时前
状态策略模式的优势分析
前端
90后的晨仔1 小时前
解析鸿蒙 ArkTS 中的 Union 类型与 TypeAliases类型
前端·harmonyos