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();