Docker 镜像介绍
Docker 镜像是用于在 Docker 容器中执行代码的文件。它类似于构建 Docker 容器的指令集,就像一个模板。换句话说,它们相当于虚拟机环境中的快照。
Docker 镜像包含运行容器所需的所有库、依赖项和文件,使其成为容器的独立可执行文件。这些镜像可以在多个位置共享和部署,因此具有高度的可移植性。
什么是 Browserless?
Nstbrowser 的 Browserless 是一种无头 Chrome 云服务,可以在没有图形用户界面的情况下操作在线应用程序并自动化脚本。对于诸如网页抓取和其他自动化操作之类的任务,它尤其有用。
你对网页抓取和 Browserless 有任何奇妙的想法或疑问吗?
在 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-compatRUN 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:alpine
或 node:slim
,以减少镜像的大小。
删除不必要的依赖项和文件,通过使用 .dockerignore
文件和选择性地包含所需文件来保持镜像的简洁。
2. 启用无头模式
启用 Puppeteer 的无头模式({ headless: true }
),这将使浏览器在没有图形用户界面的情况下运行,从而减少资源消耗并提高性能。
3. 适当分配资源
请确保 Docker 容器获得足够的 CPU 和内存资源,以成功完成浏览器自动化任务。
您可以使用 Docker 的资源限制功能(例如 --cpus
和 --memory
)来管理容器的资源使用,并防止多容器环境中的资源竞争。
4. 优化 Dockerfile
减少 Dockerfile 中的层数,并将多个命令合并到单个 RUN
指令中,以缩短镜像的构建时间。
使用多阶段构建来分离构建阶段和运行阶段的依赖关系,从而生成更简化的最终镜像。
通过合理安排 Dockerfile 命令来利用构建缓存,从而提高构建效率并缩短后续构建时间。
5. 调整浏览器启动选项
自定义 Puppeteer 的浏览器启动参数,例如 args
、executablePath
和 ignoreDefaultArgs
,以优化浏览器行为和资源使用。
调整 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 条提示