j3iiifn’s blog

ネットワーク、インフラ、プログラミングについての備忘録

pyppeteerでデバイスをエミュレートする

puppeteerでデバイスをエミュレートする方法はググればすぐに見つかるけど、pyppeteerでのやり方は見つからなかったのでメモしておく。

puppeteerなら const iPhone = puppeteer.devices['iPhone 8']; のようにライブラリで定義済みのデバイスを参照できるが、pyppeteerにはまだデバイスの定義は組み込まれていないようだ。

仕方ないので、puppeteerのデバイスを定義しているソースコード src/common/DeviceDescriptors.ts からUserAgentやViewPortの定義をコピーしてくる。

例えばiPhone 8をエミュレートしたい場合で説明する。

src/common/DeviceDescriptors.ts を探すと次のようなオブジェクトがある。

  {
    name: 'iPhone 8',
    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: {
      width: 375,
      height: 667,
      deviceScaleFactor: 2,
      isMobile: true,
      hasTouch: true,
      isLandscape: false,
    },
  },

これをPython風に書き直す。

IPHONE_8 = {
    'name': 'iPhone 8',
    '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': {
        'width': 375,
        'height': 667,
        'deviceScaleFactor': 2,
        'isMobile': True,
        'hasTouch': True,
        'isLandscape': False,
    }
}

そして、このdictをemulate関数の引数に渡す( page.emulate(IPHONE_8) )。

import asyncio
from pyppeteer import launch

async def main():
    browser = await launch()
    page = await browser.newPage()
    await page.emulate(IPHONE_8)
    await page.goto('https://example.com')
    await page.screenshot({'path': 'example.png'})
    await browser.close()

asyncio.get_event_loop().run_until_complete(main())