Puppeteer的入门教程和实践

涌现的背景

Chrome59(linux、macos)、 Chrome60(windows)以后,Chrome自带headless(无界面)形式很轻易做自动化测试或许爬虫。然则怎样和headless形式的Chrome交互则是一个题目。经由过程启动Chrome时的敕令行参数仅能完成浅易的启动时初始化操纵。Selenium、Webdriver等是一种解决方案,然则每每依靠浩瀚,不够扁平。

《Puppeteer的入门教程和实践》

Puppeteer是谷歌官方出品的一个经由过程DevTools协定掌握headless Chrome的Node库。能够经由过程Puppeteer的供应的api直接掌握Chrome模仿大部分用户操纵来举行UI Test或许作为爬虫接见页面来网络数据。

环境和装置

Puppeteer自身依靠6.4以上的Node,然则为了异步超等好用的async/await,引荐运用7.6版本以上的Node。别的headless Chrome自身对服务器依靠的库的版本请求比较高,centos服务器依靠偏稳固,v6很难运用headless Chrome,提拔依靠版本能够涌现种种服务器题目(包含且不限于没法运用ssh),最好运用高版本服务器。

Puppeteer由于是一个npm的包,所以装置很简朴:

npm i puppeteer

或许

yarn add puppeteer

Puppeteer装置时自带一个最新版本的Chromium,能够经由过程设置环境变量或许npm config中的PUPPETEER_SKIP_CHROMIUM_DOWNLOAD跳过下载。假如不下载的话,启动时能够经由过程puppeteer.launch([options])设置项中的executablePath指定Chromium的位置。

运用和例子

Puppeteer相似其他框架,经由过程操纵Browser实例来操纵浏览器作出响应的回响反映。

const puppeteer = require('puppeteer');

(async () => {
  const browser = await puppeteer.launch();
  const page = await browser.newPage();
  await page.goto('http://rennaiqian.com');
  await page.screenshot({path: 'example.png'});
  await page.pdf({path: 'example.pdf', format: 'A4'});
  await browser.close();
})();

上述代码经由过程puppeteer的launch要领生成了一个browser的实例,对应于浏览器,launch要领能够传入设置项,比较有效的是在当地调试时传入{headless:false}能够封闭headless形式。

const browser = await puppeteer.launch({headless:false})

browser.newPage要领能够翻开一个新选项卡并返回选项卡的实例page,经由过程page上的种种要领能够对页面举行经常使用操纵。上述代码就举行了截屏和打印pdf的操纵。

一个很壮大的要领是page.evaluate(pageFunction, …args),能够向页面注入我们的函数,如许就有了无穷能够

const puppeteer = require('puppeteer');

(async () => {
  const browser = await puppeteer.launch();
  const page = await browser.newPage();
  await page.goto('http://rennaiqian.com');

  // Get the "viewport" of the page, as reported by the page.
  const dimensions = await page.evaluate(() => {
    return {
      width: document.documentElement.clientWidth,
      height: document.documentElement.clientHeight,
      deviceScaleFactor: window.devicePixelRatio
    };
  });

  console.log('Dimensions:', dimensions);
  await browser.close();
})();

须要注重的是evaluate要领中是没法直接运用外部的变量的,须要作为参数传入,想要取得实行的效果也须要return出来。由于是一个开源一个多月的项目,如今项目很活泼,所以运用时自行查找api才保证参数、运用要领不会错。

调试技能

  1. 关掉无界面形式,偶然检察浏览器显现的内容是很有效的。运用以下敕令能够启动完整版浏览器:
const browser = await puppeteer.launch({headless: false})
  1. 减慢速率,slowMo选项以指定的毫秒减慢Puppeteer的操纵。这是另一个看到发生了什么的要领:
const browser = await puppeteer.launch({
  headless:false,
  slowMo:250
});

3.捕捉console的输出,经由过程监听console事宜。在page.evaluate里调试代码时这也很轻易:

page.on('console', msg => console.log('PAGE LOG:', ...msg.args));
await page.evaluate(() => console.log(`url is ${location.href}`));

4.启动细致日记纪录,一切大众API挪用和内部协定流量都将经由过程puppeteer定名空间下的debug模块举行纪录

 # Basic verbose logging
 env DEBUG="puppeteer:*" node script.js

 # Debug output can be enabled/disabled by namespace
 env DEBUG="puppeteer:*,-puppeteer:protocol" node script.js # everything BUT protocol messages
 env DEBUG="puppeteer:session" node script.js # protocol session messages (protocol messages to targets)
 env DEBUG="puppeteer:mouse,puppeteer:keyboard" node script.js # only Mouse and Keyboard API calls

 # Protocol traffic can be rather noisy. This example filters out all Network domain messages
 env DEBUG="puppeteer:*" env DEBUG_COLORS=true node script.js 2>&1 | grep -v '"Network'

爬虫实践

许多网页经由过程user-agent来推断装备,能够经由过程page.emulate(options)来举行模仿。options有两个设置项,一个为userAgent,另一个为viewport能够设置宽度(width)、高度(height)、屏幕缩放(deviceScaleFactor)、是不是是挪动端(isMobile)、有没有touch事宜(hasTouch)。

const puppeteer = require('puppeteer');
const devices = require('puppeteer/DeviceDescriptors');
const iPhone = devices['iPhone 6'];

puppeteer.launch().then(async browser => {
  const page = await browser.newPage();
  await page.emulate(iPhone);
  await page.goto('https://www.example.com');
  // other actions...
  await browser.close();
});

上述代码则模仿了iPhone6接见某网站,个中devices是puppeteer内置的一些罕见装备的模仿参数。

许多网页须要登录,有两种解决方案:

  1. 让puppeteer去输入账号密码

经常使用要领:点击能够运用page.click(selector[, options])要领,也能够挑选聚焦page.focus(selector)。
输入能够运用page.type(selector, text[, options])输入指定的字符串,还能够在options中设置delay迟缓输入更像真人一些。也能够运用keyboard.down(key[, options])来一个字符一个字符的输入。

  1. 假如是经由过程cookie推断登录状况的能够经由过程page.setCookie(…cookies),想要保持cookie能够定时接见。
Tip:有些网站须要扫码,然则雷同域名的其他网页却有登录,就能够尝试去能够登录的网页登录完应用cookie接见跳过扫码。

简朴例子

const puppeteer = require('puppeteer');

(async () => {
  const browser = await puppeteer.launch({headless: false});
  const page = await browser.newPage();
  await page.goto('https://baidu.com');
  await page.type('#kw', 'puppeteer', {delay: 100});
  page.click('#su')
  await page.waitFor(1000);
  const targetLink = await page.evaluate(() => {
    return [...document.querySelectorAll('.result a')].filter(item => {
      return item.innerText && item.innerText.includes('Puppeteer的入门和实践')
    }).toString()
  });
  await page.goto(targetLink);
  await page.waitFor(1000);
  browser.close();
})()

《Puppeteer的入门教程和实践》

求赞,别的迎接接见我的博客

    原文作者:undefined
    原文地址: https://segmentfault.com/a/1190000012924029
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞