Puppeteer环境搭建的详细步骤


Posted in Javascript onSeptember 21, 2018

简介

Puppeteer是Google开发并开源的一款工具,可用代码驱动浏览器操作。

由于诸多优秀的特性,Puppeteer常被用在爬虫与自动化测试上。详细介绍参见官方 README 。

Puppeteer本身是个NodeJS的库,自动化脚本也需要使用NodeJS编写,如果对JS不了解建议先学习JavaScript基础语法,或者使用Selenium等其他工具去实现。

对于一个陌生的工具,应当先检查是否适合自己,再去尝试使用,切莫盲目从众。

Puppeteer 用处

  • 利用网页生成PDF、图片
  • 爬取SPA应用,并生成预渲染内容(即“SSR” 服务端渲染)
  • 可以从网站抓取内容
  • 自动化表单提交、UI测试、键盘输入等
  • 帮你创建一个最新的自动化测试环境(chrome),可以直接在此运行测试用例6.捕获站点的时间线,以便追踪你的网站,帮助分析网站性能问题

配置

Node环境配置

下载并安装NodeJS:

wget https://nodejs.org/dist/v8.12.0/node-v8.12.0-linux-x64.tar.xz
tar xf node-v8.12.0-linux-x64.tar.xz
mv node-v8.12.0-linux-x64 /usr/local/lib
ln -s /usr/local/lib/node-v8.12.0-linux-x64/bin/npm /usr/local/bin/
ln -s /usr/local/lib/node-v8.12.0-linux-x64/bin/node /usr/local/bin/

*(可选)配置淘宝的源,加速npm包的下载:

npm config set registry https://registry.npm.taobao.org

安装Puppeteer

配置淘宝的Puppeteer下载源,用于安装Chromium:

export PUPPETEER_DOWNLOAD_HOST=https://storage.googleapis.com.cnpmjs.org
npm i puppeteer

国内不配置时会在卡在下载Chromium

示例

新建一个test.js

const puppeteer = require('puppeteer');

(async () => {
 const browser = await puppeteer.launch({
  ignoreHTTPSErrors: true,
  headless: false,
  args: ['--no-sandbox']
 });
 const page = await browser.newPage();
 await page.goto('https://intest.tech');
 await page.waitFor(5e3);
 await browser.close();
})();

运行:

node test.js

截图

知识点

  • puppeteer.launch 启动浏览器实例
  • browser.newPage() 创建一个新页面
  • page.goto 进入指定网页
  • page.screenshot 截图
const puppeteer = require('puppeteer');

(async () => {
const browser = await (puppeteer.launch({
// 若是手动下载的chromium需要指定chromium地址, 默认引用地址为 /项目目录/node_modules/puppeteer/.local-chromium/
executablePath: '/Users/huqiyang/Documents/project/z/chromium/Chromium.app/Contents/MacOS/Chromium',
//设置超时时间
timeout: 15000,
//如果是访问https页面 此属性会忽略https错误
ignoreHTTPSErrors: true,
// 打开开发者工具, 当此值为true时, headless总为false
devtools: false,
// 关闭headless模式, 会打开浏览器
headless: false
}));
const page = await browser.newPage();
await page.goto('https://www.jianshu.com/u/40909ea33e50');
await page.screenshot({
path: 'jianshu.png',
type: 'png',
// quality: 100, 只对jpg有效
fullPage: true,
// 指定区域截图,clip和fullPage两者只能设置一个
// clip: {
// x: 0,
// y: 0,
// width: 1000,
// height: 40
// }
});
browser.close();
})();

进阶,获取网易云音乐的歌词和评论

网易云音乐的API经过AES和RSA算法加密,需要携带加密的信息通过POST方式请求才能获取到数据。但 Puppeteer 出现后,这些都不重要了,只要它页面上显示了,通过 Puppeteer 都能获取到该元素。

知识点

  • page.type 获取输入框焦点并输入文字
  • page.keyboard.press 模拟键盘按下某个按键,目前mac上组合键无效为已知bug
  • page.waitFor 页面等待,可以是时间、某个元素、某个函数
  • page.frames() 获取当前页面所有的 iframe,然后根据 iframe 的名字精确获取某个想要的 iframe
  • iframe.$('.srchsongst') 获取 iframe 中的某个元素
  • iframe.evaluate() 在浏览器中执行函数,相当于在控制台中执行函数,返回一个 Promise
  • Array.from 将类数组对象转化为对象
  • page.click() 点击一个元素
  • iframe.$eval() 相当于在 iframe 中运行 document.queryselector 获取指定元素,并将其作为第一个参数传递
  • iframe.$$eval 相当于在 iframe 中运行 document.querySelectorAll 获取指定元素数组,并将其作为第一个参数传递
const fs = require('fs');
const puppeteer = require('puppeteer');

(async () => {
const browser = await (puppeteer.launch({ executablePath: '/Users/huqiyang/Documents/project/z/chromium/Chromium.app/Contents/MacOS/Chromium', headless: false }));
const page = await browser.newPage();
// 进入页面
await page.goto('https://music.163.com/#');

// 点击搜索框拟人输入 鬼才会想起
const musicName = '鬼才会想';
await page.type('.txt.j-flag', musicName, {delay: 0});

// 回车
await page.keyboard.press('Enter');

// 获取歌曲列表的 iframe
await page.waitFor(2000);
let iframe = await page.frames().find(f => f.name() === 'contentFrame');
const SONG_LS_SELECTOR = await iframe.$('.srchsongst');

// 获取歌曲 鬼才会想起 的地址
const selectedSongHref = await iframe.evaluate(e => {
const songList = Array.from(e.childNodes);
const idx = songList.findIndex(v => v.childNodes[1].innerText.replace(/\s/g, '') === '鬼才会想起');
return songList[idx].childNodes[1].firstChild.firstChild.firstChild.href;
}, SONG_LS_SELECTOR);

// 进入歌曲页面
await page.goto(selectedSongHref);

// 获取歌曲页面嵌套的 iframe
await page.waitFor(2000);
iframe = await page.frames().find(f => f.name() === 'contentFrame');

// 点击 展开按钮
const unfoldButton = await iframe.$('#flag_ctrl');
await unfoldButton.click();

// 获取歌词
const LYRIC_SELECTOR = await iframe.$('#lyric-content');
const lyricCtn = await iframe.evaluate(e => {
return e.innerText;
}, LYRIC_SELECTOR);

console.log(lyricCtn);

// 截图
await page.screenshot({
path: '歌曲.png',
fullPage: true,
});

// 写入文件
let writerStream = fs.createWriteStream('歌词.txt');
writerStream.write(lyricCtn, 'UTF8');
writerStream.end();

// 获取评论数量
const commentCount = await iframe.$eval('.sub.s-fc3', e => e.innerText);
console.log(commentCount);

// 获取评论
const commentList = await iframe.$$eval('.itm', elements => {
const ctn = elements.map(v => {
return v.innerText.replace(/\s/g, '');
});
return ctn;
});
console.log(commentList);
})();

参考

https://github.com/cnpm/cnpmjs.org/issues/1246#issuecomment-341631992

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
浅谈tudou土豆网首页图片延迟加载的效果
Jun 23 Javascript
你必须知道的Javascript知识点之"字面量和对应类型"说明介绍
Apr 23 Javascript
JS保存和删除cookie操作 判断cookie是否存在
Nov 13 Javascript
捕获和分析JavaScript Error的方法
Mar 25 Javascript
jquery中toggle函数交替使用问题
Jun 22 Javascript
cocos2dx骨骼动画Armature源码剖析(一)
Sep 08 Javascript
Jquery左右滑动插件之实现超级炫酷动画效果附源码下载
Dec 02 Javascript
js判断图片加载完成后获取图片实际宽高的方法
Feb 25 Javascript
Angular2学习笔记——详解路由器模型(Router)
Dec 02 Javascript
浅谈React Native Flexbox布局(小结)
Jan 08 Javascript
React学习笔记之高阶组件应用
Jun 02 Javascript
Vue v-for中的 input 或 select的值发生改变时触发事件操作
Aug 31 Javascript
jQuery序列化form表单数据为JSON对象的实现方法
Sep 20 #jQuery
JavaScript 高性能数组去重的方法
Sep 20 #Javascript
vue2 设置router-view默认路径的实例
Sep 20 #Javascript
vue实现同一个页面可以有多个router-view的方法
Sep 20 #Javascript
vuejs router history 配置到iis的方法
Sep 20 #Javascript
关于单文件组件.vue的使用
Sep 20 #Javascript
vue-cli 打包使用history模式的后端配置实例
Sep 20 #Javascript
You might like
PHP 5.0 Pear安装方法
2006/12/06 PHP
POSIX 风格和兼容 Perl 风格两种正则表达式主要函数的类比(preg_match, preg_replace, ereg, ereg_replace)
2010/10/12 PHP
php实现mysql备份恢复分卷处理的方法
2014/12/26 PHP
PHP常用函数之格式化时间操作示例
2019/10/21 PHP
JavaScript prototype对象的属性说明
2010/03/13 Javascript
匹配任意字符的正则表达式写法
2010/04/29 Javascript
js数据验证集合、js email验证、js url验证、js长度验证、js数字验证等简单封装
2010/05/15 Javascript
判断用户的在线状态 onbeforeunload事件
2011/03/05 Javascript
JavaScript全排列的六种算法 具体实现
2013/06/29 Javascript
详谈jQuery中的this和$(this)
2014/11/13 Javascript
2014年50个程序员最适用的免费JQuery插件
2014/12/15 Javascript
JavaScript截取、切割字符串的技巧
2016/01/07 Javascript
jQuery插件实现图片轮播特效
2016/06/16 Javascript
最全面的百度地图JavaScript离线版开发
2016/09/10 Javascript
javascript 数组去重复(在线去重工具)
2016/12/17 Javascript
纯JS实现出生日期[年月日]下拉菜单效果
2018/06/01 Javascript
vue调试工具vue-devtools安装及使用方法
2018/11/07 Javascript
深入浅析nuxt.js基于ssh的vue通用框架
2019/05/21 Javascript
vue实现标签云效果的方法详解
2019/08/28 Javascript
微信小程序实现吸顶效果
2020/01/08 Javascript
vue 实现用户登录方式的切换功能
2020/04/14 Javascript
Vue常用API、高级API的相关总结
2021/02/02 Vue.js
Python 中导入csv数据的三种方法
2018/11/01 Python
简单了解python高阶函数map/reduce
2019/06/28 Python
python生成器/yield协程/gevent写简单的图片下载器功能示例
2019/10/28 Python
利用4行Python代码监测每一行程序的运行时间和空间消耗
2020/04/22 Python
Pygame的程序开始示例代码
2020/05/07 Python
Furla官网:意大利著名的皮革品牌
2019/08/06 全球购物
销售业务实习自我鉴定
2013/09/23 职场文书
工作会议欢迎词
2014/01/16 职场文书
监察建议书范文
2014/03/12 职场文书
篮球社团活动总结
2014/06/27 职场文书
个人授权委托书范文
2014/09/21 职场文书
求职信范文怎么写
2015/03/19 职场文书
运动会闭幕式致辞
2015/07/29 职场文书
微信小程序用户授权最佳实践指南
2021/05/08 Javascript