🍉
「認証だけブラウザ自動操作で行って、あとはJSON APIをスクレイピング」をPlaywrightでカンタンにやる
まえおき
イマドキのSPAであれば、画面表示に必要な情報は裏でJSON APIっぽいものを叩いていることが多く、そういうサイトでスクレイピングをする場合には、ブラウザ自動操作をするよりもブラウザのふりをしてJSON APIを叩くほうが効率よく情報を取得できる。
ようは、Pythonでrequestsとか使ったほうがラク。
ただ、ログイン画面がある場合に、requestsだと少しややこしい。「それ、Playwrightだったらカンタンだよ!」という共有。
Playwright 1.16で導入された 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のスクレイピングに便利な機能とわかったので対応しました。
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.
最初は「storageStateつかえばええやん!」って流されそうになっているが、議論を重ねて Playwright 1.15で裏機能として実装される。
その後、Playwrightチーム内でのブラッシュアップを経て・・・
Playwright 1.16でAPI testingモードとしてリリースされた
Discussion