Playwright 入門
はじめに
Node.js 使ってスクレイピングする必要があったので、Playwright を使ってみました。
Playwright 使ってスクレイピングする時、こんな感じで使い始めたらいいんじゃないかなーと思う方法をまとめます。
Playwright
Playwright の公式サイトによると、Fast and reliable end-to-end testing for modern web apps
らしいです。
いろんなブラウザ、いろんな OS、いろんなプログラミング言語に対応してて、いい感じです。
他のツールないか調査してみたんですが、観測範囲では、今(2022 年)はじめるなら、Playwright 一択な雰囲気でした。
公式ドキュメントが充実してるので、基本的にはそれをみながら試すのが良いのかなと思います。
インストール
ドキュメントにもあるように、Node.js が入っていればサクッとインストールできます。ブラウザを含んでいるからか少し時間がかかりました。
npm init playwright@latest
コード自動生成
まず、Playwright の強力さを知るために、コード自動生成機能を使ってみるのが良いかなと思います。
下記コマンドで、ブラウザを開いて操作すると、操作に対応したコードが生成されます。すごい。
npx playwright codegen wikipedia.org
こんな感じで生成されます。
詳しくは、ここら参照です。
色々操作
Playwright すげぇってなったら、Node.js のプロジェクトを立ち上げて、色々試すのが良いと思います。
npm init --yes
私は、Twilio の下記ブログ記事を真似して実行してみました。
Automated Headless Browser scripting in Node.js with Playwright
以下で、いろんな操作をまとめます。
スクリーンショット
スクリーンショット取るとブラウザを操作してる実感がわきます。どんどん取りましょう。
await page.screenshot({ path: "example.png" });
クリック
クリックするとブラウザを操作してる実感がわきます。どんどんクリックしましょう。
Page
とかLocator
が持ってます。
await page.click(".modal-footer > button");
// ...
const locator = page.getByText("Submit");
await locator.click();
Pages | Playwright
Locators | Playwright
キー入力
キー入力すると、インタラクティブなテスト・スクレイピングしてる実感がわきます。どんどん入力しましょう。
await page.keyboard.type("Philadelphia");
マウス操作
マウス操作すると、SPA なサイトも動かせます。どんどん操作しましょう。
await page.mouse.move(100, 100);
await page.mouse.wheel(0, 12000);
要素取得
要素を取得することこそがスクレイピングです。どんどん取得しましょう。いろんな条件で取得できます。正規表現っぽいのも使えたりするみたいです。
やり方が色々あってややこいので、「やりたいことを英語で調べる(Stack Overflow にたどり着きがち)→ 使ってる文法を公式ドキュメントで調べる → 試してみる」みたいなサイクルを繰り返すのが良いのかなと思ってます。
const loc1 = page.locator("div .hoge");
const loc2 = page.locator("text=fuga");
const label = (await loc1.getAttribute("aria-label")) || "";
const innerText = await loc2.innerText();
ディベロッパーツールと仲良くなる。
要素を確認しまくるので、ディベロッパーツールの Elements を見ながらの作業になりそうです。
Google Chrome デベロッパーツールの基本的な使い方をわかりやすく解説
Locators、Selectors と仲良くなる。
Locators と Selectors を使いまくって、欲しい情報を取得してく必要がありそうです。エディタの保管機能で使えそうな関数を探して使ってましたが、結局公式のドキュメント見た方が詳しいので、そっちを見ながらやりたいことできる方法を探すのが良いのかなと思います。
Locator.locator()
が面白い。
Locator.locator()
を使って、取ってきた DOM をさらにフィルタリングできるのが面白いなと思いました。ややこいけど。
(method) Locator.locator(selector: string, options?: {
has?: Locator | undefined;
hasText?: string | RegExp | undefined;
} | undefined): Locator
Locator は、配列じゃないのに複数要素が入るのでうまいことバラす必要があるの辛い。
Locator には複数の要素が入ることがあって、そのまま使おうとすると、strict mode violation
とかいうエラーが出ます。なんで配列じゃないねんって感じですが、下記のように、for 文で要素を取り出して使うことができます。
const arrayOfLocators = page.locator("some-selector");
const elementsCount = await arrayOfLocators.count();
let texts = [];
for (var index = 0; index < elementsCount; index++) {
const element = await arrayOfLocators.nth(index);
const innerText = await element.innerText();
texts.push(innerText);
}
参考:[Question] Is there way to iterate the Locator elements? · Issue #10648 · microsoft/playwright
おわりに
他にもつまづきポイントありそうですが、上記操作を触ってみたら、ブラウザ操作できそうな気がしてくると思います。(私はしてきました。)
スクレイピングとか E2E テストとか、HTML のタグみたり辛そうだなぁと思ってましたが(実際、そこそこ辛いけど)、コード自動生成できたり、思ったよりもなんとかなりそうな気がしました。
そのうち、Docker 上でも動かしてみたいなと思います。
Docker | Playwright
Discussion