Puppeteer让你网页操作更简单(2)抓取数据

Puppeteer让你网页操作更简单(1)屏幕截图】

示例2 —— 让我们抓取一些数据

现在您已经了解了Headless Chrome和Puppeteer的工作原理基础知识,让我们看一个更复杂的示例,其中我们实际上可以抓取一些数据。

首先,请查看此处的Puppeteer API文档。如您所见,有大量不同的方法我们可以使用不仅可以在网站上点击,还可以填写表单、输入内容并读取数据。

在本教程中,我们将抓取Books To Scrape,这是一家专门用于帮助人们练习抓取的假书店。

在同一目录中创建一个名为scrape.js的文件,并插入以下样板代码:

const puppeteer = require('puppeteer');let scrape = async () => {// Actual Scraping goes Here...// Return a value
};scrape().then((value) => {console.log(value); // Success!
});

理想情况下,经过第一个示例的学习,上述代码对您来说是有意义的。 如果不是,没关系!

我们上面所做的就是要求之前安装的 puppeteer 依赖项。然后我们有 scrape() 函数,我们将在其中输入抓取代码。该函数将返回一个值。最后,我们调用 scrape 函数并处理返回值(将其记录到控制台)。

我们可以通过在 scrape 函数中添加一行代码来测试上述代码。试试这个:

let scrape = async () => {return 'test'; 
};

现在在控制台中运行 node scrape.js。您应该会看到 test 被返回!完美,我们的返回值被记录到了控制台。现在我们可以开始填充 scrape 函数了。

步骤 1:设置

我们需要做的第一件事是创建浏览器的实例,打开一个新页面,并导航到一个 URL。我们是这样做的:

let scrape = async () => {const browser = await puppeteer.launch({headless: false});const page = await browser.newPage();await page.goto('http://books.toscrape.com/');await page.waitFor(1000);  // 抓取browser.close();return result;
};

很棒!让我们一行一行地分解它:

首先,我们创建浏览器并将 headless 模式设置为 false。这使我们可以完全看到正在发生的事情:

const browser = await puppeteer.launch({headless: false}); 

然后,我们在浏览器中创建一个新页面:

const page = await browser.newPage();

接下来,我们转到 books.toscrape.com URL:

await page.goto('http://books.toscrape.com/');

另外,我添加了 1000 毫秒的延迟。虽然通常不必要,但这可以确保页面上的所有内容都加载:

await page.waitFor(1000);

最后,完成所有工作后,我们将关闭浏览器并返回结果。

browser.close();
return result; 

设置完成。现在,让我们开始抓取!

步骤 2:抓取

如您到目前所了解的,Books to Scrape 有大量真实书籍和这些书籍的虚拟数据。我们要做的是选择页面上的第一本书,并返回该书的标题和价格。这是 Books to Scrape 的主页。我有兴趣单击第一本书(如下红色突出显示)

查看 Puppeteer API,我们可以找到允许我们在页面上点击的方法:

page.click(selector[, options])

  • selector 要搜索要单击的元素的选择器。如果有多个元素满足选择器,将单击第一个元素。

幸运的是,Google Chrome 开发者工具可以非常轻松地确定特定元素的选择器。只需右键单击图像并选择检查:

这将打开元素面板,元素被突出显示。您现在可以在左侧单击三个点,选择复制,然后选择复制选择器:

太棒了!我们现在已经复制了选择器,可以将点击方法插入程序中。就是这样:

await page.click('#default > div > div > div > div > section > div:nth-child(2) > ol > li:nth-child(1) > article > div.image_container > a > img');

我们的窗口现在将点击第一张产品图片并导航到该产品页面!

在新页面上,我们对产品标题和产品价格感兴趣 —— 如下红色部分所示

为了检索这些值,我们将使用 page.evaluate() 方法。该方法允许我们使用内置的 DOM 选择器,如 querySelector()。

我们要做的第一件事是创建 page.evaluate() 函数并将返回的值保存到名为 result 的变量中:

const result = await page.evaluate(() => {
// 返回一些内容 
});

在我们的函数中,我们可以选择所需的元素。我们将再次使用 Google 开发者工具来解决这个问题。右键单击标题并选择检查:

如您在元素面板中所见,标题只是一个 h1 元素。我们现在可以使用以下代码选择该元素:

let title = document.querySelector('h1'); 

由于我们想要该元素中包含的文本,因此我们需要添加 .innerText —— 这是最终代码的样子:

let title = document.querySelector('h1').innerText;

类似地,我们可以通过右键单击并检查元素来选择价格:

在这里插入图片描述

如您所见,我们的价格具有 price_color 类。我们可以使用此类来选择元素及其内部文本。代码如下:

let price = document.querySelector('.price_color').innerText;

现在我们已经获取了所需的文本,可以在对象中返回它:

return {title, price
}

很棒!我们现在正在选择标题和价格,将它们保存到对象中,并将该对象的值返回到 result 变量中。将所有部分组合在一起的样子如下:

const result = await page.evaluate(() => {let title = document.querySelector('h1').innerText;let price = document.querySelector('.price_color').innerText;return {title,price}
});

现在唯一要做的就是返回我们的 result,以便将其记录到控制台:

return result;

您的最终代码应如下所示:

onst puppeteer = require('puppeteer');let scrape = async () => {const browser = await puppeteer.launch({headless: false});const page = await browser.newPage();await page.goto('http://books.toscrape.com/');await page.click('#default > div > div > div > div > section > div:nth-child(2) > ol > li:nth-child(1) > article > div.image_container > a > img');await page.waitFor(1000);const result = await page.evaluate(() => {let title = document.querySelector('h1').innerText;let price = document.querySelector('.price_color').innerText;return {title,price}});browser.close();return result;
};scrape().then((value) => {console.log(value); // Success!
});

您现在可以通过在控制台中输入以下命令来运行 Node 文件:

node scrape.js
// { title: 'A Light in the Attic', price: '£51.77' }

您应该会在屏幕上看到所选书籍的标题和价格被返回!您刚刚抓取了网络!

示例3——完善它

现在您可能会问自己,为什么我们要点击书籍,而标题和价格都显示在主页上? 为什么不从那里抓取它们? 而且,为什么不抓取所有书籍的标题和价格呢?

因为抓取网站有很多种方法! (另外,如果我们留在主页上,我们的标题会被截断)。 然而,这为您提供了练习新抓取技能的绝佳机会!

挑战

目标 —— 从主页抓取所有书籍的标题和价格,并将它们返回到数组中。 这是我的最终输出样子:

去吧! 看看您是否可以自己完成这项工作。 它与我们刚刚创建的程序非常相似。 如果您遇到困难,请向下滚动…

提示:

与前面的示例相比,此挑战的主要区别在于需要循环大量结果。 您可以按照以下方式设置代码以执行此操作:

const result = await page.evaluate(() => {let data = []; // 创建一个空数组let elements = document.querySelectorAll('xxx'); // 选择所有元素// 循环每个产品// 选择标题// 选择价格data.push({title, price}); // 将数据推送到我们的数组return data; // 返回我们的数据数组
});

解决方案:

const puppeteer = require('puppeteer');let scrape = async () => {const browser = await puppeteer.launch({headless: false});const page = await browser.newPage();await page.goto('http://books.toscrape.com/');const result = await page.evaluate(() => {let data = []; // Create an empty array that will store our datalet elements = document.querySelectorAll('.product_pod'); // Select all Productsfor (var element of elements){ // Loop through each proudctlet title = element.childNodes[5].innerText; // Select the titlelet price = element.childNodes[7].children[0].innerText; // Select the pricedata.push({title, price}); // Push an object with the data onto our array}return data; // Return our data array});browser.close();return result; // Return the data
};scrape().then((value) => {console.log(value); // Success!});

在这里插入图片描述

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

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

相关文章

计算机毕业设计 基于SSM的历史/博物馆藏系统的设计与实现 Java实战项目 附源码+文档+视频讲解

博主介绍:✌从事软件开发10年之余,专注于Java技术领域、Python人工智能及数据挖掘、小程序项目开发和Android项目开发等。CSDN、掘金、华为云、InfoQ、阿里云等平台优质作者✌ 🍅文末获取源码联系🍅 👇🏻 精…

Linux粘滞位的理解,什么是粘滞位?

文章目录 前言如何理解?粘滞位的操作最后总结一下 前言 粘滞位(Stickybit),或粘着位,是Unix文件系统权限的一个旗标。最常见的用法在目录上设置粘滞位,如此以来,只有目录内文件的所有者或者root…

Dubbo-admin监控中心

监控中心 Dubbo-admin监控中心执行操作启动provider和consumer项目进行测试总体流程 Dubbo-admin监控中心 dubbo-admin下载路径 git clone https://github.com/apache/dubbo-admin.git图1-1 dubbo-admin项目文件展示 执行操作 # 启动zookeeper# 前端 cd dubbo-admin-ui npm i…

多模态融合的基础问题及算法研究

🌞欢迎来到深度学习的世界 🌈博客主页:卿云阁 💌欢迎关注🎉点赞👍收藏⭐️留言📝 🌟本文由卿云阁原创! 🙏作者水平很有限,如果发现错误&#xff…

C++--默认参数

一.默认参数🍗 C中允许函数提供默认参数,也就是允许在函数的声明或定义时给⼀个或多个参数指定默认值。在调 ⽤具有默认参数的函数时,如果没有提供实际参数,C将⾃动把默认参数作为相应参数的值。 二.使用规则🍗 1.如果…

Spring Web文件上传功能简述

文章目录 正文简单文件上传文件写入 总结 正文 在日常项目开发过程中,文件上传是一个非常常见的功能,当然正规项目都有专门的文件服务器保存上传的文件,实际只需要保存文件路径链接到数据库中即可,但在小型项目中可能没有专门的文…

Spring中动态注册和销毁对象

1. 使用说明 通常我们项目中想要往spring容器中注入一个bean可以在项目初始化的时候结合Bean注解实现。但是该方法适合项目初始化时候使用,如果后续想要继续注入对象则无可奈何。本文主要描述一种在后续往spring容器注入bean的方法。 2. 实现 2.1 说明 2.1.1 注册…

「 典型安全漏洞系列 」03.跨站请求伪造CSRF详解

引言:CSRF(Cross-Site Request Forgery,跨站请求伪造)是一种攻击技术,通过使用用户的身份进行不诚实地操作,恶意用户可以在受害者(目标)的机器上执行一些未授权的操作。这可能会危及…

FairyGUI Day 1 导入FairyGUI

FairyGUI Unity3d引擎版本:Uinty3d 20233.2.3f1 1、从资产商店中将FairyGUI购入我的资产中,目前是免费的。 2、从我的资产中将FairyGUI导入到当前项目中。 3、我遇到的问题,我的Assets下有两个文件夹分别是Resources和Scenes,导…

进阶Docker4:网桥模式、主机模式与自定义网络

目录 网络相关 子网掩码 网关 规则 docke网络配置 bridge模式 host模式 创建自定义网络(自定义IP) 网络相关 IP 子网掩码 网关 DNS 端口号 子网掩码 互联网是由许多小型网络构成的,每个网络上都有许多主机,这样便构成了一个有层次的结构。 IP 地…

pytest + allure(windows)安装

背景 软硬件环境: windows11,已安装anaconda,python,pycharm用途:使用pytest allure 生成报告allure 依赖java,点击查看java安装教程 allure 下载与安装 从 allure下载网址下载最新版本.zip文件 放在自…

Android Dialog setCanceledOnTouchOutside失效,点击dialog外面不消失

前言:有一个需求需要点击dialog外面要消失,本来以为很简单结果设置了一直未生效 setCanceledOnTouchOutside(true); 问了半天chat-gpt4结果给的答案都不明显 查看代码发现设置了style,于是尝试去除这个style,结果点击setCancele…

蓝桥杯回文日期判断

思想:对于回文数的判断方法,最快的就是取其中一半的字符串长度,为s,然后将其进行翻转为s’ ,再把两者进行拼接即可保证是回文数,这样子就解决了枚举所有回文数的问题。 注意点: 要求必须是有效…

SQL Server中数据表的增删查改

文章目录 一、增二、查三、改四、删除 一、增 进行增删查改的前提需要在指定数据库中创建数据表,对这块不大理解的可以先看看前面几期文章: 创建数据库 创建数据表 use StudentManageDB go insert into Students (StudentName,Gender,Birthday,Age,Stu…

如何使用万能头 #include<bits/stdc++.h>

准备蓝桥杯的时候看到了很多头文件包含了这个头文件,后来查了一下 它是C中支持的一个几乎万能的头文件,几乎包含所有的可用到的C库函数。以后写代码就可以直接引用这一个头文件了,不需要在写一大堆vector、string、map、stack…… 我们该如何…

JavaScript基础语法

速通回顾一遍 引入方式 一般会把<script>标签置于<body>元素底部&#xff0c;改善显示速度&#xff1a; 内部脚本&#xff1a;<script></script>标签内外部脚本&#xff1a;<script src""></script>配置src 外部js文件中&…

数据库-数据库分类

数据库可以分为关系型数据库和非关系型数据库&#xff0c;常见的数据库如下 关系型数据库 关系型数据库是一种采用关系模型来组织数据的数据库&#xff0c;它以行和列的形式存储数据&#xff0c;以便于用户理解。关系型数据库中的数据以二维表的形式组织&#xff0c;被称为表…

MSSQL-识别扩展extended event(扩展事件)中的时间单位

经常使用sqlserver extended event(扩展事件)&#xff0c;但是总是忘记扩展事件使用的时间单位&#xff0c;不确定它们是 秒、毫秒、还是微秒&#xff1f; 以下下代码能够从 相关DMV中提取description字段内容来识别时间单位&#xff1a; SELECT [p].[name] [package_name],[o…

mac PyCharm 上传文件到远程服务器+远程服务器下载到本地

1 部署配置 选择SFTP name&#xff1a;test6 输入ssh账号和密码。保存密码和30s心跳。 2 目录映射 Local path&#xff08;本地mac机器&#xff09;&#xff1a;/Users/clevercode/PycharmProjects/test6 Root path&#xff08;远程服务机器&#xff09;&#xff1a;/home/…

k8s---ingress对外服务(traefik)

目录 ingress的证书访问 traefik traefik的部署方式&#xff1a; deamonset deployment nginx-ingress与traefix-ingress相比较 nginx-ingress-controller ui访问 deployment部署 ingress的证书访问 ingress实现https代理访问: 需要证书和密钥 创建证书 密钥 secre…