Puppeteer Web 抓取:使用 Browserless 的 Docker

2024-08-22 13:52

本文主要是介绍Puppeteer Web 抓取:使用 Browserless 的 Docker,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Docker 镜像介绍

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

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

什么是 Browserless?

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

你对网页抓取和 Browserless 有任何奇妙的想法或疑问吗?
让我们看看其他开发者在 Discord 和 Telegram 上分享了什么吧!

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

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

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

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

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

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

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

第一步:确定抓取目标

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

第二步:编写 Puppeteer 脚本

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

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);

第三步:项目初始化

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

cd ~
makedir puppeteer-docker
cd puppeteer-docker

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

  • index.mjs
import puppeteer from 'puppeteer-core';async function execPuppeteer(browserWSEndpoint) {try {const browser = await puppeteer.connect({browserWSEndpoint: browserWSEndpoint,defaultViewport: null,});const page = await browser.newPage();// 导航到目标 URLawait 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 installWORKDIR /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
{"name": "docker-puppeteer","version": "1.0.0","main": "index.mjs","dependencies": {"puppeteer-core": "^23.1.0"},"scripts": {"start": "node index.mjs"}
}

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

pnpm install

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

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

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

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

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 的浏览器启动参数,例如 argsexecutablePath 和 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 条提示

这篇关于Puppeteer Web 抓取:使用 Browserless 的 Docker的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1096459

相关文章

Linux使用fdisk进行磁盘的相关操作

《Linux使用fdisk进行磁盘的相关操作》fdisk命令是Linux中用于管理磁盘分区的强大文本实用程序,这篇文章主要为大家详细介绍了如何使用fdisk进行磁盘的相关操作,需要的可以了解下... 目录简介基本语法示例用法列出所有分区查看指定磁盘的区分管理指定的磁盘进入交互式模式创建一个新的分区删除一个存

C#使用HttpClient进行Post请求出现超时问题的解决及优化

《C#使用HttpClient进行Post请求出现超时问题的解决及优化》最近我的控制台程序发现有时候总是出现请求超时等问题,通常好几分钟最多只有3-4个请求,在使用apipost发现并发10个5分钟也... 目录优化结论单例HttpClient连接池耗尽和并发并发异步最终优化后优化结论我直接上优化结论吧,

SpringBoot使用Apache Tika检测敏感信息

《SpringBoot使用ApacheTika检测敏感信息》ApacheTika是一个功能强大的内容分析工具,它能够从多种文件格式中提取文本、元数据以及其他结构化信息,下面我们来看看如何使用Ap... 目录Tika 主要特性1. 多格式支持2. 自动文件类型检测3. 文本和元数据提取4. 支持 OCR(光学

JAVA系统中Spring Boot应用程序的配置文件application.yml使用详解

《JAVA系统中SpringBoot应用程序的配置文件application.yml使用详解》:本文主要介绍JAVA系统中SpringBoot应用程序的配置文件application.yml的... 目录文件路径文件内容解释1. Server 配置2. Spring 配置3. Logging 配置4. Ma

Linux使用dd命令来复制和转换数据的操作方法

《Linux使用dd命令来复制和转换数据的操作方法》Linux中的dd命令是一个功能强大的数据复制和转换实用程序,它以较低级别运行,通常用于创建可启动的USB驱动器、克隆磁盘和生成随机数据等任务,本文... 目录简介功能和能力语法常用选项示例用法基础用法创建可启动www.chinasem.cn的 USB 驱动

C#使用yield关键字实现提升迭代性能与效率

《C#使用yield关键字实现提升迭代性能与效率》yield关键字在C#中简化了数据迭代的方式,实现了按需生成数据,自动维护迭代状态,本文主要来聊聊如何使用yield关键字实现提升迭代性能与效率,感兴... 目录前言传统迭代和yield迭代方式对比yield延迟加载按需获取数据yield break显式示迭

使用SQL语言查询多个Excel表格的操作方法

《使用SQL语言查询多个Excel表格的操作方法》本文介绍了如何使用SQL语言查询多个Excel表格,通过将所有Excel表格放入一个.xlsx文件中,并使用pandas和pandasql库进行读取和... 目录如何用SQL语言查询多个Excel表格如何使用sql查询excel内容1. 简介2. 实现思路3

java脚本使用不同版本jdk的说明介绍

《java脚本使用不同版本jdk的说明介绍》本文介绍了在Java中执行JavaScript脚本的几种方式,包括使用ScriptEngine、Nashorn和GraalVM,ScriptEngine适用... 目录Java脚本使用不同版本jdk的说明1.使用ScriptEngine执行javascript2.

c# checked和unchecked关键字的使用

《c#checked和unchecked关键字的使用》C#中的checked关键字用于启用整数运算的溢出检查,可以捕获并抛出System.OverflowException异常,而unchecked... 目录在 C# 中,checked 关键字用于启用整数运算的溢出检查。默认情况下,C# 的整数运算不会自

在MyBatis的XML映射文件中<trim>元素所有场景下的完整使用示例代码

《在MyBatis的XML映射文件中<trim>元素所有场景下的完整使用示例代码》在MyBatis的XML映射文件中,trim元素用于动态添加SQL语句的一部分,处理前缀、后缀及多余的逗号或连接符,示... 在MyBATis的XML映射文件中,<trim>元素用于动态地添加SQL语句的一部分,例如SET或W