」工欲善其事,必先利其器。「—孔子《論語.錄靈公》
首頁 > 程式設計 > 用 puppeteer 抓取網路!

用 puppeteer 抓取網路!

發佈於2024-11-06
瀏覽:811

Scrape the web with puppeteer!

木偶师完整指南 pt.1

Puppeteer:Web 自动化的强大工具

在当今快节奏的 Web 开发环境中,自动化是关键,这就是 Puppeteer 的用武之地。Puppeteer 由 Google 开发,是一个功能强大的 Node.js 库,允许开发人员使用 JavaScript 控制 Chrome 浏览器。无论您是在无头模式下浏览网络以提高效率,还是在完整的浏览器中获得视觉反馈,Puppeteer 都可以让您比以往更轻松地自动执行网页抓取、测试等任务。有了 Puppeteer,曾经需要手动完成的工作现在只需一个脚本即可完成。

为什么要进行网页抓取?

在最近的一个项目中,我与一位客户合作,他的外汇交易社区需要一个登陆页面。他想要类似于您在 MarketWatch 或雅虎财经上看到的股票行情的东西,但他想要的不是股票,而是在网站上显示 1 美元的实时货币兑换率。

虽然有可用的 API 可以提供数据(具有使用限制和月费),但我看到了使用 Puppeteer 创建自定义解决方案的机会。通过预先投入一些时间,我能够免费抓取和显示数据,最终为我的客户节省了经常性成本。

客户网站:Majesticpips.com

设置 puppeteer 变得简单

在我们开始抓取网络以实现其所有荣耀之前,我们必须将 puppeteer 安装到我们的应用程序中。

正如文档中所述

步骤1

使用您选择的 npm、yarn 或 pnpm 安装库。

  • npm 我木偶师

  • 纱线添加傀儡师

  • pnpm 添加木偶操纵者

这将在安装过程中下载 Chrome 的兼容版本,这对于初学者来说更容易快速启动和运行。

如果您是一位经验丰富的开发人员并且有您想要使用的特定 chrome/chromium 版本;然后安装这些软件包

  • npm i puppeteer-core

  • 纱线添加 puppeteer-core

  • pnpm 添加 puppeteer-core

最适合您,该软件包将是轻量级的,因为它只安装 puppeteer,而 chrome 版本则由您决定。

安装“puppeteer”对于初次测试者来说是更好的选择。它简化了设置并确保您拥有 Chromium 的工作版本,使您能够专注于编写脚本。

步骤2

现在在您的 JS 文件中,您需要为使用 ES 模块系统(ES6 标准)且节点版本为 12 及更高版本的应用程序导入 puppeteer。

从 'puppeteer' 导入 puppeteer; (受到推崇的)
或者
从 'puppeteer-core' 导入 puppeteer;

或者您可以使用 Node.js 的 commonJs 模块系统的 require 语法,该语法也与旧版本的 Node.js 兼容。

const puppeteer = require('puppeteer');
或者
const puppeteer = require('puppeteer-core');

步骤3

导入Puppeteer后,我们就可以开始编写执行网页抓取的命令了。下面的代码显示了您需要使用的内容。

我们使用库提供的这些方法启动浏览器。

const browser = await puppeteer.launch();

const page = await browser.newPage();

await browser.close();

puppeteer.launch() = 此方法启动一个新的浏览器实例。

browser.newPage() = 此方法在浏览器实例中创建一个新页面(或选项卡)。

browser.close() = 此方法关闭浏览器实例。

在 puppeteer.launch() 中,我们可以传递参数来根据我们的喜好自定义浏览器启动。我们将在第 2 部分中更详细地介绍这一点。但是,默认情况下,puppeteer.launch() 具有预设值,例如将无头模式设置为 true。

步骤4

浏览器已经启动,现在我们有了一个可以上网的页面。让我们导航到我们将抓取一些数据的网站。

在此示例中,我们将从 qoutes 网站抓取数据。

 await page.goto(https://quotes.toscrape.com/)

 await page.screenshot({ path: 'screenshot.png' })

我添加了await page.screenshot({path:'screenshot.png'})。这是一个很好的工具,可以确保一切按计划进行。执行此代码时,您的项目目录中将有一个图像文件,用于捕获您正在抓取的网站的当前状态。您还可以根据自己的喜好调整文件名。

如果一切正常,则继续执行步骤 5。

步骤5

现在我们的脚本已经成型,让我们深入研究从网页提取数据的关键部分。这是我们的脚本到目前为止的样子:

const puppeteer = require('puppeteer');

(async () => {

const browser = await puppeteer.launch();

const page = await browser.newPage();

await page.goto(https://quotes.toscrape.com/)

await page.screenshot({ path: 'screenshot.png' })

 const quotesScraper = await page.evaluate(() => {

const quotes = document.querySelectorAll(".quote"); 
    const quotesArray = [];

   for (const quote of quotes) { 
       const texts = quote.querySelector(".text").innerText; 
         const author = quote.querySelector(".author").innerText;  

        quotesArray.push({
           quote: texts,
           author
         });

     }
     return quotesArray;
});

console.log(quotesScraper);

await browser.close();

})();

要验证数据是否已成功抓取,我们可以在 CLI 中运行节点“server-file-name”,数据将使用 console.log(quotesScraper);.
显示在控制台中

[
  {
    quote: '“The world as we have created it is a process of our thinking. It cannot be changed without changing our thinking.”',
    author: 'Albert Einstein'
  },
  {
    quote: '“It is our choices, Harry, that show what we truly are, far more than our abilities.”',
    author: 'J.K. Rowling'
  },
  {
    quote: '“There are only two ways to live your life. One is as though nothing is a miracle. The other is as though everything is a miracle.”',
    author: 'Albert Einstein'
  },
  {
    quote: '“The person, be it gentleman or lady, who has not pleasure in a good novel, must be intolerably stupid.”',
    author: 'Jane Austen'
  },
  {
    quote: "“Imperfection is beauty, madness is genius and it's better to be absolutely ridiculous than absolutely boring.”",
    author: 'Marilyn Monroe'
  }
....
]

await page.evaluate(() => { ... }):这就是奇迹发生的地方。 evaluate 方法允许我们在正在抓取的页面上下文中运行 JavaScript 代码。这就好像您打开浏览器的开发者控制台并直接在页面上运行代码。

const quote = document.querySelectorAll(".quote");:在这里,我们选择页面上与 .quote 类匹配的所有元素。这给了我们一个引用元素的 NodeList。

constquotesArray = [];:我们初始化一个空数组来存储我们提取的引号。

for (const quote of quote) { ... }:此循环迭代每个引号元素。对于每一个,我们都会提取引用文本和作者。

quotesArray.push({ quote: texts,author });:对于每个引用,我们创建一个包含引用文本和作者的对象,然后将该对象推入quotesArray。

returnquotesArray;:最后,我们返回引号数组,然后将其存储在 Node.js 环境中的quotesScraper中。

这种提取数据的方法非常强大,因为它允许您像用户一样与页面交互,但是以自动化和编程的方式。

关闭浏览器

await browser.close();:抓取数据后,关闭浏览器以释放资源非常重要。此行确保我们启动的浏览器实例正确关闭。

展望第二部分

通过此脚本,您已成功使用 Puppeteer 从网站抓取数据。但我们只是触及了可能性的表面。在第 2 部分中,我们将探索更高级的技术,例如处理动态内容并使用 Express.JS 创建报废数据的 API 功能。 请继续关注,我们将深入探索 Puppeteer 的世界!

版本聲明 本文轉載於:https://dev.to/cedsengine/scrape-the-web-with-puppeteer-2hmh?1如有侵犯,請聯絡[email protected]刪除
最新教學 更多>
  • 如何在鼠標單擊時編程選擇DIV中的所有文本?
    如何在鼠標單擊時編程選擇DIV中的所有文本?
    在鼠標上選擇div文本單擊帶有文本內容,用戶如何使用單個鼠標單擊單擊div中的整個文本?這允許用戶輕鬆拖放所選的文本或直接複製它。 在單個鼠標上單擊的div元素中選擇文本,您可以使用以下Javascript函數: function selecttext(canduterid){ if(d...
    程式設計 發佈於2025-05-14
  • HTML格式標籤
    HTML格式標籤
    HTML 格式化元素 **HTML Formatting is a process of formatting text for better look and feel. HTML provides us ability to format text without us...
    程式設計 發佈於2025-05-14
  • 如何使用Python有效地以相反順序讀取大型文件?
    如何使用Python有效地以相反順序讀取大型文件?
    在python 中,如果您使用一個大文件,並且需要從最後一行讀取其內容,則在第一行到第一行,Python的內置功能可能不合適。這是解決此任務的有效解決方案:反向行讀取器生成器 == ord('\ n'): 緩衝區=緩衝區[:-1] ...
    程式設計 發佈於2025-05-14
  • 如何限制動態大小的父元素中元素的滾動範圍?
    如何限制動態大小的父元素中元素的滾動範圍?
    在交互式接口中實現垂直滾動元素的CSS高度限制問題:考慮一個佈局,其中我們具有與用戶垂直滾動一起移動的可滾動地圖div,同時與固定的固定sidebar保持一致。但是,地圖的滾動無限期擴展,超過了視口的高度,阻止用戶訪問頁面頁腳。 $("#map").css({ margin...
    程式設計 發佈於2025-05-14
  • CSS強類型語言解析
    CSS強類型語言解析
    您可以通过其强度或弱输入的方式对编程语言进行分类的方式之一。在这里,“键入”意味着是否在编译时已知变量。一个例子是一个场景,将整数(1)添加到包含整数(“ 1”)的字符串: result = 1 "1";包含整数的字符串可能是由带有许多运动部件的复杂逻辑套件无意间生成的。它也可以是故意从单个真理...
    程式設計 發佈於2025-05-14
  • 如何避免Go語言切片時的內存洩漏?
    如何避免Go語言切片時的內存洩漏?
    ,a [j:] ...雖然通常有效,但如果使用指針,可能會導致內存洩漏。這是因為原始的備份陣列保持完整,這意味著新切片外部指針引用的任何對象仍然可能佔據內存。 copy(a [i:] 對於k,n:= len(a)-j i,len(a); k
    程式設計 發佈於2025-05-14
  • 如何使用Regex在PHP中有效地提取括號內的文本
    如何使用Regex在PHP中有效地提取括號內的文本
    php:在括號內提取文本在處理括號內的文本時,找到最有效的解決方案是必不可少的。一種方法是利用PHP的字符串操作函數,如下所示: 作為替代 $ text ='忽略除此之外的一切(text)'; preg_match('#((。 &&& [Regex使用模式來搜索特...
    程式設計 發佈於2025-05-14
  • 如何簡化PHP中的JSON解析以獲取多維陣列?
    如何簡化PHP中的JSON解析以獲取多維陣列?
    php 試圖在PHP中解析JSON數據的JSON可能具有挑戰性,尤其是在處理多維數組時。 To simplify the process, it's recommended to parse the JSON as an array rather than an object.To do...
    程式設計 發佈於2025-05-14
  • 如何在Chrome中居中選擇框文本?
    如何在Chrome中居中選擇框文本?
    選擇框的文本對齊:局部chrome-inly-ly-ly-lyly solument 您可能希望將文本中心集中在選擇框中,以獲取優化的原因或提高可訪問性。但是,在CSS中的選擇元素中手動添加一個文本 - 對屬性可能無法正常工作。 初始嘗試 state)</option> < o...
    程式設計 發佈於2025-05-14
  • 如何使用FormData()處理多個文件上傳?
    如何使用FormData()處理多個文件上傳?
    )處理多個文件輸入時,通常需要處理多個文件上傳時,通常是必要的。 The fd.append("fileToUpload[]", files[x]); method can be used for this purpose, allowing you to send multi...
    程式設計 發佈於2025-05-14
  • 使用jQuery如何有效修改":after"偽元素的CSS屬性?
    使用jQuery如何有效修改":after"偽元素的CSS屬性?
    在jquery中了解偽元素的限制:訪問“ selector 嘗試修改“:”選擇器的CSS屬性時,您可能會遇到困難。 This is because pseudo-elements are not part of the DOM (Document Object Model) and are th...
    程式設計 發佈於2025-05-14
  • PHP陣列鍵值異常:了解07和08的好奇情況
    PHP陣列鍵值異常:了解07和08的好奇情況
    PHP數組鍵值問題,使用07&08 在給定數月的數組中,鍵值07和08呈現令人困惑的行為時,就會出現一個不尋常的問題。運行print_r($月份)返回意外結果:鍵“ 07”丟失,而鍵“ 08”分配給了9月的值。 此問題源於PHP對領先零的解釋。當一個數字帶有0(例如07或08)的前綴時,PHP...
    程式設計 發佈於2025-05-14
  • 如何從Python中的字符串中刪除表情符號:固定常見錯誤的初學者指南?
    如何從Python中的字符串中刪除表情符號:固定常見錯誤的初學者指南?
    從python import codecs import codecs import codecs 導入 text = codecs.decode('這狗\ u0001f602'.encode('utf-8'),'utf-8') 印刷(文字)#帶有...
    程式設計 發佈於2025-05-14
  • PHP SimpleXML解析帶命名空間冒號的XML方法
    PHP SimpleXML解析帶命名空間冒號的XML方法
    在php 很少,請使用該限制很大,很少有很高。例如:這種技術可確保可以通過遍歷XML樹和使用兒童()方法()方法的XML樹和切換名稱空間來訪問名稱空間內的元素。
    程式設計 發佈於2025-05-14

免責聲明: 提供的所有資源部分來自互聯網,如果有侵犯您的版權或其他權益,請說明詳細緣由並提供版權或權益證明然後發到郵箱:[email protected] 我們會在第一時間內為您處理。

Copyright© 2022 湘ICP备2022001581号-3