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 条提示
相关推荐
理想不理想v17 分钟前
vue经典前端面试题
前端·javascript·vue.js
不收藏找不到我19 分钟前
浏览器交互事件汇总
前端·交互
YBN娜32 分钟前
Vue实现登录功能
前端·javascript·vue.js
阳光开朗大男孩 = ̄ω ̄=32 分钟前
CSS——选择器、PxCook软件、盒子模型
前端·javascript·css
minDuck37 分钟前
ruoyi-vue集成tianai-captcha验证码
java·前端·vue.js
小政爱学习!1 小时前
封装axios、环境变量、api解耦、解决跨域、全局组件注入
开发语言·前端·javascript
魏大帅。1 小时前
Axios 的 responseType 属性详解及 Blob 与 ArrayBuffer 解析
前端·javascript·ajax
ZHOU西口1 小时前
微服务实战系列之玩转Docker(十八)
分布式·docker·云原生·架构·数据安全·etcd·rbac
花花鱼1 小时前
vue3 基于element-plus进行的一个可拖动改变导航与内容区域大小的简单方法
前端·javascript·elementui
k09331 小时前
sourceTree回滚版本到某次提交
开发语言·前端·javascript