Puppeteer是NPM庫,它提供了NodeJS高級API來控制Chrome。Puppeteer 默認以無頭(無界面)方式運行,但也可以配置為運行有界面的Chrome。
Puppeteer 提供了一系列 API,通過 Chrome DevTools Protocol 協議控制 Chromium/Chrome 瀏覽器的行為。
1、 爬取網頁元素(vs中例子:title)
await page.waitForSelector('h4', {timeout: 10 * 1000});
先獲取選擇器,再使用page.$(‘selector’)獲取單個元素,
page.$$(‘selector’)獲取元素組,
page.$eval(‘selector’,pagefunction[參數,參數])獲取單個元素屬性
page.$$eval(‘selector’,pagefunction[參數,參數])獲取多個元素屬性
2、模擬鍵盤(vs中keyboard)
先page.goto去一個網頁,page.$(‘selector’)找到選擇器對應的框,再page.keyboard.type(‘輸入’),page.keyboard.press(左鍵或者右鍵),點擊左鍵或者右鍵,page.keyboard.up(‘鍵’)抬起鍵,page.keyboard.doan(‘鍵’),按下鍵
3、 打印出該網頁包含的所有子網頁以及他們的selector(vs中iframe)
dumpFrameTree(page.mainFrame(), '');
await browser.close();
function dumpFrameTree(frame, indent) {
console.log(indent + frame.url());
for (let child of frame.childFrames())
dumpFrameTree(child, indent + ' ');
4、文件上傳(vs中upload)
//創建一個Page實例
const page = await browser.newPage();
//跳轉百度首頁
await page.goto("https://www.baidu.com");
//等待元素加載成功
const soutuBtn = await page.waitForSelector('span.soutu-btn');
//點擊上傳圖片按鈕
await soutuBtn.click();
//uploadFile上傳圖片
const uploadPic = await page.waitForSelector('input.upload-pic');
//上傳圖片目錄自定義
await uploadPic.uploadFile('C:\\Users\\baiwenjing\\Desktop\\圖片.jpg');
await page.waitFor(3000);
await page.screenshot({ path: 'upload.png'})
5、定位輸入框,進行輸入
const user = await page.$('#fm-login-id');
await user.type('bwj990502');
const password = await page.$('#fm-login-password');
await password.type('123456');
先page.$(‘選擇器’),找到輸入的元素,之后.type(‘輸入’),進行輸入,也可用模擬鍵盤輸入。
6、鼠標操作:
- mouse.click(x, y, [options]) 移動鼠標指針到指定的位置,然后按下鼠標,這個其實 mouse.move 和 mouse.down 或 mouse.up 的快捷操作
- mouse.down([options]) 觸發 mousedown 事件,options 可配置:
- options.button 按下了哪個鍵,可選值為[left, right, middle], 默認是 left, 表示鼠標左鍵
- options.clickCount 按下的次數,單擊,雙擊或者其他次數
- delay 按鍵延時時間
- mouse.move(x, y, [options]) 移動鼠標到指定位置, options.steps 表示移動的步長
- mouse.up([options]) 觸發 mouseup 事件
7、 Page.waitFor 系列 API
- page.waitFor(selectorOrFunctionOrTimeout[, options[, …args]]) 下面三個的綜合 API
- page.waitForFunction(pageFunction[, options[, …args]]) 等待 pageFunction 執行完成之后
- page.waitForNavigation(options) 等待頁面基本元素加載完之后,比如同步的 HTML, CSS, JS 等代碼
- page.waitForSelector(selector[, options]) 等待某個選擇器的元素加載之后,這個元素可以是異步加載的,這個 API 非常有用,你懂的。
比如我想獲取某個通過 js 異步加載的元素,那么直接獲取肯定是獲取不到的。這個時候就可以使用 page.waitForSelector 來解決:
await page.waitForSelector('.gl-item'); //等待元素加載之后,否則獲取不到異步加載的元素
const links = await page.$$eval('.gl-item > .gl-i-wrap > .p-img > a', links => {
return links.map(a => {
return {
href: a.href.trim(),
name: a.title
}
});
});
8、await page.hover(‘selector’) 模擬鼠標移動到被選擇元素上,只是移動到並未點擊,點擊該元素要使用await page.click(‘selector’);
9、page.tap(‘selector’) 在被選擇元素上模擬觸摸,相當於點擊
10、當有iframe多層框架的時候,先要用page.frames()打印出所有fram的信息,然后用const frame=.await page.frames().find(f=>f.name()===’name’;來切換到該frame頁面
const frames = await page.frames();//得到所有的frame框
console.log(frames.length);//查看得到的frame列表數量
// console.log(frames); //打印出所有的iframe框信息
const frame = await page.frames().find(f => f.name() === 'login-iframe-2019');
await frame.waitForTimeout(1000);
11、當之前的頁面是frame頁面,再切換到一個新頁面時,要想得到她的page對象,可以用
//方法一:browser.pages(),可以獲取所有打開的Page對象,可以通過遍歷或篩選找到自己想獲取的Page對象 網頁的標號從0開始
const newPage = (await browser.pages())[2];
//方法二:通過browser.waitForTarget獲取target
const target = await browser.waitForTarget(t => t.url().includes('網址'));
const newPage = await target.page();
12、屏幕自動滾動
await newPage.evaluate(async () => {
await new Promise((resolve, reject) => {
var totalHeight = 0;
var distance =50;
var timer = setInterval(() => {
var scrollHeight = document.body.scrollHeight;
window.scrollBy(0, distance);
totalHeight += distance;
if (totalHeight >= scrollHeight) {
clearInterval(timer);
resolve();
}
}, 100);
});
});
13、雙擊
await page.click('.link-page-wrap',{ clickCount: 2 });
const foo = await page.$('.foo-item');
await = foo.click();
await = foo.click({ clickCount: 2 });
14、顯示隱藏的元素
await page.evaluate(() => { document.querySelector('mySelector').style.display = 'yes'; });
15、元素拖拽
const e = await page.$('#searchResultsSidebar');
const box = await e.boundingBox();
await page.mouse.move(box.x + box.width / 2, box.y + boy.height / 2);
await page.mouse.down();
await page.mouse.move(100, 200); // move to (100, 200) coordinates
await page.mouse.up();