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

相关文章

Java中String字符串使用避坑指南

《Java中String字符串使用避坑指南》Java中的String字符串是我们日常编程中用得最多的类之一,看似简单的String使用,却隐藏着不少“坑”,如果不注意,可能会导致性能问题、意外的错误容... 目录8个避坑点如下:1. 字符串的不可变性:每次修改都创建新对象2. 使用 == 比较字符串,陷阱满

Python使用国内镜像加速pip安装的方法讲解

《Python使用国内镜像加速pip安装的方法讲解》在Python开发中,pip是一个非常重要的工具,用于安装和管理Python的第三方库,然而,在国内使用pip安装依赖时,往往会因为网络问题而导致速... 目录一、pip 工具简介1. 什么是 pip?2. 什么是 -i 参数?二、国内镜像源的选择三、如何

使用C++实现链表元素的反转

《使用C++实现链表元素的反转》反转链表是链表操作中一个经典的问题,也是面试中常见的考题,本文将从思路到实现一步步地讲解如何实现链表的反转,帮助初学者理解这一操作,我们将使用C++代码演示具体实现,同... 目录问题定义思路分析代码实现带头节点的链表代码讲解其他实现方式时间和空间复杂度分析总结问题定义给定

Linux使用nload监控网络流量的方法

《Linux使用nload监控网络流量的方法》Linux中的nload命令是一个用于实时监控网络流量的工具,它提供了传入和传出流量的可视化表示,帮助用户一目了然地了解网络活动,本文给大家介绍了Linu... 目录简介安装示例用法基础用法指定网络接口限制显示特定流量类型指定刷新率设置流量速率的显示单位监控多个

ElasticSearch+Kibana通过Docker部署到Linux服务器中操作方法

《ElasticSearch+Kibana通过Docker部署到Linux服务器中操作方法》本文介绍了Elasticsearch的基本概念,包括文档和字段、索引和映射,还详细描述了如何通过Docker... 目录1、ElasticSearch概念2、ElasticSearch、Kibana和IK分词器部署

JavaScript中的reduce方法执行过程、使用场景及进阶用法

《JavaScript中的reduce方法执行过程、使用场景及进阶用法》:本文主要介绍JavaScript中的reduce方法执行过程、使用场景及进阶用法的相关资料,reduce是JavaScri... 目录1. 什么是reduce2. reduce语法2.1 语法2.2 参数说明3. reduce执行过程

如何使用Java实现请求deepseek

《如何使用Java实现请求deepseek》这篇文章主要为大家详细介绍了如何使用Java实现请求deepseek功能,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录1.deepseek的api创建2.Java实现请求deepseek2.1 pom文件2.2 json转化文件2.2

python使用fastapi实现多语言国际化的操作指南

《python使用fastapi实现多语言国际化的操作指南》本文介绍了使用Python和FastAPI实现多语言国际化的操作指南,包括多语言架构技术栈、翻译管理、前端本地化、语言切换机制以及常见陷阱和... 目录多语言国际化实现指南项目多语言架构技术栈目录结构翻译工作流1. 翻译数据存储2. 翻译生成脚本

C++ Primer 多维数组的使用

《C++Primer多维数组的使用》本文主要介绍了多维数组在C++语言中的定义、初始化、下标引用以及使用范围for语句处理多维数组的方法,具有一定的参考价值,感兴趣的可以了解一下... 目录多维数组多维数组的初始化多维数组的下标引用使用范围for语句处理多维数组指针和多维数组多维数组严格来说,C++语言没

在 Spring Boot 中使用 @Autowired和 @Bean注解的示例详解

《在SpringBoot中使用@Autowired和@Bean注解的示例详解》本文通过一个示例演示了如何在SpringBoot中使用@Autowired和@Bean注解进行依赖注入和Bean... 目录在 Spring Boot 中使用 @Autowired 和 @Bean 注解示例背景1. 定义 Stud