puppeteer

avatar

前言

最近在捣鼓puppeteer模拟登录,记录一下遇到的问题

1. 跨域iframe的获取

就算是puppeteer,默认情况下,也会有同源策略的限制,不过可以添加启动参数来获取 github.com/puppeteer/p…

args: [
    '--disable-web-security', // 关闭安全策略
    '--disable-features=IsolateOrigins,site-per-process' // 多origin单一进程
  ]

然后使用以下来获取

await page.waitForSelector('#captcha_container iframe[src*="captcha"]')
const iframeEle = await page.$('#captcha_container iframe[src*="captcha"]')
const frame = await iframeEle.contentFrame()

page总会提供一个mainFrame,所以通常情况下page.xx()page.mainFrame().xx()是相同的。 pptr.dev/api/puppete…

2. iframe元素的定位

Api有个方法,可以获取元素相对于主框架的宽高和位置(左上角)

ElementHandle.boundingBox()

3. cookie

不像document.cookie受cookie选项的限制,page.cookie()会拿到所有的cookie 比如

[{
  name: '',
  value: '',
  domain: '',
  path: '/',
  expires: 1706439706.766258,
  size: 52,
  httpOnly: true,
  secure: true,
  session: false,
  sameSite: 'None',
  sameParty: false
}]

4. Promise和await的一些反直觉的组合

  1. 如果Promise的构造函数抛出异常的话,会自动reject(111)
function foo () {
  return new Promise((resolve, reject) => {
    throw 111
  })
}
foo().catch(e => {
  console.log(e);
})
  1. 如果Promise的构造函数为async函数 一定要try catch来处理可能的异常,因为回调函数中的rejected没地方处理。并调用resolve reject来转换Promise的状态
function foo () {
  return new Promise(async (resolve, reject) => {
    throw 111 // UnhandledPromiseRejectionWarning
  })
}
  1. async函数返回Promise, async不会再包装成Promise
async function bar () {
  return Promise.resolve(222)
}

bar().then((res) => {
  console.log(res);
})