谷歌 Puppeteer 爬虫工具初体验(可用于H5截图预览)

2024-03-01 22:10

本文主要是介绍谷歌 Puppeteer 爬虫工具初体验(可用于H5截图预览),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

https://segmentfault.com/a/1190000014403160

随着网络的迅速发展,因特网已经成为大量信息的载体,如何有效地提取并利用这些信息成为一个巨大的挑战。搜索引擎(Search Engine) —— 例如传统的通用搜索引擎 Baidu 和 Google等,作为一个辅助人们检索信息的工具成为用户访问因特网的入口和指南。但是,通用性搜索引擎也存在着一定的局限性,如:通用搜索引擎所返回的结果包含大量用户不关心的网页、大多提供基于关键字的检索,难以支持根据语义信息提出的查询等。

为了解决上述问题,定向抓取相关网页资源的聚焦爬虫应运而生。聚焦爬虫是一个自动下载网页的程序,它根据既定的抓取目标,有选择的访问万维网上的网页与相关的链接,获取所需要的信息。与通用爬虫(general purpose web crawler)不同,聚焦爬虫并不追求大的覆盖,而将目标定为抓取与某一特定主题内容相关的网页,为面向主题的用户查询准备数据资源。

Puppeteer 是什么

Puppeteer 是由谷歌官方团队所开发维护的一个 node 库,它提供了一组用来操纵 Chrome 或 Chromium(即无 UI 的 Chrome) 浏览器的 API。

Puppeteer 的直译意思为傀儡师,意在我们可以通过 Puppeteer 来像操纵傀儡一样操纵浏览器去获取我们特定想要的信息。

Puppeteer 的功能

我们在浏览器中手动完成的大部分事情都可以用 Puppeteer 来完成。本文将采用下面几个例子来让你快速上手:

  • 捕捉网页快照,生成PDF、图片等
  • 爬取SPA应用,并生成预渲染内容(即“SSR” - 服务端渲染)
  • 创建测试用例,实现自动化测试,如表单提交、UI测试、键盘输入等
  • 捕获站点的时间线,以便追踪你的网站,帮助分析网站性能

Puppeteer 安装与使用

1. 安装

理论上 Puppeteer 的安装非常简单,就像我们去安装任意的一个 npm 包。
你只需要在你的项目目录的控制台里运行如下代码:

npm i --save puppeteer//或yarn add --save puppeteer

由于国内大环境(你懂的 |-_-| ),我们使用以上代码安装的时候,经常会出错:

ERROR: Failed to download Chromium r515411! Set "PUPPETEER_SKIP_CHROMIUM_DOWNLOA
D" env variable to skip download.

这通常是由于 Chromium 浏览器未正常下载到而引起的。这个时候,我们可以先设定环境变量,跳过安装 Chromium 的步骤,然后手动翻墙去下载:

set PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=1

下载完毕后,运行 Chromium 安装包(切记:Mac 系统需要将该应用拷贝到应用程序中!),然后在代码里做如下配置即可:

(async () => {const browser = await puppeteer.launch({executablePath: '/Applications/Chromium.app/Contents/MacOS/Chromium', //   以 Mac 版本为例,注意:路径并不是截止到 .app !// ... (其他一些配置)});
})();

也许会有人疑问,为啥不用 cnpm 来安装呢?一看就是聪明的宝宝,配置好淘宝源路径之后,使用

cnpm i --save puppeteer

安装,更适合无法出柜的宝宝,期间要下载 74M 左右的 Chromium ,请您耐心等待。

2. 常用语法

本文只对一些特别特别常用的方法进行介绍,有其他需求请戳 Puppeteer 官方KPI。

您也可以直接跳过此模块,直接阅读下方示例,有个更直观的了解。

Puppeteer 的每一步操作都是一个异步请求,因此要用到 generator 的语法糖 async 和 await

1)puppeteer.launch()

【作用】:启动浏览器。

【返回值】:promise。

【常用参数】:

  • headless

    是否开启浏览器的无头模式。默认值为 true。设为 false 后,抓包的时候,浏览器将打开可见,否则不可见。

  • executablePath

    设置执行抓包的浏览器的路径。默认会查找 node_modules/puppeteer/.local-chromium 路径。可手动自行配置。数据类型为字符串。

  • timeout

    等待浏览器实例启动的最大毫秒数,超过这个时间则报超时错误。默认为 30000。设为 0 则禁用此项参数。数据类型为 Number。

2)browser.newPage()

【作用】:开启浏览器新窗口。

【返回值】:promise。

3)page.setViewport()

【作用】:配置窗口信息。

【返回值】:promise。

  • width

    窗口的宽度。单位为 px 。

  • height

    窗口的高度。单位为 px 。

  • deviceScaleFactor

    设备实际缩放比。默认值为 1 。

  • isMobile

    是否开启手机模式。默认为 false 。

  • hasTouch

    是否支持 touch 事件。默认为 false 。

  • isLandscape

    是否开启横屏模式。默认为 false 。

4)page.goto(url, options)

【作用】:当前窗口加载固定 url 地址页。url 需要以 https 开头。

【返回值】:promise。

5)page.waitFor()

【作用】:当前代码等待某某条件成功后继续执行后面代码。

【返回值】:promise。

该方法的参数有很多种,通常我们只需要传入毫秒数即可,程序会暂停我们指定的时间,然后再继续执行后面的代码。

6)page.waitForSelector()

【作用】:当前代码等待页面渲染出某个 DOM 元素后继续执行后面代码。

【返回值】:promise。

7)page.$()

【作用】:获取当前页面的某个元素,类似于 document.querySelector() ,如果找不到,则返回 null 。

【返回值】:promise <ELement>。

8)page.$$()

【作用】:获取当前页面的某类元素,类似于 document.querySelectorAll() ,如果找不到,则返回一个空数组。

【返回值】:promise <Array>。

9)page.$eval(selector, pageFunction[, ...args])

【作用】:获取当前页面的某个元素,然后在 pageFunction 里面对获取的元素进行处理。

【返回值】:promise。

10)page.$$eval(selector, pageFunction[, ...args])

【作用】:获取当前页面的某类元素,然后在 pageFunction 里面对获取的元素数组进行处理。

【返回值】:promise。

11)browser.close()

【作用】:关闭所有浏览器窗口并退出 Chromium 浏览器。Browser 对象也将会被销毁。

【返回值】:promise。

以上就是我们经常用到的一些方法,接下来,我们将通过示例获取更直观的体验。

不上代码强撸问题都是耍流氓

药~药~切开脑~煎饼果子来一套!

1. 捕捉网页快照,生成PDF、图片等

我们以阮一峰老师的 ECMAScript 6 入门 网页为目标 URL ,并生成一组 pdf 文件。

const URL = 'http://es6.ruanyifeng.com';const puppeteer = require('puppeteer');
const fs = require('fs');fs.mkdirSync('es6-pdf');(async () => {let browser = await puppeteer.launch();let page = await browser.newPage();await page.goto(URL);await page.waitFor(5000); // 等待五秒,确保页面加载完毕// 获取左侧导航的所有链接地址及名字let aTags = await page.evaluate(() => {let eleArr = [...document.querySelectorAll('#sidebar ol li a')];return eleArr.map((a) =>{return {href: a.href.trim(),name: a.text}});});// 先将本页保存成pdf,并关闭本页console.log('正在保存:0.' + aTags[0].name);await page.pdf({path: `./es6-pdf/0.${aTags[0].name}.pdf`});// 遍历节点数组,逐个打开并保存 (此处不再打印第一页)for (let i = 1, len = aTags.length; i < len; i++) {let a = aTags[i];console.log('正在保存:' + i + '.' + a.name);page = await browser.newPage();await page.goto(a.href);await page.waitFor(5000);await page.pdf({path: `./es6-pdf/${i + '.' + a.name}.pdf`});}browser.close();
})();

运行结果:

2. 实现自动化测试

我们以简单的测试汽车之家 iphone X 手机下随意选取一款车,然后询价为例:

const URL = 'https://m.autohome.com.cn/';const puppeteer = require('puppeteer');
const devices = require('puppeteer/DeviceDescriptors');
const iPhone = devices['iPhone X'];
const fs = require('fs');fs.mkdirSync('screenshot');(async () => {let browser = await puppeteer.launch({headless: false // 无头模式});let page = await browser.newPage();await page.emulate(iPhone);await page.goto(URL);await page.waitFor(3000);await page.screenshot({path: 'screenshot/1.png'});await page.tap('body > section.wrapper > section.recommend-auto.fn-mt > div:nth-child(2) > div.brand.activate > a:nth-child(1)');await page.waitFor(3000);await page.screenshot({path: 'screenshot/2.png'});await page.tap('body > section > div.abc > section.findercar-brandcore > ul:nth-child(2) > li:nth-child(1) > a');await page.waitFor(3000);await page.screenshot({path: 'screenshot/3.png'});await page.tap('body > section.summary-console > a');await page.waitFor(3000);await page.screenshot({path: 'screenshot/4.png'});await page.type('body > section > section:nth-child(1) > section > dl.form-dl > dd:nth-child(2) > p.textcard.finish > input', '测试人员', {delay: 200});await page.type('#userPhone', '13333333333', {delay: 200});await page.screenshot({path: 'screenshot/5.png'});await page.tap('body > section > section:nth-child(1) > section > div.linkcont.js-linkbtn > a');await page.waitFor(3000);await page.screenshot({path: 'screenshot/6.png'});browser.close();
})();

运行截图:

由于最终提交询价资料的时候,网站做了智能验证,所以无法自动提交成功,但整体流程我们都通过截图一步步保存了下来,让我们的测试更加方便、有理有据,便于撕逼。

3. 分析网站性能

我们以测试汽车之家 iphone X 手机下主页的性能为例:

const URL = 'https://m.autohome.com.cn/';const puppeteer = require('puppeteer');
const devices = require('puppeteer/DeviceDescriptors');
const iPhone = devices['iPhone X'];
const fs = require('fs');fs.mkdirSync('performance');(async () => {let browser = await puppeteer.launch();let page = await browser.newPage();await page.emulate(iPhone);await page.tracing.start({path: 'performance/trace.json'});await page.goto(URL);await page.tracing.stop();browser.close();
})();

将 performance/trace.json 拖到 Chrome 浏览器的 performance 窗口下查看性能火山图:

 

总结

Puppeteer 的功能远不止于此,笔者在本文中只是列举了几个最简单最常用的例子。大家有兴趣,欢迎深入研究并分享,独乐乐不如众乐乐。

参考文献

  • 百度百科 - 网络爬虫
  • Puppeteer 官方 github 库

这篇关于谷歌 Puppeteer 爬虫工具初体验(可用于H5截图预览)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/763988

相关文章

Python实现微信自动锁定工具

《Python实现微信自动锁定工具》在数字化办公时代,微信已成为职场沟通的重要工具,但临时离开时忘记锁屏可能导致敏感信息泄露,下面我们就来看看如何使用Python打造一个微信自动锁定工具吧... 目录引言:当微信隐私遇到自动化守护效果展示核心功能全景图技术亮点深度解析1. 无操作检测引擎2. 微信路径智能获

Java中的工具类命名方法

《Java中的工具类命名方法》:本文主要介绍Java中的工具类究竟如何命名,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录Java中的工具类究竟如何命名?先来几个例子几种命名方式的比较到底如何命名 ?总结Java中的工具类究竟如何命名?先来几个例子JD

Android实现在线预览office文档的示例详解

《Android实现在线预览office文档的示例详解》在移动端展示在线Office文档(如Word、Excel、PPT)是一项常见需求,这篇文章为大家重点介绍了两种方案的实现方法,希望对大家有一定的... 目录一、项目概述二、相关技术知识三、实现思路3.1 方案一:WebView + Office Onl

MySql match against工具详细用法

《MySqlmatchagainst工具详细用法》在MySQL中,MATCH……AGAINST是全文索引(Full-Textindex)的查询语法,它允许你对文本进行高效的全文搜素,支持自然语言搜... 目录一、全文索引的基本概念二、创建全文索引三、自然语言搜索四、布尔搜索五、相关性排序六、全文索引的限制七

基于Java实现回调监听工具类

《基于Java实现回调监听工具类》这篇文章主要为大家详细介绍了如何基于Java实现一个回调监听工具类,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录监听接口类 Listenable实际用法打印结果首先,会用到 函数式接口 Consumer, 通过这个可以解耦回调方法,下面先写一个

使用Python构建一个Hexo博客发布工具

《使用Python构建一个Hexo博客发布工具》虽然Hexo的命令行工具非常强大,但对于日常的博客撰写和发布过程,我总觉得缺少一个直观的图形界面来简化操作,下面我们就来看看如何使用Python构建一个... 目录引言Hexo博客系统简介设计需求技术选择代码实现主框架界面设计核心功能实现1. 发布文章2. 加

JS+HTML实现在线图片水印添加工具

《JS+HTML实现在线图片水印添加工具》在社交媒体和内容创作日益频繁的今天,如何保护原创内容、展示品牌身份成了一个不得不面对的问题,本文将实现一个完全基于HTML+CSS构建的现代化图片水印在线工具... 目录概述功能亮点使用方法技术解析延伸思考运行效果项目源码下载总结概述在社交媒体和内容创作日益频繁的

基于Python打造一个全能文本处理工具

《基于Python打造一个全能文本处理工具》:本文主要介绍一个基于Python+Tkinter开发的全功能本地化文本处理工具,它不仅具备基础的格式转换功能,更集成了中文特色处理等实用功能,有需要的... 目录1. 概述:当文本处理遇上python图形界面2. 功能全景图:六大核心模块解析3.运行效果4. 相

springboot项目中常用的工具类和api详解

《springboot项目中常用的工具类和api详解》在SpringBoot项目中,开发者通常会依赖一些工具类和API来简化开发、提高效率,以下是一些常用的工具类及其典型应用场景,涵盖Spring原生... 目录1. Spring Framework 自带工具类(1) StringUtils(2) Coll

基于Python实现高效PPT转图片工具

《基于Python实现高效PPT转图片工具》在日常工作中,PPT是我们常用的演示工具,但有时候我们需要将PPT的内容提取为图片格式以便于展示或保存,所以本文将用Python实现PPT转PNG工具,希望... 目录1. 概述2. 功能使用2.1 安装依赖2.2 使用步骤2.3 代码实现2.4 GUI界面3.效