mkdir my-app
cd my-app
npm init -y
npm i puppeteer
# or "yarn add puppeteer"
複製代碼
npm i puppeteer-core
# or "yarn add puppeteer-core"
複製代碼
//import puppeteer from "puppeteer-core";//核心板
import puppeteer from "puppeteer";
const isDevelopment = process.env.NODE_ENV !== 'production'
this.browser = await puppeteer.launch({
headless: !isDevelopment,
executablePath: "C:/Program Files (x86)/Google/Chrome/Application/chrome.exe",
defaultViewport: {
width: 1349,
height: 600
}
})
複製代碼
headless默認true,開發環境使用false,能夠看到可視化頁面 executablePath:默認node_modules下的Chromium瀏覽器,能夠改成本地的chrome瀏覽器 defaultViewport:窗口大小,默認800×600頁面顯示不全html
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();
})();
複製代碼
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.goto('https://news.ycombinator.com', {waitUntil: 'networkidle2'});
await page.pdf({path: 'hn.pdf', format: 'A4'});
await browser.close();
})();
複製代碼
獲取視圖大小node
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.goto('https://example.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();
})();
複製代碼
await page.waitFor(2000);//hover前不加延遲,就會超時?????
await page.hover(moreBtnSelector)
複製代碼
(1)browser.pages()jquery
browser.pages()[0]
複製代碼
(2)page.url()、page.name()git
const page2 = (await browser.pages()).find(p => p.url().indexOf('beijing') > -1)
複製代碼
(3)使用targetcreated事件github
const newPagePromise = new Promise(x => this.browser.once('targetcreated', target => x(target.page()))); // targetcreated發生時就能夠獲得page
複製代碼
(1)page.frames()chrome
const frame1 = ( await page.frames() )[0]
複製代碼
(2)page.url()、page.name()。 page.url()獲得的地址和看到的src有時不相同, page.name()多是重複的npm
const frame1 = await page.frames().find(f => f.name() === 'allbox');
複製代碼
解決方法瀏覽器
const frame1 = await new Promise((resolve, reject) => {
let timer
let fn = () => {
if (timer) clearTimeout(timer)
let frame = page.mainFrame().childFrames().find(f => f.url().indexOf('xxx') > -1)
if (frame) {
resolve(frame)
} else {
timer = setTimeout(fn, 200)
}
}
fn()
})
const frame2 = await new Promise((resolve, reject) => {
let timer
let fn = () => {
if (timer) clearTimeout(timer)
let frame = frame1.childFrames().find(f => f.name() === 'lhsbIframe')
if (frame) {
resolve(frame)
} else {
timer = setTimeout(fn, 200)
}
}
fn()
})
複製代碼
await frame1.$eval('div[id="layui-layer1"]', f => f.style.display = 'none')
複製代碼
await this.typeInput('//input[@type="text" and @jpath and not(@readonly)]', page, frame2)
async typeInput(xPath, page, frame) {
if (!frame) frame = page;
const elementHandle = await frame.$x(xPath)
for (let i = 0; i < elementHandle.length; i++) {
let jpath = await frame.evaluate(el => el.getAttribute('jpath'), elementHandle[i])
let value = this.gf(jpath)
if (typeof value !== 'string') continue
await elementHandle[i].focus()
await this.inputClear(page)
await elementHandle[i].type(value)
}
await this.inputBlur(page);
}
複製代碼
//清空input
async inputClear(page) {
await page.keyboard.down('Control');
await page.keyboard.down('KeyA');
await page.keyboard.press('Backspace');//Backspace/Delete
await page.keyboard.up('Control');
await page.keyboard.up('KeyA');
}
複製代碼
//input失去焦點
async inputBlur(page) {
await page.click('body')
}
複製代碼
const body = await page.content();
const $ = await cheerio.load(body);
await page.evaluate(async () => {
const selector = await $('input[jpath="zzsybsbSbbdxxVO.qtkspzmxb.txffs"]')
await selector.focus();
await selector.val(7777);
await selector.trigger("input").trigger('propertychange').trigger("change")
//ng使用了modal雙向綁定,須要手動觸發onInput事件
await selector.blur();
}, $);
複製代碼