前端数据爬虫之puppeteer

前端数据爬虫之puppeteer

puppeteer 官网

puppeteer能做什么

  • 生成页面 PDF。

  • 抓取 SPA(单页应用)并生成预渲染内容(即"SSR"(服务器端渲染))。

  • 自动提交表单,进行 UI 测试,键盘输入等。

  • 创建一个时时更新的自动化测试环境。 使用最新的 JavaScript 和浏览器- 功能直接在最新版本的Chrome中执行测试。

  • 捕获网站的 timeline trace,用来帮助分析性能问题。

  • 测试浏览器扩展

安装

npm i puppeteer

使用

请使用高版本的node

官网说需要使用Node v6.4.0(async/await需要在Node v7.6.0)及以上版本,但是实测Node v14.21.3 运行不起来,目前我用的是 Node v22.1.0

创建文件

文件名为:example.js

js 复制代码
// 引入官网的一个例子,生成一个 example.png 图片
const puppeteer = require('puppeteer');

(async () => {
  const browser = await puppeteer.launch();
  const page = await browser.newPage();
  await page.goto('https://example.com');
  await page.screenshot({path: 'example.png'});

  await browser.close();
})();

执行命令

node example.js

API解读

puppeteer.launch()

创建一个浏览器实例

js 复制代码
const browser = await puppeteer.launch({
  ignoreHTTPSErrors: false, // 是否在导航期间忽略 HTTPS 错误. 默认是 false。
  executablePath: '', // 可运行浏览器的路径
  slowMo: 10, // 将 Puppeteer 操作减少指定的毫秒数。这样你就可以看清发生了什么,这很有用。
  defaultViewport: {  // 默认视口大小,默认800*600。如果为null的话就禁用视口
    width: 1920,
    height: 1080
  },
  timeout: 3000,  // 等待浏览器实例启动的最长时间(以毫秒为单位)。默认是 30000 (30 秒). 通过 0 来禁用超时。
  env: 'process.env', // 指定浏览器可见的环境变量。默认是 process.env。
});

// 关闭浏览器
await browser.close();

browser.newPage()

提供操作一个 tab 页,一个 Browser 实例可以有多个 Page 实例。

js 复制代码
const page = await browser.newPage();

监听事件 ononceremoveListener

Page会触发多种事件,可以用 node 原生的方法 来捕获处理,比如 on,once 或者 removeListener

  • 语法
js 复制代码
/**
 * 页面事件监听
 * @param {String} eventName 事件名称
 * @param {Function} Function 监听事件回调
 */
page.on(eventName, Function)
  • 示例
js 复制代码
page.on("request", (request) => {
  // 当请求发起后页面会触发这个事件。
  request.continue();
});

age.on("response", (response) => {
  // 请求收到响应的时候触发。
  // const headers = response.headers();
});

page.on("requestfailed", (request) => {
  // 请求失败时触发
  // console.log(request.url());
});
page.on("requestfinished", (request) => {
  // 请求完成并且响应体下载完成时触发
  // console.log(request.url());
});

page.on('framenavigated', (frame) => {
  // 监听url改变
  // frame.url()
})

页面导航/跳转 goto

  • 语法
js 复制代码
/**
 * 页面导航/跳转
 * @param {String} url 航到的地址. 地址应该带有http协议, 比如 https://.
 * @param {Object} options 导航配置,可选值
 * @param {String} options.timeout 跳转等待时间,单位是毫秒, 默认是30秒, 传 0 表示无限等待
 * @returns {Promise} Promise对象resolve后是主要的请求的响应。如果有多个跳转, resolve后是最后一次跳转的响应
 */
page.goto(url[, options])
  • 示例
js 复制代码
page.goto('https://www.baidu.com/')

执行 JavaScript evaluate

  • 语法
js 复制代码
/**
 * 执行 JavaScript
 * @param {Funtion | String} pageFunction 要在页面实例上下文中执行的方法
 * @param {Object} args 要传给 pageFunction 的参数
 * @returns {Promise} pageFunction执行的结果
 * @description 如果pageFunction返回的是Promise,page.evaluate将等待promise完成,并返回其返回值。
 * @description 如果pageFunction返回的是不能序列化的值,将返回undefined
 */
page.evaluate(pageFunction[, ...args])
  • 示例
js 复制代码
const result = await page.evaluate(x => {
  return Promise.resolve(8 * x);
}, 7); // (译者注: 7 可以是你自己代码里任意方式得到的值)
console.log(result); // 输出 "56"

console.log(await page.evaluate('1 + 2')); // 输出 "3"
const x = 10;
console.log(await page.evaluate(`1 + ${x}`)); // 输出 "11"

选择元素 $$$$eval$$eval

  • 语法
js 复制代码
/**
 * 选择元素
 * @param {String} selector 选择器
 */
page.$(selector)  // 此方法在页面内执行 document.querySelector。如果没有元素匹配指定选择器,返回值是 null。
page.$$(selector) // 此方法在页面内执行 document.querySelectorAll。如果没有元素匹配指定选择器,返回值是 []。

/**
 * 选择元素
 * @param {String} selector 选择器
 * @param {Function} pageFunction 在浏览器实例上下文中要执行的方法
 * @param {Object} args 要传给 pageFunction 的参数
 */
page.$eval(selector, pageFunction[, ...args]) // 此方法在页面内执行 document.querySelector,然后把匹配到的元素作为第一个参数传给 pageFunction。
page.$$eval(selector, pageFunction[, ...args])  // 此方法在页面内执行 Array.from(document.querySelectorAll(selector)),然后把匹配到的元素数组作为第一个参数传给 pageFunction。
  • 示例
js 复制代码
const searchValue = await page.$eval('#search', el => el.value);
const preloadHref = await page.$eval('link[rel=preload]', el => el.href);
const html = await page.$eval('.main-container', e => e.outerHTML);

const divsCounts = await page.$$eval('div', divs => divs.length)

等待指定的选择器匹配的元素出现在页面中 waitForSelector

  • 语法
js 复制代码
/** 
 * 等待指定的选择器匹配的元素出现在页面中
 * @param {String} selector 要等待的元素选择器
 * @param {Object} options 可选参数
 * @param {Boolean} options.visible 等元素出现在dom中并且可以看到, 比如。 没有 display: none 或者 visibility: hidden 样式。 默认是 false。
 * @param {Boolean} options.hidden 等元素在dom中消失或看不到, 比如。 有 display: none 或者 visibility: hidden 样式。 默认是 false。
 * @param {Number} options.timeout 最大等待时间,单位是毫秒,默认是30000 (30 seconds),传0表示不会超时
 * @returns {<Promise<ElementHandle>>} Promise对象,当指定选择器匹配的元素添加到dom中时
 */
page.waitForSelector(selector[, options])
  • 示例
js 复制代码
await page.waitForSelector('div)');

定位器 locator

  • 语法
js 复制代码
/**
 * 定位某个元素
 * @param {String} selector 选择器
 */
page.locator(selector);
  • 示例
js 复制代码
// 元素点击
await page.locator('button').click();

// 填写输入
await page.locator('input').fill('value');

// 将鼠标悬停在元素上
await page.locator('div').hover();

// 滚动一个元素
await page.locator('div').scroll({
  scrollLeft: 10,
  scrollTop: 20,
});

// 等待元素可见,等待元素变为 visible 或隐藏。
await page.locator('.loading').wait();
相关推荐
轻口味35 分钟前
命名空间与模块化概述
开发语言·前端·javascript
前端小小王1 小时前
React Hooks
前端·javascript·react.js
迷途小码农零零发1 小时前
react中使用ResizeObserver来观察元素的size变化
前端·javascript·react.js
娃哈哈哈哈呀2 小时前
vue中的css深度选择器v-deep 配合!important
前端·css·vue.js
旭东怪2 小时前
EasyPoi 使用$fe:模板语法生成Word动态行
java·前端·word
ekskef_sef4 小时前
32岁前端干了8年,是继续做前端开发,还是转其它工作
前端
sunshine6414 小时前
【CSS】实现tag选中对钩样式
前端·css·css3
真滴book理喻5 小时前
Vue(四)
前端·javascript·vue.js