Puppeteer Web 抓取:使用 Browserless 的 Docker

news2024/9/23 0:35:20

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

    // 导航到目标 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
{
  "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 条提示

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2074642.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

虚拟机Ubuntu误操作导致无法自动联网的解决办法

直接上解决办法:安装netplan.io。 sudo apt install netplan.io sudo netplan apply 问题描述: 虚拟机的Ubuntu由于我的乱操作不小心删除了很多东西,导致开机无法自动联网了。而且在设置里边也没了设置网络的地方。 尝试不同办法发现用sudo…

基于javaweb+jsp的鲜花商城系统

基于javawebjsp的鲜花商城系统的设计与实现~ 开发语言:Java 数据库:MySQL 技术:SpringSpringMVCMyBatisJSP 工具:IDEA/Ecilpse、Navicat、Maven 系统展示 前台 后台 摘要 当下,正处于信息化的时代,许多行…

超越GPT4V,最强多模态MiniCPM-V2.6模型分享

MiniCPM-V2.6是由OpenBMB开发的一款多模态大型语言模型(MLLM),专为视觉-语言理解设计。 MiniCPM-V2.6模型能够处理图像、视频和文本输入,并提供高质量的文本输出。 MiniCPM-V 2.6模型在单图像理解方面超越了广泛使用的专有模型&…

78 Linux libusb库USB HID应用编程笔记

1 前言 这几天搞另外一个项目,基于Ubuntu开发一个小的应用程序,就是通过USB HID与设备通信。因此需要在Linux环境编写对应USB HID通信应用。 目前libusb库已经很好的支持USB相关应用的开发,库中提供了丰富的USB接口,用户可以直接调…

gptk是什么意思?Mac电脑如何在crossover里安装gptk2.0测试版?借助GPTK玩《原神》《黑神话悟空》游戏

很人多都听说使用 gptk2.0 beta 可以让《黑神话:悟空》等游戏的帧数提高,但自己并不知道如何安装,下面就给大家说下如何在crossover里安装 gptk2.0 beta 。安装前请先确认自己的电脑里已经安装好了crossover软件。 Game Porting Toolkit 简介…

【MySQL】MySQL表的增删改查(初阶)

欢迎关注个人主页:逸狼 创造不易,可以点点赞吗~ 如有错误,欢迎指出~ 目录 表内容操作 插入内容 按顺序插入 指定某些列插入 一次插入多行记录 插入时间 查询表内容 全列查询 指定列查询 指定表达式查询 用as取别名 ​编辑 去重查询 排序查询…

堆排序算法及优化(java)

目录 1.1 引言 1.2 堆排序的历史 1.3 堆排序的基本原理 1.3.1 堆的概念 1.3.2 堆排序的过程 1.3.3 堆调整 1.3.4 堆排序算法流程 1.4 堆排序的Java实现 1.4.1 简单实现 1.4.2 代码解释 1.4.3 优化实现 1.4.4 代码解释 1.5 堆排序的时间复杂度 1.5.1 分析 1.5.2 …

Flutter ListView滑动

在Flutter中,ScrollController可以精确地控制和管理滚动行为。通过ScrollController,可以监听滚动的位置、速度,甚至可以在用户滚动时触发自定义的动作。此外,ScrollController还提供了对滚动位置的直接控制,可以编程地…

Aiseesoft PDF Converter Ultimate 3.3.62 + crack

Aiseesoft PDF Converter Ultimate 是一个用于将 PDF 文件转换为其他格式的程序。它允许您将 PDF 转换为 Word、Text、Excel、PowerPoint、ePub、HTML、JPG、TIFF、PNG、GIF 等。 以下是该程序主要功能的简要说明: 支持不同的格式。该程序支持超过 25 种不同的格式,用于从 P…

PyTorch深度学习网络(一:MLP)

全连接神经网络,又称多层感知机(MLP),是深度学习最基础的神经网络。全连接神经网络主要由输入层、隐藏层和输出层构成。本文实现了一个通用MLP网络,包括以下功能: 根据输入的特征数、类别数、各隐藏层神经…

Canvas 动画: atan2 三角函数与鼠标跟随效果

这个案例展示了如何使用HTML5的Canvas和JavaScript实现一个动态效果:在画布上绘制一个箭头,并让它实时跟随鼠标移动。这个小项目不仅有趣,还能帮助你理解编程和基本数学概念的实际应用。 项目需求 我们的目标是在一个画布上绘制一个箭头&…

java-4 final、单例类、枚举类、抽象类、接口

final 1. 认识final 2. 常量 大项目中经常将常量集中写在Constant文件中 单例类 (设计模式) 为什么要把构造器私有化,你不是私有化,别人就可以 new 好多个对象,还怎么是单例吖 定义一个类变量、类方法,…

海外媒体宣发:著名媒体【越南通讯社VNanet】发布新闻稿

海外媒体宣发:著名媒体【越南通讯社VNanet】发布新闻稿 近日,越南通讯社VNanet发布了一篇关于全球气候变化的新闻稿,引起了广泛关注。本文将详细介绍新闻稿的主要内容以及其对全球气候变化的影响。 一、新闻稿概述 越南通讯社VNanet作为越…

解决WIndows10下更新蓝牙驱动屡屡失败问题

因为换了个1T自带Win10系统的SSD硬盘,导致蓝牙驱动死活装不上了。驱动精灵,官方驱动都没用。这可前所未闻啊。 想起换下来的硬盘系统里面还有系统在,试试看能不能直接用之前的系统蓝牙驱动,原则上是应该没问题的。所以就将之前的…

混合现实UI优化:利用物理环境的直接交互

随着虚拟现实(VR)和混合现实(MR)技术的发展,用户界面(UI)的设计变得越来越重要,尤其是在需要适应多种物理环境的情况下。本文将介绍一种名为 InteractionAdapt 的用户界面优化方法,它专为VR环境中的工作空间适配而设计,能够有效利用物理环境,为用户提供更加灵活和个…

Kafka的Offset(偏移量)详解

Kafka的Offset详解 1、生产者Offset2、消费者Offset2.1、消费者2.2、生产者2.3、实体类对象2.4、JSON工具类2.5、项目配置文件2.6、测试类2.7、测试2.8、总结 1、生产者Offset 2、消费者Offset 2.1、消费者 package com.power.consumer;import org.apache.kafka.clients.consu…

Android - 自定义view

为什么要自定义view? 在Android开发中有很多业务场景,原生的控件无法满足需求,并且经常也会遇到一个UI在多处重复使用情况,于是可以通过自定义View的方式来实现这些UI效果。 自定义view的分类 自定义属性 Window window是一个…

图数据库查询语言 cypher 与 memgraph

Cyper 作为声明式查询语言, SQL 在计算机行业无人不晓, 无人不知. 而 Cypher 就是 Graph Database 图数据库的 SQL. Cypher 用"圆括号"来表示节点, 用"方括号,连接线及箭头"表示关系 这样一句话 - "Sally likes Graphs. Sally is friends with John. …

完成控制器方法获取参数-@RequestParam

文章目录 1.将方法的request和response参数封装到参数数组1.SunDispatcherServlet.java1.根据方法信息,返回实参列表2.具体调用 2.测试 2.封装Http请求参数到参数数组1.自定义RequestParam注解2.MonsterController.java 增加参数3.SunDispatcherServlet.java1.resol…

软件架构的发展经历了从单体结构、垂直架构、SOA架构到微服务架构的过程剖析

1.单体架构 特点: 1、所有的功能集成在一个项目工程中。 2、所有的功能打一个war包部署到服务器。 3、应用与数据库分开部署。 4、通过部署应用集群和数据库集群来提高系统的性能。 优点: 1、项目架构简单,前期开发成本低,周期短,小型项目的首选。 缺点: 1、全部…