# Puppeteer
Puppeteer 是一个 Node 库,它提供了一个高级 API 来通过 DevTools 协议控制 Chromium 或 Chrome。
Puppeteer API 概览
# puppeteer
puppeteer.connect(options)-- 将puppeteer添加到已有的chromium实例puppeteer.createBrowserFetcher([options])puppeteer.defaultArgs([options])--chromium启动时使用的默认参数puppeteer.executablePath()-- 查询绑定的chromium路径puppeteer.launch([options])-- 使用 defaultArgs 默认值启动chromium及通过 executablePath 等管理它的进程,然后生成一个browser实例并初始化
# Browser
Events
browser.on('disconnected')-- pptr 断开连接时触发browser.on('targetchanged')-- 当url改变时触发browser.on('targetcreated')-- 当目标被创建时触发,如window.open、browser.newPage打开新页面browser.on('targetdestroyed')-- 当目标被销毁时被触发,例如当一个页面被关闭时
Methods
browser.browserContexts()-- 返回一个包含所有打开的浏览器上下文数组,在新创建的浏览器中,这将返回browserContexts的单一实例browser.close()-- 关闭chromium及所有页面,browser不能再被使用browser.createIncognitoBrowserContext()-- 创建匿名的浏览器上下文,且不分享cookies/cachebrowser.defaultBrowserContext()-- 返回默认的浏览器上下文,且不能被关闭browser.disconnect()-- 断开连接,但chromium进程不关闭,且browser不能再被使用browser.newPage()-- 返回新的Page对象(开标签页)browser.pages()-- 返回浏览器中所有的页面browser.process()-- 产生浏览器的进程,如果是pptr.connect创建的则返回nullbrowser.target()-- 目标对象browser.targets()-- 所有活动目标browser.userAgent()-- 原始的uabrowser.version()-- 版本browser.wsEndpoint()-- 返回浏览器websocket地址
# Page
Events
page.on('close')page.on('console')-- 调用了console的方法page.on('dialog')-- 对话框page.on('domcontentloaded')page.on('error')page.on('frameattached')--iframe加载时触发page.on('framedetached')--iframe移除时触发page.on('framenavigated')--iframe导航到新的 url 时触发page.on('load')page.on('metrics')-- 调用了console.timestamp时触发page.on('pageerror')-- 当发生页面js代码没有捕获的异常时触发page.on('request')page.on('requestfailed')page.on('requestfinished')page.on('response')page.on('workercreated')-- 当页面生成响应的webworker时触发page.on('workerdestroyed')-- 当页面终止响应的websocket时触发
Namespace
page.accessibility-- 命名空间,返回Accessibilitypage.coverage-- 命名空间,返回Coveragepage.keyboard-- 命名空间,返回Keyboardpage.mouse-- 命名空间,返回Mousepage.touchscreen-- 命名空间,返回Touchscreenpage.tracing-- 命名空间,返回Tracing
Methods
page.$(selector)-- 相当于执行document.querySelectorpage.$$(selector)-- 相当于执行document.querySelectorAllpage.$$eval(selector, pageFunction[, ...args])-- 执行Array.from(document.querySelectorAll(selector)),并将结果传给pageFunctionpage.$eval(selector, pageFunction[, ...args])-- 将选择到的第一个元素传给pageFunctionpage.$x(expression)-- 解析指定的XPath表达式page.addScriptTag(options)-- 注入一个指定src或代码的script标签到当前页面page.addStyleTag(options)-- 注入样式page.authenticate(credentials)-- 认证凭据page.bringToFront()-- 切换到某个tabpage.browser()-- 当前page实例所属的browser实例page.click(selector[, options])page.close([options])-- 在beforeUnload前默认不执行page.content()- 返回页面完整的HTML代码page.cookies([...urls])-- 返回当前域名的cookie或返回指定url下的cookiepage.deleteCookie(...cookies)page.emulate(options)-- 根据指定的参数和ua生成模拟器page.emulateMedia(mediaType)-- 改变页面的css媒体类型page.evaluate(pageFunction[, ...args])page.evaluateHandle(pageFunction[, ...args])page.evaluateOnNewDocument(pageFunction[, ...args])page.exposeFunction(name, puppeteerFunction)-- 添加一个名为name的方法到window对象page.focus(selector)-- 聚焦与selectorpage.frames()-- 返回所有的iframe标签page.goBack([options])-- 回退page.goForward([options])-- 前进page.goto(url[, options])-- 跳转到指定地址page.hover(selector)-- 指定元素hoverpage.isClosed()-- 页面是否被关闭page.mainFrame()-- 保证页面一直有一个主iframepage.metrics()-- 返回包含指标数据的键值对page.pdf([options])-- 生成当前页面的PDFpage.queryObjects(prototypeHandle)-- 遍历js对战,找到带有指定原型的对象page.reload([options])page.screenshot([options])-- 截图page.select(selector, ...values)-- 选择器page.setBypassCSP(enabled)-- 绕过页面的安全策略page.setCacheEnabled([enabled])-- 设置每个请求忽略缓存,默认是启用page.setContent(html[, options])-- 注入HTML?page.setCookie(...cookies)page.setDefaultNavigationTimeout(timeout)-- 设置默认跳转等待时间page.setExtraHTTPHeaders(headers)-- 设置额外的http请求头page.setGeolocation(options)-- 设置坐标点page.setJavaScriptEnabled(enabled)-- 是否启用js,下个页面会起作用page.setOfflineMode(enabled)-- 启用离线模式page.setRequestInterception(value)-- 请求拦截器page.setUserAgent(userAgent)-- 设置uapage.setViewport(viewport)-- 设置viewportpage.tap(selector)-- 匹配selector,滚动到可视区域并点击page.target()page.title()page.type(selector, text[, options])-- 输入内容page.url()page.viewport()page.waitFor(selectorOrFunctionOrTimeout[, options[, ...args]])-- 等待page.waitForFunction(pageFunction[, options[, ...args]])page.waitForNavigation([options])page.waitForRequest(urlOrPredicate[, options])page.waitForResponse(urlOrPredicate[, options])page.waitForSelector(selector[, options])page.waitForXPath(xpath[, options])-- 等待xPath对应的元素出现page.workers()-- 返回与页面关联的webworkers
# Worker
worker.evaluate(pageFunction, ...args)-- 等待并解析返回的值worker.evaluateHandle(pageFunction, ...args)worker.executionContext()worker.url()
# Accessibility
accessibility.snapshot([options])-- 截屏
# Keyboard
keyboard.down(key[, options])keyboard.press(key[, options])keyboard.sendCharacter(char)-- 分发一个press和input事件,但不会发送keydown或keyup事件keyboard.type(text, options)-- 输入内容keyboard.up(key)
# Mouse
mouse.click(x, y, [options])mouse.down([options])mouse.move(x, y, [options])--mousemove事件mouse.up([options])
# Touchscreen
touchscreen.tap(x, y)-- 触发touchstart、touchend事件
# Tracing
tracing.start(options)-- 跟踪tracing.stop()-- 停止跟踪
# Dialog
dialog.accept([promptText])-- 提示中输入的文本dialog.defaultValue()-- 如果对话框出现提示,返回默认值,否则返回空字符串dialog.dismiss()-- 返回一个promisedialog.message()-- 显示在对话框中的信息dialog.type()-- 对话框类型
# ConsoleMessage
consoleMessage.args()consoleMessage.text()consoleMessage.type()
# Frame
frame.$(selector)-- 查询指定选择器frame.$$(selector)-- 执行querySelectorAll方法frame.$$eval(selector, pageFunction[, ...args])-- 将querySelectorAll选择的数据遍历传给pageFunction的第一个参数frame.$eval(selector, pageFunction[, ...args])-- 同1、3frame.\$x(expression)-- 执行XPath表达式frame.addScriptTag(options)frame.addStyleTag(options)frame.childFrames()-- 子frameframe.click(selector[, options])-- 选择元素,滚动到可视区域内,并触发page.mouse点击事件frame.content()-- 获取框架的所有内容frame.evaluate(pageFunction, ...args)-- 相当于先执行pageFunction后再返回frame.evaluateHandle(pageFunction, ...args)-- 返回页面对象frame.executionContext()-- 返回解析为框架的默认执行上下文的promiseframe.focus(selector)-- 传入元素并使获得焦点frame.goto(url, options)frame.hover(selector)-- 同focusframe.isDetached()-- 不被加载?加载失败返回true,否则返回falseframe.name()frame.parentFrame()frame.select(selector, ...values)-- 指定下拉框及值,一旦选择了会触发change和input事件frame.setContent(html)frame.tap(selector)-- 滚动到可视区域frame.title()-- 获取titleframe.type(selector, text[, options])-- 输入内容frame.url()-- 获取urlframe.waitFor(selectorOrFunctionOrTimeout[, options[, ...args]])-- 等待selector或延迟n毫秒frame.waitForFunction(pageFunction[, options[, ...args]])frame.waitForNavigation(options)frame.waitForSelector(selector[, options])frame.waitForXPath(xpath[, options])
# ExecutionContext
executionContext.evaluate(pageFunction, ...args)executionContext.evaluateHandle(pageFunction, ...args)executionContext.frame()executionContext.queryObjects(prototypeHandle)
# JSHandle
jsHandle-- 可以使用page.$eval(),page.evaluate(),page.evaluateHandle()方法创建jsHandle.asElement()-- 如果对象句柄是ElementHandle的一个实例,则返回该句柄本身或nulljsHandle.dispose()-- 停止引用jsHandle.executionContext()-- 返回所属的执行上下文jsHandle.getProperties()-- 包含属性名称作为键的映射和属性值的JSHandle实例jsHandle.getProperty(propertyName)-- 从引用的对象中获取单个属性jsHandle.jsonValue()-- 返回对象的JSON表示
# ElementHandle
elementHandle.$(selector)elementHandle.$$(selector)elementHandle.$eval(selector, pageFunction, ...args)elementHandle.$$eval(selector, pageFunction, ...args)elementHandle.$x(expression)elementHandle.asElement()elementHandle.boundingBox()-- 返回元素的边界框elementHandle.boxModel()-- 返回盒模型elementHandle.click([options])elementHandle.contentFrame()elementHandle.dispose()elementHandle.executionContext()elementHandle.focus()elementHandle.getProperties()-- 该方法返回一个包含属性名称作为键的映射和属性值的 JSHandle 实例elementHandle.getProperty(propertyName)-- 获取属性elementHandle.hover()elementHandle.isIntersectingViewport()-- 是否处于可视区域内elementHandle.jsonValue()elementHandle.press(key[, options])elementHandle.screenshot([options])-- 将元素滚动到视图中,然后再截图elementHandle.tap()elementHandle.toString()elementHandle.type(text[, options])-- 输入内容elementHandle.uploadFile(...filePaths)-- 上传文件
# Request
request.abort([errorCode])-- 中断请求,需要使用page.setRequestInterception开启拦截request.continue([overrides])-- 覆写选项并继续请求request.failure()request.frame()-- 返回发起请求的framerequest.headers()-- 请求的http头对象request.isNavigationRequest()-- 这个请求是否正在驱动框架在导航request.method()-- 请求方法request.postData()-- 请求提交的数据request.redirectChain()-- 获取资源的请求链request.resourceType()-- 请求资源类型request.respond(response)-- 完成请求后返回的响应内容request.response()-- 响应对象request.url()-- 获取请求的url
# Response
response.buffer()-- 如果返回内容的是二进制流response.frame()-- 响应请求的frameresponse.fromCache()-- 如果来自缓存,返回trueresponse.fromServiceWorker()-- 如果来自service worker,返回trueresponse.headers()-- 响应头response.json()-- 响应体,且可被JSON.parse解析response.ok()-- 响应是否成功response.remoteAddress()-- 远程服务器ip和端口response.request()-- 返回匹配的request对象response.securityDetails()-- 安全细节response.status()-- 状态码response.statusText()-- 状态文本response.text()-- 响应内容response.url()-- 响应url
# SecurityDetails
securityDetails- 通过安全链接收到响应时的安全性详细信息securityDetails.issuer()securityDetails.protocol()securityDetails.subjectName()securityDetails.validFrom()securityDetails.validTo()
# Target
target.browser()-- 目标所属的浏览器target.browserContext()target.createCDPSession()-- 创建一个chrome devtools协议回话至目标target.opener()target.page()-- 返回是否为page或background_page类型target.type()-- 类型target.url()-- 链接
# CDPSession
cdpSession-- 用于与 chrome devtools 协议的原生通信cdpSession.detach()-- 分离、断开连接cdpSession.send(method[, params])-- 发送信息
# Coverage
coverage.startCSSCoverage(options)coverage.startJSCoverage(options)coverage.stopCSSCoverage()coverage.stopJSCoverage()
# TimeoutError
某些操作因超时而终止时,就会触发