🍉

「認証だけブラウザ自動操作で行って、あとはJSON APIをスクレイピング」をPlaywrightでカンタンにやる

2022/01/26に公開

まえおき

イマドキのSPAであれば、画面表示に必要な情報は裏でJSON APIっぽいものを叩いていることが多く、そういうサイトでスクレイピングをする場合には、ブラウザ自動操作をするよりもブラウザのふりをしてJSON APIを叩くほうが効率よく情報を取得できる。

ようは、Pythonでrequestsとか使ったほうがラク。

ただ、ログイン画面がある場合に、requestsだと少しややこしい。「それ、Playwrightだったらカンタンだよ!」という共有。

Playwright 1.16で導入された API testingを使う

https://playwright.dev/docs/1.16/test-api-testing

API testing とは名ばかりで、実体はBrowserContext(認証情報とかローカルデータとか)の上でFetch APIっぽいものが使える機能。(後述する生い立ちを見ると、このあたりはわかりやすいかも)

// ログインページへ
await page.goto('https://your.service.com/login')

// 画面上で認証する
await page.click('#login')
await page.keyboard.type('YusukeIwaki')
await page.keyboard.press('Tab')
await page.keyboard.type('my_secret_password')
await Promise.all([
  page.waitForNavigation(),
  page.keyboard.press('Enter'),
])

// 認証済み状態で、JSON APIを色々たたく
const request = page.request

const currentUserResponse = await request.get('https://your.service.com/api/current_user')
console.log(await currentUserResponse.json())

const menuItemsResponse = await request.get('https://your.service.com/api/menu_items')
console.log(await menuItemsResponse.json())

これ、ものすごく直感的で便利〜。

(宣伝) playwright-ruby-clientでも対応した

個人で開発を続けているPlaywrightのRubyクライアントでは、「API testingならRSpecのrequest specで十分だろ」と思ってこれまでこの機能をサポートしてこなかったんですが、SPAのスクレイピングに便利な機能とわかったので対応しました。

https://github.com/YusukeIwaki/playwright-ruby-client/pull/195

v1.18.1以降と、v1.17.1で使えます。

Playwright.create(playwright_cli_executable_path: './node_modules/.bin/playwright') do |playwright|
  playwright.chromium.launch do |browser|
    page = browser.new_page
    
    # ログインページへ
    page.goto('https://your.service.com/login')
    page.click('#login')
    page.keyboard.type('YusukeIwaki')
    page.keyboard.press('Tab')
    page.keyboard.type('my_secret_password')
    page.expect_navigation do
      page.keyboard.press('Enter')
    end

    # 認証済み状態で、JSON APIを色々たたく
    request = page.request

    current_user = request.get('https://your.service.com/api/current_user').json
    menu_items = request.get('https://your.service.com/api/menu_items').json
  end
end

(参考) API testingの生い立ち

もともとの発端は↓のissue.
https://github.com/microsoft/playwright/issues/5999

最初は「storageStateつかえばええやん!」って流されそうになっているが、議論を重ねて Playwright 1.15で裏機能として実装される。
https://github.com/microsoft/playwright/pull/8349

その後、Playwrightチーム内でのブラッシュアップを経て・・・
https://github.com/microsoft/playwright/issues/8865

Playwright 1.16でAPI testingモードとしてリリースされた
https://github.com/microsoft/playwright/releases/tag/v1.16.0

Discussion