ゼスト Tech Blog

ゼストは「護りたい。その想いを護る。」をミッションに、在宅医療・介護業界向けのSaaSを開発しています。

Puppeteerに初チャレンジしてうまくいかなかったところのまとめ

こんにちは。株式会社ゼストでエンジニアをしている武藏です。

本記事では、Puppeteerに初チャレンジした私が、「こうすればよかったかも」と思った課題感とその対策を紹介します。

Puppeteerとは

Puppeteerは、DevToolsプロトコルまたはWebDriver BiDiを介してChromeFirefoxを制御するための、高水準APIを提供するJavaScriptライブラリです。
Webページの自動操作、スクリーンショットの取得、PDF生成、フォーム送信、UIテストなど、ブラウザで手動で行うほとんどの操作を自動化できます。

主な特徴として、

  • ヘッドレスモード: ブラウザのUIなしで動作可能。サーバー環境での自動化に適しています。
  • API: シンプルで使いやすいAPIを提供。JavaScriptで直感的にブラウザ操作を記述できます。
  • Webスクレイピング: Webページからデータを抽出するスクレイピングに強力です。
  • パフォーマンス: 高速なブラウザ操作を実現します。

Puppeteerは、Web開発におけるテスト自動化や、Webサイトからの情報収集など、幅広い用途で活用できる強力なツールです。

文字列の検索がうまくいかない

開発中に、ある項目の検索がうまくいかない、というケースが発生しました。

原因を調査していくと、  (ノーブレークスペース)が含まれる要素を正しく取得できていないことが分かりました。

トリムや normalize-space、置換もなぜかうまく機能せず、部分一致でも要件を満たせなかったため、 最終的にはテキストを取得してNode側で置換するようにしました。

replace(/\s/g, " ") のようにNode側だと空白の正規表現の対象になります。

  が含まれる可能性がある箇所では、最初から割り切ってNode側で処理するのも一つの選択肢かもしれません。

あと、今回はセレクターにXPath方式を使用していましたが、他のセレクターなら違う対処法があるかもしれません。


ページ遷移やクリック操作が不安定

デバッグ環境では問題なく動作していても、環境やタイミングによっては、ネットワークが遅かったり、処理が輻輳して重くなったりして、処理が不安定になることがあります。

Puppeteer には、page.waitForSelector()page.waitForNavigation() など、表示を待つための関数が用意されており、適切に使用することで処理の失敗を抑えられます。

また、以下のように slowMo オプションを指定することで、全体の処理にディレイを入れることができます。

const browser = await puppeteer.launch({
  slowMo: 100
});

slowMo は全体に有効で、設定することで処理を安定させることができ便利なのですが、環境やタイミングによっては、スローモーションだけではカバーできず、処理が不安定になることがあります。

開発を進める中でも、この問題に直面し Wait の追加が必要になることがありました。

操作対象のサイトにクローラーと判定されるリスクを避けるためにも、スローモーションを設定しないというのは難しいですが、主要な処理の実装が揃った段階で、一度スローモーションを減らしてテストするなどして、スローモーションに依存しすぎていないか確認できればよいかと思いました。


セレクトボックスの選択が安定しない

データ量が多いセレクトボックスで Wait などを十分に設定していても、選択がうまく動かないケースがありました。 そこで、page.locator(selector) のように比較的新しい機能であるロケーターを使用してみたところ、それまでより安定して選択ができるようになりました。

Chromeのレコーダーで記録した操作を、スクリプトとしてエクスポートした場合も、現在はロケーターを使用したもので出力されるようなので、 最初からロケーターで統一していればよかったかもしれません。

まとめ

今回は Puppeteerを使用した中で、特に「こうすればよかった」と思った点を紹介しました。 今後Puppeteerを使う際の参考になれば幸いです。