【java办公自动化(7)】-- puppeteer+nodejs+java+chrome秒速加载动态网站,虐杀selenium
需求前言
最近用了selenium,尽管做了很多优化,但是性能还是很差,无奈只好上网另寻他法,看了node.js也可快速加载动态网站。于是,花了两小时,学习了下nodejs,没错就是学nodejs安装与卸载。两小时后,调bug开始了,苦战cmd,苦战chrome,苦战js。战报:大窩全胜。胜后写书总结经验,分享后人再战再胜。
效果展示
- 1、首先,需要安装nodejs环境,查看安装正确与否 node -v
- 然后,安装chrome,不能过低版本。
- 然后,写js文件
const puppeteer = require('puppeteer');
(async ()=> {
// chrome地址
const chromePath='C://Users//yanhui//AppData//Local//Google//Chrome//Application//chrome.exe';
//传进的将要解析的url网址
var args = process.argv.splice(2);
const address= args[0];
const browser = await puppeteer.launch({ignoreHTTPSErrors: true,headless: false,executablePath:chromePath,timeout:60000,args: ['--no-sandbox', '--disable-setuid-sandbox']});
// 打开新页面
const page = await browser.newPage();
//等待时间
var time=1000;
// 访问
await page.goto(address, {waitUntil: 'domcontentloaded'}).catch(err => console.log(err));
await page.waitFor(time);
var style,text;
page.evaluate(function(){
var style = document.createElement('style'),
text = document.createTextNode('body{background:#fff}');
style.setAttribute('type', 'text/css');
style.appendChild(text);
document.head.insertBefore(style, document.head.firstChild);
});
let content = await page.content()
console.log(content);
await browser.close();
})();
- async代表什么,代表快。快速访问,快速收割。
- process.argv.splice(2);参数传递,这个需要百度学习下nodejs命令行执行时带参数。
- ‘–no-sandbox’, '–disable-setuid-sandbox’无头浏览器了解下。
- 重点,请划上,要考:
var style,text;
page.evaluate(function(){
var style = document.createElement('style'),
text = document.createTextNode('body{background:#fff}');
style.setAttribute('type', 'text/css');
style.appendChild(text);
document.head.insertBefore(style, document.head.firstChild);
});
- 然后,Process process = Runtime.getRuntime().exec(exec);传参,
传递url参数即可,即可获取html的代码。
扩展需求
- puppeteer还可以截图,只要会js,走偏天下都不怕。
- 调用了 page.emulate方法按照给定设备对页面的尺寸进行了设定
- 自动化操作:
await page.goto('http://www.baidu.com')
await page.type('#index-kw', 'puppeteer')
await page.click('#index-bn')
await page.waitForNavigation({ timeout: 3000 })
await page.screenshot({
path: 'c:/temp/baidu_iphone_X_search_puppeteer.png'
})
- github地址:https://github.com/puppeteer/puppeteer
- 满大街都是vue,angular,react等前端框架写的网页的情况下,crawler就不能爬取js动态生成的内容了,这十分鸡肋。于是,研究了很久,找到了利用chromium作为沙盒环境进行爬虫的puppeteer爬虫框架,他的功能原本是模拟进行自动化测试的,可以捕获页面的截屏,获取页面的内容等,用来做动态内容的抓取,功能十分强大。示例及demo我放在github上了,可自取。
- 自动提交表单
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch({ headless: false })
const page = await browser.newPage()
await page.goto('http://www.baidu.com')
await page.type('#kw', 'puppeteer') // 键盘输入关键字
await page.waitFor(1000)
await page.click('#su') // 模拟用户点击搜索提交表单
await page.waitFor(2000)
await page.screenshot({ path: 'test/image/search.png', fullPage: true }) // 截全屏
await browser.close()
})()
- UI自动化测试
// ui测试
const puppeteer = require('puppeteer');
const devices = require('puppeteer/DeviceDescriptors');
const iPhone = devices['iPhone 6'];
(async () => {
const browser = await puppeteer.launch({ headless: false, slowMo: 0 });
const page = await browser.newPage();
await page.emulate(iPhone); // 让页面模拟成iphone6
await page.goto('https://m.v.qq.com/play.html?cid=rjvr8psrvic4567&vid=')
await page.screenshot({ path: 'test/image/1.png' })
// 点击登录
await page.click('.btn_user_text')
await page.waitFor(1000)
await page.screenshot({ path: 'test/image/2.png' })
// 点击qq登录
await page.waitFor(1000)
await page.click('.btn_qq')
await page.waitFor(1000)
await page.screenshot({ path: 'test/image/3.png' })
// 输入账号密码
await page.type('#u', '******') // 账号
await page.type('#p', '******') // 密码
await page.screenshot({ path: 'test/image/4.png' })
await page.waitFor(1000)
// 点击登录
await page.click('#go')
await page.waitFor(1000)
await page.screenshot({ path: 'test/image/5.png' })
await page.waitFor(1000)
await browser.close();
})()
- 动态渲染网站
// 爬虫
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch({ headless: false, slowMo: 0 });
const page = await browser.newPage();
await page.setViewport({ // 设置viewport大小
width: 375,
height: 600,
isMobile: true,
hasTouch: true
})
await page.goto('https://www.bilibili.com/');
let list = await page.evaluate(() => { // 爬取内容
const title = document.querySelectorAll('.ri-title')
const elements = Array.from(title);
let titles = elements.map(element => {
return element.innerHTML
})
return titles
});
console.log(list)
await page.waitFor(1000) // 等待时长
await page.evaluate(() => window.scrollTo(0, document.body.scrollHeight));
await browser.close();
})()
- 分析页面性能
// 性能分析
const puppeteer = require('puppeteer');
const devices = require('puppeteer/DeviceDescriptors');
const iPhone = devices['iPhone 6'];
(async () => {
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.emulate(iPhone); // 让页面模拟成iphone6
await page.tracing.start({ path: 'test/doc/trace.json' }); // 生成页面性能追踪的文件
await page.goto('https://www.bilibili.com/');
await page.tracing.stop();
browser.close();
})();