和node的差不多,只有写API不一样
1) 安装依赖
dependencies: puppeteer: ^1.7.1
2) 下载 chrome-win 到 <project_root>/.local-chromium/662092/ 下面,不然跑不起,要最新版的chromium,何以用cnpm下载 cnpm i puppeteer -S
然后在依赖里面找到复制出来。
dart ./bin/main.dart
import 'package:puppeteer/puppeteer.dart';main(Listarguments) async { var browser = await puppeteer.launch(headless: false); var myPage = await browser.newPage(); await myPage.goto('https://www.github.com', wait: Until.networkIdle);}
执行js
import 'package:puppeteer/puppeteer.dart';main(Listarguments) async { var browser = await puppeteer.launch( headless: false, devTools: true, ); var page = await browser.newPage(); await page.goto(base_url); // 执行一段js var title = await page.evaluate('''(newTitle) => { document.title = newTitle; return document.title }''', args: ["hello world"]); print(title); // 两秒后关闭浏览器 await Future.delayed(Duration(seconds: 2)); await browser.close();}
获取页面内的元素
// document.querySelector 没找到返回null var target = await page.$('#nav-dongman'); await target?.click() // document.querySelectorAll 没找到返回null var target = await page.$$('p'); await target?.elementAt(0)?.click() // document.querySelector然后把匹配到的元素作为第一个参数传给 pageFunction var target = await page.$eval('#nav-dongman', 'e => e.children[0].href'); print(target); // Array.from(document.querySelectorAll(selector)) 没找到返回null // 然后把匹配到的元素数组作为第一个参数传给 pageFunction // 如果 pageFunction 返回的是 Promise,那么此方法会等 promise 完成后返回其返回值 var target = await page.$$eval('p', '(es, index) => es[index].tagName', args: [0]); print(target); // 找到一个匹配 selector 选择器的元素,并点击它 // 如果需要会把此元素滚动到可视,然后通过 page.mouse 点击它。 如果选择器没有匹配任何元素,此方法将会报错 await page.click('#nav-dongman') // 找到一个匹配selector的元素,并且把焦点给它。 如果没有匹配的元素,此方法将报错 page.focus(selector) // 加载到页面中的所有iframe标签 // page.frames() // 要hover的元素的选择器,如果有多个匹配的元素,hover第一个 page.hover(selector) // page.select(selector, ...values) // 当提供的选择器完成选中后,触发change和input事件 如果没有元素匹配指定选择器,将报错 await page.select('select#colors', ['blue']) // 要点击的元素的选择器。如果有多个匹配的元素,点击第一个 // 如果需要会把此元素滚动到可视,然后通过 page.touchscreen 来点击元素的中间位置 如果没有匹配的元素,此方法会报错 await page.tap('#a') // 返回页面标题 await page.title; // 返回页面的 url await page.url; // 要输入内容的元素选择器。如果有多个匹配的元素,输入到第一个匹配的元素 // 每个字符输入后都会触发 keydown, keypress/input 和 keyup 事件 // 要点击特殊按键,比如 Control 或 ArrowDown,用 keyboard.press await page.type('form.form-horizontal input.form-control', 'hello world', delay: Duration(microseconds: 300)) // 等待指定的选择器匹配的元素出现在页面中 // 如果调用此方法时已经有匹配的元素,那么此方法立即返回。 如果指定的选择器在超时时间后扔不出现,此方法会报错 ElementHandle first_img = await page.waitForSelector('img', timeout: Duration(seconds: 10)); print(await first_img.propertyValue('src'));
页面导航
page.goBack([options]) 导航到页面历史的前一个页面page.goForward([options]) 导航到页面历史的后一个页面page.goto(url[, options]) 导航到的地址. 地址应该带有http协议, 比如 https://
向页面注入js
// 添加一个script标签到body的最后 await page.addScriptTag( content: 'alert(1)', type: 'text/javascript', );
向页面注入css
// 添加一个style标签到head的最后面 await page.addStyleTag(content: ''' p { color: red; }''')
返回页面的html代码
page.content()
指定启动页面的模拟器
var page = await browser.newPage(); // devices: https://github.com/GoogleChrome/puppeteer/blob/master/lib/DeviceDescriptors.js await page .emulate(Device('iPhone 7', userAgent: "Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/11.0 Mobile/15A372 Safari/604.1", viewport: DeviceViewport( width: 375, height: 667, deviceScaleFactor: 2, isMobile: true, hasTouch: true, isLandscape: false, ))); await page.goto(base_url);
禁用js
改变这个值不会影响已经执行的js。下一个跳转会完全起作用。await page.setJavaScriptEnabled(false);