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

news/2024/7/19 8:43:58 标签: 前端, node, node.js, 爬虫

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

在这里插入图片描述


http://www.niftyadmin.cn/n/5330846.html

相关文章

Kali Linux保姆级教程|零基础从入门到精通,看完这一篇就够了!(附工具包)

作为一名从事网络安全的技术人员,不懂Kali Linux的话,连脚本小子都算不上。 Kali Linux预装了数百种享誉盛名的渗透工具,使你可以更轻松地测试、破解以及进行与数字取证相关的任何其他工作。 今天给大家分享一套Kali Linux资料合集&#xf…

MySQL:运行mysql时,提示Table ‘performance_schema.session_variables’ doesn’t exist

docker exec -it docker_mysql_id /bin/bash mysql -uroot -p123456mysql_upgrade -u root -p --force exitdocker restart docker_mysql_id

PHP 字符串面试题

如何获取字符串的长度? 可以使用 strlen() 函数获取字符串的长度,例如: $length strlen($string);如何将字符串转换为大写或小写? 可以使用 strtoupper() 函数将字符串转换为大写,例如: $uppercase s…

基于单片机的集中供热监控电路设计

一、摘要 随着城市化进程的加快,集中供热系统在城市居民生活中扮演着越来越重要的角色。为了确保供热系统的稳定运行,提高供热效率,降低能耗,本文设计了一种基于单片机的集中供热监控电路。该电路主要包括温度传感器、压力传感器…

【人工智能与深度学习】当输入层维度为1024,输出层维度为100时,为什么全连接层参数量为1024*100+100

当输入层维度为1024,输出层维度为100时,为什么全连接层参数量为1024*100100 在神经网络中,全连接层(也称为稠密层或线性层)的参数量计算通常包括权重(weights)和偏置(biases&#x…

【机器学习300问】2、机器学习分为哪几类?

一、监督学习 监督学习(Supervised Learning)是机器学习和人工智能中的一种算法学习训练方式。它利用有标签的数据(通常称为训练数据)作为输入,训练一个模型来学习输入和输出之间的关系。模型学习后可以用于预测新的、…

指向未来: 量子纠缠的本质是一个指针

指向未来: 量子纠缠的本质是一个指针 概述基本概念理解量子纠缠PythonJavaC 理解波粒二象性PythonJavaC 理解量子隧穿理解宇宙常量PythonJavaC 概述 量子纠缠 (Quantum Entanglement) 是量子系统重两个或多个粒子间的一种特殊连接, 这种连接使得即使相隔很远, 这些粒子的状态也…

tidb Cloud 连接spring boot 项目

一、 免费试用tidbitcloud TiDB Cloud Documentation | PingCAP Docs 1.github账号登录 2.创建集群 3.点击对应集群cludter0 导入数据 导入 本地导入只支持csv文件,其他导入需要AWZ账号使用S3云存储 二、连接spingboot项目 选择java,复制下面的jd…