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 data
        let elements = document.querySelectorAll('.product_pod'); // Select all Products

        for (var element of elements){ // Loop through each proudct
            let title = element.childNodes[5].innerText; // Select the title
            let price = element.childNodes[7].children[0].innerText; // Select the price

            data.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!
    });

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

el-select中多选回显数据后没法重新选择和更改

<el-form-item label"展示内容" prop"videoId"><el-select class"modal-input" multiple v-model"form.videoId"><el-optionclass"modal-input"v-for"(item) in videoIdTypes":key"item.id&q…

直播产品痛点话术

一、用户需求分析 为了更好地满足用户需求&#xff0c;我们对市场进行了深入的调研。发现主播们在直播过程中面临着多方面的挑战&#xff0c;如产品功能、质量、价格、安全性等方面的需求。 二、产品功能不足 当前市场上的主播产品存在功能不足的问题。例如&#xff0c;一些…

法规更新美国玩具标准ASTM F963-17有更新,最新标准为ASTM F963-23

美国材料试验协会 (ASTM)在10月13日发布了新的玩具安全标准&#xff1a;ASTM F963-23&#xff0c;ASTM F963-17美国联邦法规16 CFR 1250还在使用当中&#xff0c;出口美国的玩具的厂商要引起重视。 ASTM F963-17是什么标准&#xff1f; ASTM F963-17是美国玩具检测标准&#…

postman 简单测试(一)

1.postman官网 Postman API Platform 2.研究了一下postman 一些简单的功能&#xff0c;自己做个记录&#xff0c;同时希望能节约点测试时间。 2.1新建一个 collections 长期测的话&#xff0c;最好注册一个账号&#xff0c;开放更多功能。 2.2新建一个请求 后端要先搭建起来…

网络部署实战具体学习内容总结

网络部署实战具体学习内容总结 &#x1f4bb;网络部署实战课程通常旨在教授学生如何规划、配置、维护和优化计算机网络。这些课程涵盖了广泛的主题&#xff0c;以确保学生具备网络部署和管理所需的技能。 网络部署实战课程具体学习内容&#x1f447; 1️⃣网络架构设计及网络原…

解决方案:reactNative通过webview跳转微信智能客服空白webview页面

在reactNative中使用webview跳转微信智能客服&#xff0c;功能正常&#xff0c;从微信退回到App时&#xff0c;会有一个空白的webview页面&#xff0c;在使用感觉上不是那么的顺滑。解决这个可以在webview中使用onLoadEnd方法来解决这个问题 在react-native-webview中onLoadEn…

07-微服务getaway网关详解

一、初识网关 在微服务架构中&#xff0c;一个系统会被拆分为很多个微服务。那么作为客户端要如何去调用这么多的微服务呢&#xff1f;如果没有网关的存在&#xff0c;我们只能在客户端记录每个微服务的地址&#xff0c;然后分别去调用。这样的话会产生很多问题&#xff0c;例…

光彩耀新年,戴森美发科技品类,见证成长美一面

龙年将至&#xff0c;祥瑞满天&#xff0c;新年曙光寓意着好运从「头」开始&#xff0c;同时也承载着人们对新一年的期许。值此之际&#xff0c;戴森中国美发科技品类正式发布全新蓝彩朱红色系列产品&#xff0c;为新年注入活力与希望&#xff0c;携手消费者一起开启护发造型新…

thinkphp 命令行执行

1 php 1 which php 查看命令来源 2 ll /usr/bin/php 软连接&#xff0c;来源是php的安装文件的可执行文件php 3 $PATH的作用, 显示当前PATH环境变量,该变量的值由一系列以冒号分隔的目录名组成如下&#xff0c; echo $PATH /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/…

微信分销功能怎么做_微信小程序分销商城有什么意义

微信分销功能&#xff1a;开启财富之门的金钥匙 在数字化浪潮的推动下&#xff0c;微信已成为我们生活中不可或缺的一部分。而微信分销功能&#xff0c;更是为企业和个人提供了一个全新的商业机会。那么&#xff0c;如何利用微信分销功能&#xff0c;开启财富之门呢&#xff1…

git中的语法和术语含义

目录 第一章、git常用术语1.1&#xff09;文件状态1.2&#xff09;git常用术语的含义 第二章、git文件状态解析2.1&#xff09;从git init开始&#xff1a;Untracked&#xff08;未跟踪&#xff09;2.2&#xff09;git add fileName后&#xff1a;Staged&#xff08;已暂存&…

Linux:网络文件共享服务和内网搭建yum仓库

目录 一、网络文件共享服务 1.储存类型 2.FTP文本传输协议 二、内网搭建yum仓库 1.通过ftp服务搭建内网yum仓库服务器 2.通过httpd协议搭建内网yum仓库服务器 一、网络文件共享服务 1.储存类型 分为三种&#xff1a; 直连式存储: Direct-Attached Storage&#xff0c;简…

【目标检测】YOLOv5算法实现(八):模型验证

本系列文章记录本人硕士阶段YOLO系列目标检测算法自学及其代码实现的过程。其中算法具体实现借鉴于ultralytics YOLO源码Github&#xff0c;删减了源码中部分内容&#xff0c;满足个人科研需求。   本系列文章主要以YOLOv5为例完成算法的实现&#xff0c;后续修改、增加相关模…

基于Java SSM框架实现学生综合考评管理系统项目【项目源码+论文说明】

基于java的SSM框架实现学生学生综合考评管理系统演示 摘要 随着社会的发展&#xff0c;社会的各行各业都在利用信息化时代的优势。计算机的优势和普及使得各种信息系统的开发成为必需。 学生综合考评管理系统&#xff0c;主要的模块包括查看&#xff1b;管理员&#xff1b;个…

统计学-R语言-5.1

文章目录 前言随机性和规律性概率变量的分布离散型--二项、泊松、几何二项分布几何分布泊松分布 连续型--均匀、正态均匀分布正态分布 其它统计分布--χ2分布、t分布、F分布χ2分布t分布F分布 练习 前言 从本篇文章开始介绍有关概率与分布的介绍。 随机性和规律性 当不能预测…

2024 基于 Rust 的 linter 工具速度很快

2024 年 Web 工具的一大趋势是使用 Rust 重写现有工具。Rust 是一种出色的编程语言&#xff0c;能生成运行速度惊人的二进制文件&#xff0c;且与其它 Web 工具的互操作性极佳&#xff0c;这得益于 WebAssembly 的帮助。swc 和 Turbopack 等工具的速度提升为快速开发体验带来了…

麒麟KYLINOS操作系统上使用五种不同方式安装软件

原文链接&#xff1a;麒麟KYLINOS使用五种不同方式安装软件 hello&#xff0c;大家好啊&#xff01;今天我要给大家介绍的是在麒麟KYLINOS操作系统上使用五种不同方式安装软件的方法。在Linux系统中&#xff0c;有多种方式可以安装软件&#xff0c;每种方式都适用于不同的场景和…

Grind75第11天 | 310.最小高度树、127.单词接龙、230.二叉搜索树中第k小的元素

310.最小高度树 题目链接&#xff1a;https://leetcode.com/problems/minimum-height-trees 解法&#xff1a; 这个题类似最短路径问题&#xff0c;用的BFS。 从题目的例子可以看到&#xff0c;最小高度树的根节点&#xff0c;好像是入度比较大的节点&#xff0c;这是一个大…

MySQL基础笔记(6)函数

函数&#xff1a;是指一段可以直接被另一段程序调用的程序或者代码~&#xff08;MySQL内置&#xff09; 一.字符串函数 trim不能去除中间的空格~ select concat(jsl,1325): 执行如上的代码&#xff0c;返回字符串"jsl1325"。 select lower(JSL); 执行如上的代码&…

【健康小贴士】关节炎是不是冻出来的?

大家冬天肯定被父母唠叨过&#xff1a; 「天气这么冷&#xff0c;裤子穿这么短&#xff0c;小心得关节炎&#xff01;」 ❌这种说法其实是不对的或者并不全面&#xff0c;答案来了&#x1f440;