Puppeteer的基本使用及多目标同时访问

news2024/10/6 0:38:01

文章目录

      • 一、安装 puppeteer 并更改默认缓存路径
        • 1、更改 Puppeteer 用于安装浏览器的默认缓存目录
        • 2、安装 puppeteer
        • 3、项目结构目录
      • 二、基本使用
        • 1、启动浏览器并访问目标网站
        • 2、生成截图
        • 3、生成 PDF 文件
        • 4、获取目标网站 html 结构并解析
        • 5、拦截请求
        • 6、执行 JavaScript
        • 7、同时访问多个目标
        • 8、补充说明图片获取后传递至前端展示
      • 三、效果展示
      • 四、参考资料

一、安装 puppeteer 并更改默认缓存路径

1、更改 Puppeteer 用于安装浏览器的默认缓存目录

在项目文件夹根目录中创建 .puppeteerrc.cjs 文件,文件内容如下:

const {join} = require('path');

/**
 * @type {import("puppeteer").Configuration}
 */

module.exports = {
  // Changes the cache location for Puppeteer.
  cacheDirectory: join(__dirname, '.cache', 'puppeteer'),
};

注:安装 Puppeteer 时,它会自动下载最新版本的用于测试的 Chrome,该方法适用于不希望将安装的浏览器(Chrome)安装在默认路径下。浏览器默认下载到 $HOME/.cache/puppeteer 文件夹(从 Puppeteer v19.0.0 开始)。根据自身实际可跳过该步骤。

2、安装 puppeteer

yarn add puppeteer

3、项目结构目录

项目结构目录

更多安装详情及环境配置参见官网:https://pptr.nodejs.cn/

二、基本使用

1、启动浏览器并访问目标网站
const puppeteer = require('puppeteer');

// 启动浏览器
const brower = await puppeteer.launch({
    // 无头模式(默认值 true,设置为false后启动程序将弹出浏览器)
    headless: false,
    args: ['--no-sandbox', '--disable-setuid-sandbox', '--enable-accelerated-2d-canvas', '--enable-aggressive-domstorage-flushing'],
    // 忽略 https 报错
    ignoreHTTPSErrors: true,
    timeout: 120000,
});
// 创建标签页
const page = await brower.newPage();
// 设置可视区域的大小
await page.setViewport({ width: 1920, height: 800 })
// 访问目标(此处以访问百度为例)
await page.goto('https://www.baidu.com/', {
    // waitUntil: 'networkidle0',
    timeout: 120000
});

// 1、生成截图
// 2、生成PDF文件
// 3、其他...

// 关闭浏览器
await brower.close();

参数说明:

  • waitUntil:给定事件字符串,直到事件被触发,表示等待成功。
    • load:默认值,等待 load 事件触发。
    • domcontentloaded:等待 domcontentloaded 事件触发。
    • networkidle0:直到目标页面的请求不超过0个,且这一状态持续 500ms
    • networkidle2:直到目标页面的请求不超过2个,且这一状态持续 500ms

参考链接:https://pptr.nodejs.cn/api/puppeteer.puppeteerlifecycleevent

2、生成截图
...
await page.goto(...);

let imgBuffer = null;
imgBuffer = await page.screenshot({
    // 保存路径
    path: './screenshot/img.png',
    // 全屏截取
    fullPage: true,
    // 截取范围
    // clip: {x: 0, y: 0, width: 1920, height: 800}
});

await brower.close();

// 后续可封装成函数
// return imgBuffer;

imgBuffer:截图获取成功后,生成 buffer 数据,便于后续将该图片传递至前端展示。
关于 screenshot 方法的更多参数见:https://pptr.nodejs.cn/api/puppeteer.screenshotoptions/

3、生成 PDF 文件
...
await page.goto(...);

await page.pdf({
    path: `./public/pdf/article.pdf`,
    // 隐藏页眉和页脚
    displayHeaderFooter: true,
    // 页面范围(全部)
    pageRanges: '',
    // 格式
    format: 'A3',
    // scale: 1.2,
    // 生成带标签的(可访问的)PDF。
    // tagged: false,
    // 背景
    printBackground: true,
    margin: { top: '15px' }
    // outline: true,
})

await brower.close();

更多详情参见:https://pptr.nodejs.cn/api/puppeteer.pdfoptions

4、获取目标网站 html 结构并解析

此处解析使用 cheerio,安装 cheerio

yarn add cheerio

获取 html 结构:

...
await page.goto(...);

// 获取页面 html 结构
const html = await page.content();
// 有点类似于 JQuery 
const $ = cheerio.load(html);
// 获取目标元素中的属性
const link = $('#xxx .xxx').find('a').attr('href');
// 获取文本内容
const title = $('#xxx .xxx').find('a span').text();

await brower.close();
5、拦截请求
// 创建标签页
let page = await brower.newPage();
// 启用请求拦截
await page.setRequestInterception(true);

// 设置请求处理函数
page.on('request', (request) => {
    // 只允许加载HTML、CSS、JS文件,其他资源(如图片)则阻止加载,提高加载速度
    if (request.resourceType() === 'image' || request.url().endsWith('.mp4')) {
        // 终止请求
        request.abort();
    } else {
        request.continue();
    }
});

await page.goto(...);
6、执行 JavaScript
...
await page.goto(...);

await page.evaluate(async () => {
    // 获取目标元素
    const element = document.querySelector('#xxx');
    // 隐藏目标元素
    element ? element.style.display = 'none' : '';
})
7、同时访问多个目标
// 目标网站信息,可以把过滤规则写在里面
const targetUrl = {
    "url1": { 
        "url": "http://xxx.com",
        "filter": async (html) => {
            const $ = cheerio.load(html);
            // 获取文本内容
            const title = $('#xxx .xxx').find('a span').text();
            return title;
        }
    },
    "url2": { "url": "xxx",... },
}

// 启动浏览器 ... 
const brower = await puppeteer.launch({...})

// 针对不同网站获取信息
const promises = Object.keys(targetUrl).map(async (target) => {
    let page = target;
    // 创建标签页
    page = await brower.newPage();
    // 访问目标网址
    await page.goto(targetUrl[target]['url'], {
        waitUntil: 'domcontentloaded'
    });
    // 获取页面 html 结构
    const html = await page.content();
    // 针对不同的网站过滤提取不同的信息
    const titleList = await targetUrl[target]['filter'](html);
    // 关闭标签页
    await page.close();
    // 以对象的键命名
    return { [target]: titleList }
})

// 处理返回的信息,插入数据库
const data = {};
await Promise.all(promises).then((result) => {
    // 获取集合,此处使用的mongodb数据库,集合名称为 eng_news
    const engNewsTable = mongoDB.collection('eng_news');
    result.forEach((el, index) => {
        // 获取键名
        const target = Object.keys(targetUrl)[index];
        // 获取键名对应的值
        data[target] = el[target]
    })
    // 插入数据库
    engNewsTable.insertOne(data);
}).catch((error) => {
    console.log(error);
});

// 关闭浏览器
await brower.close();
8、补充说明图片获取后传递至前端展示

后端使用 express 框架:

router.post('/getTargetImg', async function (req, res, next) {
    const pdfResult = await getTargetPDF(req.body.url);

    if (pdfResult) {
        const imgBuffer = pdfResult.imgBuffer;
        if (imgBuffer) {
            // 设置 Content-Type 为 image/png
            res.setHeader('Content-Type', 'image/png');
            res.send(imgBuffer);
        } else {
            res.send(null);
        }
    } else {
        res.send(null);
    }
})

前端使用 vue3 接收:

await getTargetImgAPI({ url: url }).then(
    (response) => {
        if (response.data) {
            // 图片获取成功 ...
            const blob = new Blob([response.data], { type: "image/png" });
            const url = URL.createObjectURL(blob);
            
        } else {
            // 图片获取失败
            ...
        }
    },
    (error) => {
        console.log(error);
    }
);

前端获取到 buffer 数据并处理完成后,生成的 url 可直接放在 img 标签的 :src 中使用。例:<img :src="xx">

三、效果展示

效果展示

四、参考资料

  • https://pptr.nodejs.cn/
  • https://blog.csdn.net/zhai_865327/article/details/104792646
  • https://juejin.cn/post/7047794666191716383
  • https://juejin.cn/post/6923868889306644488
  • https://zhuanlan.zhihu.com/p/76237595

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

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

相关文章

(Java)心得:LeetCode——18.四数之和

一、原题 给你一个由 n 个整数组成的数组 nums &#xff0c;和一个目标值 target 。请你找出并返回满足下述全部条件且不重复的四元组 [nums[a], nums[b], nums[c], nums[d]] &#xff08;若两个四元组元素一一对应&#xff0c;则认为两个四元组重复&#xff09;&#xff1a; …

【CTF Web】QSNCTF 文章管理系统 Writeup(SQL注入+Linux命令+RCE)

文章管理系统 题目描述 这是我们的文章管理系统&#xff0c;快来看看有什么漏洞可以拿到FLAG吧&#xff1f;注意&#xff1a;可能有个假FLAG哦 解法 SQL 注入。 ?id1 or 11 --取得假 flag。 爆库名。 ?id1 union select 1,group_concat(schema_name) from information_sch…

反调试 - ptrace占坑

ptrace占坑 这是ptrace占坑的标志。 ptrace可以让一个进程监视和控制另一个进程的执行,并且修改被监视进程的内存、寄存器等,主要应用于调试器的断点调试、系统调用跟踪等。 在Android app保护中,ptrace被广泛用于反调试。一个进程只能被ptrace一次,如果先调用了ptrace方法,那…

AI办公自动化-用kimi把PDF文档按照章节自动拆分成多个docx文档

一个PDF文档很长&#xff0c;希望按照章节分拆成小文档。 可以在kimichat中输入提示词&#xff1a; 你是一个Python编程专家&#xff0c;要完成一个编写拆分PDF文档的Python脚本的任务&#xff0c;具体步骤如下&#xff1a; 打开文件夹&#xff1a;D:\chatgpt图书\图书1&…

爬虫工作量由小到大的思维转变---<第七十三章 > Scrapy爬虫详解一下HTTPERROE的问题

前言&#xff1a; 在我们的日常工作中&#xff0c;有时会忽略一些工具或组件的重要性&#xff0c;直到它们引起一连串的问题&#xff0c;我们才意识到它们的价值。正如在Scrapy框架中的HttpErrorMiddleware&#xff08;HTTP错误中间件&#xff09;一样&#xff0c;在开始时&…

JVM调优:JVM中的垃圾收集器详解

JVM&#xff08;Java Virtual Machine&#xff09;垃圾收集器是Java虚拟机中的一个重要组件&#xff0c;负责自动管理Java堆内存中的对象。垃圾收集器的主要任务是找出那些不再被程序使用的对象&#xff0c;并释放它们占用的内存&#xff0c;以便为新的对象分配空间。这个过程被…

ES6 笔记02

目录 01 对象的扩展 02 链判断运算符 03 属性名表达式 04 Symbol 类型 05 set集合的使用 06 Map集合的使用 07 Set集合和Map集合的遍历方式 08 iterator迭代器 01 对象的扩展 对象的属性和方法的简洁表示: es6允许在字面量对象里面直接写变量名 let 变量名变量值; let …

Hexo博客重新部署与Git配置

由于电脑重装了一次&#xff0c;发现之前Hexo与NexT主题版本过于落后&#xff0c;重新部署了下。 1 Node.js与git安装 这一块安装就不赘述了。去两个官网找安装文件安装即可。 node.js git 打开git以后配置的几个关键命令行。 git config --global user.name "你的gi…

langchain 自定义模型使用

目录 背景 参考 实现 调用 背景 在公司有大模型可以通过 api 方式调用&#xff0c;想使用 langchain 框架调用&#xff0c;langchina 已经封装好大部分模型了&#xff0c;但自己公司的模型不支持&#xff0c;想使用&#xff0c;相当于自定义模型 参考 Custom Chat Model …

基于Springboot的家教管理系统(有报告)。Javaee项目,springboot项目。

演示视频&#xff1a; 基于Springboot的家教管理系统&#xff08;有报告&#xff09;。Javaee项目&#xff0c;springboot项目。 项目介绍&#xff1a; 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#xff09;三层体系结构&…

Idea插件Easy-Code模板文件

目录 需要引入的依赖application.yml.vmapplication-dev.yml.vmresult.java.vm (统一返回集)resultCodeEnum.java.vm &#xff08;统一返回集需要的枚举类&#xff09;globalCorsConfig.java.vm &#xff08;全局跨域处理&#xff09;entity.java.vm &#xff08;实体类&#x…

【科研绘图 基础版】01 使用Python绘制时间序列折线图

下面这段代码绘制了一个折线图&#xff0c;其中包含了实际平均温度数据和使用线性回归模型预测的平均温度数据&#xff08;用来近似地表示数据的整体趋势&#xff09;。 具体来说&#xff0c;图中的横轴表示年份&#xff0c;纵轴表示平均温度。蓝色的实心线代表了实际的平均温度…

【Mac】Perfectly Clear Workbench(智能图像清晰修复软件)安装教程

软件介绍 Perfectly Clear Workbench是由Athentech Imaging开发的一款图像处理软件&#xff0c;旨在帮助用户快速、轻松地优化和改善数字照片的质量。以下是Perfectly Clear Workbench的一些主要特点和功能&#xff1a; 1.自动图像优化 该软件采用先进的图像处理算法&#xf…

StarRocks 【新一代MPP数据库】

1、StarRocks 1.1、StarRocks 简介 StarRocks 是新一代极速全场景 MPP (Massively Parallel Processing&#xff0c;MPP数据库是一种基于大规模并行处理技术的数据库系统&#xff0c;旨在高效处理大量数据。) 数据库。StarRocks 的愿景是能够让用户的数据分析变得更加简单和敏…

设计模式:迭代器模式(Iterator)

设计模式&#xff1a;迭代器模式&#xff08;Iterator&#xff09; 设计模式&#xff1a;迭代器模式&#xff08;Iterator&#xff09;模式动机模式定义模式结构时序图模式实现在单线程环境下的测试在多线程环境下的测试模式分析优缺点适用场景应用场景参考 设计模式&#xff1…

第五百回 Get路由管理

文章目录 1. 概念介绍2. 使用方法2.1 普通路由2.2 命名路由 3. 示例代码4. 内容总结 我们在上一章回中介绍了"使用get显示Dialog"相关的内容&#xff0c;本章回中将介绍使用get进行路由管理.闲话休提&#xff0c;让我们一起Talk Flutter吧。 1. 概念介绍 我们在本章…

什么是分库分表

读写分离主要应对的是数据库读并发&#xff0c;没有解决数据库存储问题。试想一下&#xff1a;如果 MySQL 一张表的数据量过大怎么办? 答案当然是分库分表 什么是分库&#xff1f; 分库 就是将数据库中的数据分散到不同的数据库上&#xff0c;可以垂直分库&#xff0c;也可…

一二三应用开发平台使用手册——系统管理-系统参数系统日志-使用说明

系统参数 概述 通过配置化&#xff0c;可以提升系统灵活性和运维便利性。 配置化往往分为两大类&#xff0c;一类是偏技术层面的&#xff0c;如平台的发送邮件提醒的邮箱&#xff0c;相对固化&#xff0c;不会频繁调整&#xff0c;一般放在系统的配置文件里&#xff0c;如spr…

目标检测——印度车辆数据集

引言 亲爱的读者们&#xff0c;您是否在寻找某个特定的数据集&#xff0c;用于研究或项目实践&#xff1f;欢迎您在评论区留言&#xff0c;或者通过公众号私信告诉我&#xff0c;您想要的数据集的类型主题。小编会竭尽全力为您寻找&#xff0c;并在找到后第一时间与您分享。 …

MySQL前缀索引、脏页和干净页、COUNT(*)讨论、表删除内存问题

文章目录 如何加索引如何给身份证号添加索引 SQL语句变慢脏页 (Dirty Pages)干净页 (Clean Pages)为何区分脏页和干净页处理脏页管理策略 flush如何控制 为什么删除表数据后表文件大小不变问题背景核心原因数据存储方式参数影响 解决方案1. 调整innodb_file_per_table设置2. 使…