【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();
})();
知識付費
如需獲取代碼,請加WX(bin490647751),支付9.9元,可獲取【java辦公自動化】系列文章。