在这里插入图片描述

在现代的Web开发和爬虫开发中,Puppeteer是一个非常强大的工具,它可以帮助我们自动化浏览器操作,提取页面内容。本文将从初阶到高阶,详细介绍如何使用Puppeteer提取页面内容的各种技巧,特别关注多层类关系选择器的使用。

初阶技巧

1. 提取单个元素的文本内容

使用page.$page.evaluate来提取单个元素的文本内容。

const titleElement = await page.$('h1');
const title = await titleElement.getProperty('textContent').then(t => t.jsonValue());
console.log(title);

2. 提取多个元素的文本内容

使用page.$$page.$$eval来提取多个元素的文本内容。

const spanTexts = await page.$$eval('span', spans => spans.map(span => span.textContent));
console.log(spanTexts);

3. 提取元素的属性

使用page.$page.evaluate来提取单个元素的属性。

const linkElement = await page.$('a');
const href = await linkElement.getProperty('href').then(h => h.jsonValue());
console.log(href);

4. 提取多个元素的属性

使用page.$$page.$$eval来提取多个元素的属性。

const links = await page.$$eval('a', links => links.map(link => link.getAttribute('href')));
console.log(links);

中阶技巧

1. 提取嵌套元素的内容

使用page.evaluate来提取嵌套元素的内容。

const nestedData = await page.evaluate(() => {const items = document.querySelectorAll('.item');return Array.from(items).map(item => ({title: item.querySelector('h2').textContent,description: item.querySelector('p').textContent}));
});
console.log(nestedData);

2. 提取动态加载的内容

使用page.waitForSelector来等待动态加载的内容。

await page.waitForSelector('.dynamic-content');
const dynamicContent = await page.$eval('.dynamic-content', el => el.textContent);
console.log(dynamicContent);

3. 提取页面中的JSON数据

使用page.evaluate来提取页面中的JSON数据。

const jsonData = await page.evaluate(() => {const script = document.querySelector('script[type="application/json"]');return JSON.parse(script.textContent);
});
console.log(jsonData);

4. 提取页面中的表单数据

使用page.$$eval来提取表单中的数据。

const formData = await page.$$eval('form input', inputs => {return inputs.map(input => ({name: input.name,value: input.value}));
});
console.log(formData);

高阶技巧

1. 提取复杂选择器的内容

使用page.$$eval来提取复杂选择器的内容。例如,提取content .top .info:last-child span:last-child的内容。

const complexData = await page.$$eval('.content .top .info:last-child span:last-child', spans => {return spans.map(span => ({text: span.textContent,}));
});
console.log(complexData);

2. 提取页面中的所有数据

使用page.evaluate来提取页面中的所有数据。

const allData = await page.evaluate(() => {const data = {};document.querySelectorAll('*').forEach(el => {if (el.textContent.trim() !== '') {data[el.tagName.toLowerCase()] = el.textContent;}});return data;
});
console.log(allData);

3. 提取页面中的所有链接和内容

使用page.$$eval来提取页面中的所有链接和内容。

const linksAndContent = await page.$$eval('a', links => {return links.map(link => ({href: link.href,text: link.textContent}));
});
console.log(linksAndContent);

4. 提取页面中的所有图片和内容

使用page.$$eval来提取页面中的所有图片和内容。

const imagesAndContent = await page.$$eval('img', images => {return images.map(image => ({src: image.src,alt: image.alt}));
});
console.log(imagesAndContent);

5. 提取页面中的所有表格数据

使用page.$$eval来提取页面中的所有表格数据。

const tableData = await page.$$eval('table', tables => {return tables.map(table => {const rows = Array.from(table.querySelectorAll('tr'));return rows.map(row => {const cells = Array.from(row.querySelectorAll('td, th'));return cells.map(cell => cell.textContent);});});
});
console.log(tableData);

6. 提取页面中的所有脚本数据

使用page.$$eval来提取页面中的所有脚本数据。

const scriptData = await page.$$eval('script', scripts => {return scripts.map(script => script.textContent);
});
console.log(scriptData);

7. 提取页面中的所有样式数据

使用page.$$eval来提取页面中的所有样式数据。

const styleData = await page.$$eval('style', styles => {return styles.map(style => style.textContent);
});
console.log(styleData);

复杂选择器的使用技巧

1. 提取特定类名的最后一个子元素

使用page.$$eval来提取特定类名的最后一个子元素。

const lastChildData = await page.$$eval('.content .top .info:last-child span:last-child', spans => {return spans.map(span => ({text: span.textContent,}));
});
console.log(lastChildData);

2. 提取特定类名的最后一个子元素的属性

使用page.$$eval来提取特定类名的最后一个子元素的属性。

const lastChildAttributes = await page.$$eval('.content .top .info:last-child span:last-child', spans => {return spans.map(span => ({text: span.textContent,className: span.className,id: span.id}));
});
console.log(lastChildAttributes);

3. 提取特定类名的最后一个子元素的子元素

使用page.$$eval来提取特定类名的最后一个子元素的子元素。

const nestedChildData = await page.$$eval('.content .top .info:last-child span:last-child', spans => {return spans.map(span => ({text: span.textContent,nestedText: Array.from(span.querySelectorAll('span')).map(nestedSpan => nestedSpan.textContent)}));
});
console.log(nestedChildData);

4. 提取特定类名的直接子元素

使用page.$$eval来提取特定类名的直接子元素。

const directChildren = await page.$$eval('.content > .top', elements => {return elements.map(el => ({text: el.textContent,className: el.className}));
});
console.log(directChildren);

5. 提取特定类名的二代子元素

使用page.$$eval来提取特定类名的二代子元素。

const secondLevelChildren = await page.$$eval('.content .top > .info', elements => {return elements.map(el => ({text: el.textContent,className: el.className}));
});
console.log(secondLevelChildren);

6. 提取特定类名的多代子元素

使用page.$$eval来提取特定类名的多代子元素。

const multiLevelChildren = await page.$$eval('.content .top .info span', elements => {return elements.map(el => ({text: el.textContent,className: el.className}));
});
console.log(multiLevelChildren);

7. 提取特定类名的多代子元素的属性

使用page.$$eval来提取特定类名的多代子元素的属性。

const multiLevelChildrenAttributes = await page.$$eval('.content .top .info span', elements => {return elements.map(el => ({text: el.textContent,className: el.className,id: el.id}));
});
console.log(multiLevelChildrenAttributes);

类的层次关系说明

1. 直接子元素选择器 (>)

直接子元素选择器用于选择某个元素的直接子元素。例如,选择.content类下的直接子元素.top

const directChildren = await page.$$eval('.content > .top', elements => {return elements.map(el => ({text: el.textContent,className: el.className}));
});
console.log(directChildren);

2. 二代子元素选择器

二代子元素选择器用于选择某个元素的二代子元素。例如,选择.content类下的二代子元素.info

const secondLevelChildren = await page.$$eval('.content .top > .info', elements => {return elements.map(el => ({text: el.textContent,className: el.className}));
});
console.log(secondLevelChildren);

3. 多代子元素选择器

多代子元素选择器用于选择某个元素的多代子元素。例如,选择.content类下的多代子元素span

const multiLevelChildren = await page.$$eval('.content .top .info span', elements => {return elements.map(el => ({text: el.textContent,className: el.className}));
});
console.log(multiLevelChildren);

4. 多代子元素的属性选择器

多代子元素的属性选择器用于选择某个元素的多代子元素及其属性。例如,选择.content类下的多代子元素span及其属性:

const multiLevelChildrenAttributes = await page.$$eval('.content .top .info span', elements => {return elements.map(el => ({text: el.textContent,className: el.className,id: el.id}));
});
console.log(multiLevelChildrenAttributes);

总结

从初阶到高阶,这些技巧可以帮助你逐步掌握如何使用Puppeteer提取页面的各种内容。初阶技巧主要集中在基本的元素选择和属性提取上,中阶技巧则涉及到动态内容的等待和嵌套元素的提取,高阶技巧则更加复杂,可以提取页面中的所有数据,包括表格、脚本、样式等。通过这些技巧,你可以应对各种复杂的页面爬取任务。

希望这篇文章对你有所帮助!如果你有任何问题或建议,请随时在评论区留言。

以我之思,借AI之力

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

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SQL server 获取表中所有行的序号

在SQL Server中,要获取某个表中的某一行所在的记录总数,通常有几种方法可以实现,具体使用哪种方法取决于你的具体需求。以下是几种常见的方法: 1. 使用COUNT()函数结合子查询 如果你想要知道某个特定行在表中的位置(…

《CSDN 用户视角:见证 AI 重构企业办公,在智能协同、数据驱动下实现组织进化》

在数字化转型的大潮汹涌而至的当下,人工智能(AI)宛如一场疾风骤雨,以前所未有的速度重塑着企业办公的格局。从琐碎流程的自动化,到智能决策的深度赋能,AI 技术正掀起一场对传统工作模式的彻底颠覆&#xff…

PYQT实战:天气助手

应用采用了现代化的界面设计,包括圆角边框、卡片式布局和响应式建议功能。 这个天气应用可以作为学习PyQt5开发的实例,展示了GUI设计、定时更新、数据处理和用户交互的实现方法 #!/usr/bin/env python # -*- coding: GBK -*- import sys import request…

PL-SLAM: Real-Time Monocular Visual SLAM with Points and Lines

PL-SLAM 文章目录 PL-SLAM摘要系统介绍综述方法综述LINE-BASED SLAM一、基于线的SLAM二、基于线和点的BA三、全局重定位使用线条初始化地图实验结果说明位姿求解三角化LSD 直线检测算法📊 **一、核心原理**⚙️ **二、实现方法**📐 **三、应用场景**⚖️ **四、优缺点与优化…

快速手搓一个MCP服务指南(八):FastMCP 代理服务器:构建灵活的 MCP 服务中介层

在分布式系统和微服务架构日益普及的今天,服务间的通信与集成变得至关重要。FastMCP 从 2.0.0 版本引入的代理服务器功能,为 MCP (Model Context Protocol) 生态提供了强大的服务中介能力。本文将深入解析 FastMCP 代理服务器的核心概念、应用场景与实践…

Ubuntu20下安装SAMBA服务

1、安装Samba: 在 Ubuntu 上,打开终端,并运行以下命令以安装 Samba sudo apt update sudo apt install samba 2、配置共享目录 修改共享目录的权限,我的共享目录是samba_share sudo chmod -R 777 ./samba_share 创建Samba用户账号 sud…

Python 数据分析与机器学习入门 (一):环境搭建与核心库概览

Python 数据分析与机器学习入门 (一):环境搭建与核心库概览 本文摘要 本文是 Python 数据分析与机器学习入门系列的第一篇,专为初学者设计。文章首先阐明了 Python在数据科学领域的优势,然后手把手指导读者如何使用 Anaconda 搭建一个无痛、专…

编译UltraleapTrackingWebSocket

最近要在项目中用到 Leap Motion,无意中发现了一个 Go 语言的 Leap Motion 库: https://gobot.io/documentation/platforms/leapmotion/ 示例代码看起来很简单,但是要实际运行起来还需要一些条件。 在示例代码中,我们看到它连接…

[ linux-系统 ] 磁盘与文件系统

1.认识磁盘结构 机械键盘是计算机中唯一的机械设备,磁盘是外设,容量大,速度慢,价格便宜 物理结构: 磁头是一面一个,左右摆动,两个整体移动的,有磁头停靠点磁头和盘面不接触&#x…

Spring AI RAG

目录 Spring AI 介绍 Spring AI 组件介绍 Spring AI 结构化输出 Srping AI 多模态 Spring AI 本地Ollama Spring AI 源码 Spring AI Advisor机制 Spring AI Tool Calling Spring AI MCP Spring AI RAG Spring AI Agent 一、技术架构与核心流程‌ 检索增强生成 (RA…

深入Linux开发核心:掌握Vim编辑器与GCCG++编译工具链

文章目录 一、Vim:终端环境下的编辑艺术1.1 Vim设计哲学:模态编辑的终极实践1.2 高效导航:超越方向键的移动艺术1.3 定制化开发环境:从基础到专业IDE1.4 调试集成:Vim作为调试前端 二、GCC/G:Linux编译基石…

阿里云-spring boot接入arms监控

目标:在ecs中启动一个java应用,且携带arms监控 原理:在java应用启动时,同时启动一个agent探针,时刻监控java应用变化(如:接口调用、CPU、线程池状态等) 1.arms接入中心添加java应用…

昆泰芯3D霍尔磁传感器芯片在汽车零部件中的应用

HUD即抬头显示系统(Head-Up Display),HUD 是一种将重要的车辆或飞行等相关信息(如速度、导航指示、警告信息等)投射到驾驶员或操作员前方视野范围内的透明显示屏或直接投射到风挡玻璃上的技术。 HUD即抬头显示系统(Head-Up Display)&#xff…

new Vue() 的底层工作原理

当你调用 new Vue() 时,Vue.js 会执行一系列复杂的初始化过程。让我们深入剖析这个看似简单的操作背后发生的事情: 1. 初始化阶段 (1) 内部初始化 function Vue(options) {if (!(this instanceof Vue)) {warn(Vue is a constructor and should be cal…

最简安装SUSE15SP7导致大部分命令缺失

我嘞个去~~~明明选择Enable了ssh,结果也没给装。 俺习惯使用NetworkManager管理网络,没给装,用不了nmcli和nmtui。不高兴归不高兴,最简安装的话,也情有可原。我嘞个去去~~连ping、vi都没有装,这也太简了。…

Vue-14-前端框架Vue之应用基础嵌套路由和路由传参

文章目录 1 嵌套路由1.1 News.vue1.2 Detail.vue1.3 router/index.ts2 路由传参2.1 query参数2.1.1 News.vue(传递参数)2.1.2 Detail.vue(接收参数)2.2 params参数2.2.1 router/index.ts(需要提前占位)2.2.2 News.vue(传递参数)2.2.3 Detail.vue(接收参数)2.3 props配置2.3.1 r…

Python网安-ftp服务暴力破解(仅供学习)

目录 源码在这里 需要导入的模块 连接ftp,并设置密码本和线程 核心代码 设置线程 源码在这里 https://github.com/Wist-fully/Attack/tree/cracker 需要导入的模块 import ftplib from threading import Thread import queue 连接ftp,并设置密码…

ES6数组的`flat()`和`flatMap()`函数用法

今天给大家分享ES6中两个超实用的数组函数:flat()和flatMap(),学会它们能让数组处理变得更轻松! 1. flat()函数 1.1 基本介绍 flat()用于将嵌套数组"拍平",即将多维数组转换为一维数组。 1.2 语法 const newArray …

upload-labs靶场通关详解:第15-16关

第十五关 getimagesize函数验证 一、分析源代码 function isImage($filename){$types .jpeg|.png|.gif;if(file_exists($filename)){$info getimagesize($filename);$ext image_type_to_extension($info[2]);if(stripos($types,$ext)>0){return $ext;}else{return false…

【Linux】基础IO流

好的代码自己会说话,清晰的逻辑与优雅的结构,是程序员与世界对话的方式。 前言 这是我自己学习Linux系统编程的第五篇笔记。后期我会继续把Linux系统编程笔记开源至博客上。 上一期笔记是关于进程: 【Linux】进程-CSDN博客https://blog.csdn…