Puppeteer使いがPlaywrightを使ってみて感じた利点
ブラウザの自動操作にPuppeteerを利用しているが、試しにPlaywrightを使ってみたら良いと思う点が多かったのでまとめた。正直な感想を言うと、「ほぼ上位互換では?」と思うくらいには良い点が多かったし、悪い点は見つからなかった。同じ作者の後発なだけはある。
なお、Puppeteer歴1年、Playwright歴1日で書いているので、変な箇所があればご指摘ください。
利用バージョン
- Puppeteer :
5.5.05.4.1 - Playwright : 1.8.0
便利だと思った点
とても柔軟なselector
Puppeteerはpage.$x()
など一部でXPath selector が利用できるものの、page.click()
やpage.$eval()
など多くの関数ではCSS selectorしか利用できなかった。
しかし、Playwrightでは、selectorを利用するすべての関数で、CSS selectorもXPath selectorも利用できる。
それだけではなく、表示上のテキストでマッチさせるselectorがあったり、CSS selectorに便利な擬似クラスが追加してあったり、複数種類のSelectorを組み合わせるなど、かなり柔軟に要素が特定できる。
参照 : https://playwright.dev/docs/selectors
なお、独自のselectorを作成/登録することは、Puppeteer(5.4以降)でもPlaywrightでも可能。これを使うと、Puppeteerでも結構柔軟なselectorが作れると思う。
参照 : https://playwright.dev/docs/api/class-selectors
参照 : https://pptr.dev/#?product=Puppeteer&version=v5.5.0&show=api-interface-customqueryhandler
Auto-waiting
Puppeteerは要素が存在しない状態でelement.click()
などをするとエラーとなってしまうため、page.waitForSelector()
などで要素の出現を待ってから要素を操作する場面が多かった。
Playwrightでは、多くの操作でAuto waitingが採用されており、自動で一定時間要素の出現[1]を待ってくれる。これにより、page.waitForSelector()
を使わずに簡潔に書ける場面がかなり増えた。
参照 : https://playwright.dev/docs/actionability
innerHTML / isCheckedなど、地味に便利なメソッド
内部テキストの取得や、チェックボックスにチェックが入っているか、など状態の取得は、Puppeteerではpage.$eval()
などでブラウザ上でJavaScriptを走らせて取得していたが、Playwrightでは、element.innerText()
やelement.isChecked()
などの関数がデフォルトで用意されているため、書くときに時短になる。
ファイルダウンロード
Puppeteerはファイルのダウンロード処理に特化した処理がなく、ダウンロード完了を検知することができなかった。[2]
Playwrightでは、ダウンロードの開始をイベントとして知ることができ、完了までawaitすることもできるため、簡潔に書くことができる。
参照 : https://playwright.dev/docs/downloads
1行でファイル選択
<input type="file">でファイルを選択する際に、page.setInputFiles()
やelement.setInputFiles()
を利用すると、1行でファイルアップロード処理が可能
(Puppeteerと似たように書ける、FileChooser
クラスも用意されている。)
参照 : https://playwright.dev/docs/input#upload-files
fill()でinputのテキストを上書き
<input type="text">や<textarea>にテキストがすでに入っている場合、PuppeteerやPlaywrightのelement.type()
は、既存のテキストに追記する。
Playwrigtは、element.type()
とは別にelement.fill()
が用意されており、簡単にテキストの上書きができる。[3] Puppeteerでこれをやろうとすると、element.$eval()
を使う(changeイベントが発火しない)、トリプルクリックやCtrl+a
の後Delete
ボタン(何やっているのかわかりにくい)などイマイチだった。
参照 : https://playwright.dev/docs/input#text-input
参照 : https://playwright.dev/docs/api/class-elementhandle#elementhandlefillvalue-options
selectのoption指定にlabelやElemenHandleが使える
puppeteerでは、<select>の<option>指定はpage.select()
などでvalueを指定する必要があるが、value指定は結構面倒なことも多い。
playwrightでは、valueのほか、labelやindex(何番目のオプションか)も使えるし、なんならElementHandleの指定もできる。
参照 : https://playwright.dev/docs/api/class-elementhandle#elementhandleselectoptionvalues-options
コード自動生成
Puppeteerには、Puppeteer RecorderというChrome拡張のコードジェネレータがあるが、使ってみれば分かるが正直出来はあまりよろしくない。(イマイチの部分の多くは、ツール自体というよりはselectorの柔軟さのなさだが、それ以外の部分のコードも結構変。)[4]
Playwrightはコードジェネレータが付属しており、CLIからブラウザを起動して記録できるが、こちらはselectorの柔軟さも相まってそこそこ使えるコードを吐いてくれる。
参照 : https://playwright.dev/docs/intro#record-scripts
録画
browser.newPage()
などの引数に、recordVideo
オプションをつけることで録画が可能。
適当なページで試してみたら2分程のwebm動画(1280x720)で7MB程度[5]だった。
参照 : https://playwright.dev/docs/videos
多言語対応
PupetterはPythonバインディングであるPypetterがあるが、Playwrightは多言語対応が簡単になるような仕組みが用意されているようで、公式にPython/C#(Preview)/Java(Preview)に対応していほか、Rubyもそのうち対応するような書き方をしているし、独自に作っている人もいるようだ。
公式のRuby版が出たら試してみよう。
参照 : https://playwright.dev/docs/languages
クロスブラウザ対応
Playwrightのウリなので、一応触れておくと、Puppeteerよりも多くのブラウザに対応している。ただ、状況は少し複雑で単純な利点というわけではない。
ブラウザ | Puppeteer | Playwright |
---|---|---|
Chrome/Chromium | ○ | ○ |
Edge(Blink) | ○ | ○ |
Firefox | △(Nightly) | △(独自改造版) |
Webkit | × | △(独自改造版) |
Edge(EdgeHTML) | × | × |
IE | × | × |
Playwrightをインストールするときに、ブラウザを3つもダウンロードしてきて時間がかかると思っていたが、ブラウザを1つだけダウンロードするnpmパッケージが用意されているため、普段はこっちを使うと良さそう。
環境変数を設定することで、ブラウザのダウンロードをスキップすることも可能(Puppeteerでも可能)。
その他
ざっくりとしか使えていないので、あまり調査ができていない部分やマニュアルを見ただけで試していないものについて、ひとまずココにまとめる。
気になる機能をここに追記したり、試したものは別項目にしたりします。
- ViewPortを設定しなくてもブラウザいっぱいに表示される?
-
keyboard.press()
がPuppeteerよりも高機能なのでは? - ドキュメントのNight Mode が目に優しい
-
page.waitForLoadState()
はどういうとき使うのかよく分かっていない
Discussion
独自に作っている人ですw
半月くらいまえに、公式ページから、
この文章が消されてしまいました。
PlaywrightのSlackで「Ruby作らんの?」って聞いてみたんですが、いまのところ公式に作る予定は無いそうです...。
Ruby版、予定なくなったんですねー。残念です。
独自版の存在価値が高くなったということだと思うので、期待していますw