non vorrei lavorare

昔はおもにプログラミングやガジェット系、今は?

puppeteerで動的にウインドウの大きさを変更するには

こんばんは。先週は次男が発熱で実家に居て、週末に自宅に帰ってきた@kjunichiです。

背景

puppeteerで非ヘッドレスモード(Chromiumが画面に表示されるモード)でブラウズしている様子をキャプチャーする際にChromiumのウインドウのサイズを変更したくなった。

page.setViewportでは、ウィンドウのサイズは変わらない

page.setViewportでは、ウインドウのサイズは変わらなかった。puppeteerでpdf等のファイルの保存した際の画面サイズは このメソッドで変更されるが、画面に表示されているウインドウのサイズは変わらなかった。

Chrominumのウインドウのサイズを変更するには

以下のISSUEを見つけた

github.com

ここに、ヒントになるコードが載っていた。

puppeteerで非ヘッドレスモードで表示されているウインドウのサイズを動的に変更できた

上記のISSUEで紹介されているコードを一部変更して動く以下のコードができた。

puppeteerでAPIは結局のところ、用意されておらず。

browser._connection

chromeと通信するためのコネクションを使って、直接DevTools Protocolをしゃべる事で、ウインドウサイズの 変更を行っている模様。

DevTools Protocolでウインドウのサイズを変更する際に必要なwindowsIdを以下のように2段階で取得している模様。

const { targetInfos: [{ targetId }] } = await browser._connection.send(
    'Target.getTargets'
)

const { windowId } = await browser._connection.send(
    'Browser.getWindowForTarget', {
      targetId
    }
)  

これらをまとめて以下のようなコードで、動的にpuppeteerで表示されたChromiumのウインドウのサイズを 変えることができた。

const puppeteer = require('puppeteer')


const run = async () => {
  const browser = await puppeteer.launch({
    headless: false,
    args: ['--disable-infobars', ]
  })

  const page = await browser.newPage()

  await page.goto('https://www.google.com/')

  await page.waitFor(1000)

  const { targetInfos: [{ targetId }] } = await browser._connection.send(
    'Target.getTargets'
  )

  const { windowId } = await browser._connection.send(
    'Browser.getWindowForTarget', {
      targetId
    }
  )
  console.log(`windowId = ${windowId}`)

  const myresize = async (c, wid, w, h) => {
    await page.setViewport({ width: w, height: h })
    await c.send('Browser.setWindowBounds', {
      bounds: {
        height: h,
        width: w
      },
      windowId: wid
    })
  }
  // Resize.
  myresize(browser._connection, windowId, 1300, 600)

  await page.goto('https://kjunichi.github.io/')
  await page.waitFor(3000)

  // Resize.
  myresize(browser._connection, windowId, 640, 480)

  //await page.goto('https://github.com/kjunichi/')
  await page.goto('https://www.apple.com/')
  await page.waitFor(6000)

  await browser.close()
}

run()

実行結果

実行委結果を以下のYouTubeのチャンネルに動画としてアップした。

youtu.be

参考資料

moznion.hatenadiary.com

関連記事

Chrome DevTools Protocolつながり

10年前の記事