このPuppeteer Stealthチュートリアルでは、以下の内容を取り上げます:
- ボット検出とは何か、そしてなぜそれがPuppeteerにとって問題となるのか。
- Puppeteer Extraとは何か。
- ブロックを回避するためにPuppeteer Extra Stealthプラグインを使用する方法。
ボット検出:Puppeteerの最大の敵
Puppeteerは、ブラウザ自動化において最も広く使用されているJavaScriptライブラリの一つです。GoogleのChromeチームが開発を支援しているため、非常に人気があります。その高レベルなAPIにより、DevTools Protocolを介してヘッドレスまたはヘッド付きブラウザを制御できるため、ウェブスクレイピング、自動テスト、ボット開発に最適なツールとなっています。
しかし、Puppeteerはボット検出技術によって容易にブロックされてしまいます。これは、Chrome/Chromiumをヘッドレスモードで使用する場合に特に当てはまります。なぜでしょうか?それは、Puppeteerが制御下のブラウザをヘッドレスインスタンスとして認識させるデフォルトのプロパティやヘッダーを自動的に設定するためです。例えば、navigator.webdriver: true というChrome設定が設定されます。
ボット対策ソリューションはこれを把握しており、これらの設定を分析して、現在のユーザーが人間かボットかを判断します。不審な設定が見つかった場合、そのユーザーをボットとしてマークします。
例えば、このヘッドレスモードのボット検出テストを考えてみましょう。ブラウザでテストページを開くと、次のような画面が表示されます:

では、Puppeteerのvanilla版を使用してそのサイトにアクセスし、テスト結果を抽出してみましょう:
import puppeteer from "puppeteer"
(async () => {
// ブラウザをセットアップして起動する
const browser = await puppeteer.launch()
// 新しい空白ページを開く
const page = await browser.newPage()
// ページをターゲットページに移動する
await page.goto("https://arh.antoinevastel.com/bots/areyouheadless")
// テスト結果のメッセージを取得
const resultElement = await page.$("#res")
const message = await resultElement.evaluate(e => e.textContent)
// 結果のメッセージを出力
console.log(`テストの結果は "%s" です`, message);
// 現在のブラウザセッションを閉じる
await browser.close()
})()
上記のスクリプトを実行すると、次のように表示されます:
テストの結果は "You are Chrome headless" です
これは、ページが自動リクエストをヘッドレスブラウザからのものと検知できたため、テストが失敗したことを意味します。
デフォルトでは、Puppeteerは機能に制限のあるツールです。ボット検出を回避するには、手動で調整し、デフォルトの設定を上書きする必要があります。Puppeteer Extraを使えば、そのような手間は一切不要です!
Puppeteer Extra: Puppeteerの拡張可能なバージョン
Puppeteer Extraは、Puppeteerを基盤として構築された軽量なラッパーであり、プラグインサポートによって機能を拡張します。つまり、puppeteer-extra はpuppeteerのドロップイン置換となります。人気のブラウザ自動化ライブラリと同様に動作するだけでなく、プラグインを登録するためのuse()メソッドを提供します。
各プラグインは、Puppeteerに追加の機能を追加します。利用可能な最も有用なプラグインには、次のようなものがあります:
puppeteer-extra-plugin-stealth: ボット検出技術によるヘッドレスブラウザインスタンスの検出を困難にする。puppeteer-extra-plugin-recaptcha:reCAPTCHAやhCaptchaを自動的に解決します。puppeteer-extra-plugin-adblocker: 広告やトラッカーを削除し、その結果として帯域幅と読み込み時間を削減します。puppeteer-extra-plugin-devtools: DevTools への安全なトンネルを作成し、どこからでもブラウザのデバッグを可能にします。puppeteer-extra-plugin-repl: 対話型のREPL(Read-Eval-Print-Loop)インターフェースにより、デバッグ作業を楽しくします。puppeteer-extra-plugin-block-resources: 画像、メディア、CSS、JSファイルなどのページリソースを動的にブロックします。puppeteer-extra-plugin-anonymize-ua: ページ遷移時に User-Agent ヘッダーを匿名化します。これがなぜ重要なのかについては、ウェブスクレイピングのための User-Agent に関するガイドをご覧ください。puppeteer-extra-plugin-user-preferences: カスタム Chrome/Chromium ユーザー設定を設定します。
それでは、Puppeteer Stealthプラグインについてさらに詳しく見ていきましょう。
Puppeteer Extra Stealth プラグインとは何か、そしてその機能
puppeteer-extra-plugin-stealth は、ボット検出を回避するための一連の設定を含む、Puppeteer Extra 用のプラグインです。 具体的には、Puppeteer Stealthは、Puppeteerがボットであることを露呈させるリークやプロパティを上書きする、組み込みの回避モジュールに依存しています。例えば、User-Agentヘッダーから「HeadlessChrome」を削除し、Puppeteerがデフォルトで設定するnavigator.webdriverプロパティを削除します。
Puppeteer Extra Stealth プラグインの目的は、Puppeteer 経由で制御されるヘッドレス Chromium インスタンスが、sannysoft.com 上のすべてのボット検出テストを通過できるようにすることです。本稿執筆時点では、その目的は達成されています。 同時に、公式ドキュメントにも記載されている通り、ヘッドレスChromiumを検出する方法は依然として存在します。つまり、すべてのボット検出メカニズムを回避することは不可能ですが、このプロジェクトの目的は、そのプロセスを可能な限り困難にすることにあります。
ウェブスクレイピング中にボット検出を回避するためにPuppeteer Stealthを使用する方法
では、ブロックされないようにPuppeteerスクラッピングスクリプトにPuppeteer Stealthを統合する方法を見ていきましょう。
以下の手順に従ってください!
ステップ1:Puppeteer ExtraとStealthプラグインをインストールする
以下のコマンドを実行して、Puppeteer ExtraとPuppeteer Stealthプラグインをプロジェクトの依存関係に追加します:
npm install puppeteer-extra puppeteer-extra-plugin-stealth
完了です!これで、Puppeteerの自動化スクリプトにStealthプラグインを統合するための前提条件が整いました。
ステップ 2: Puppeteer Extra の設定と Stealth プラグインの登録
まず、puppeteerのインポート文を次の記述に置き換えてください:
import puppeteer from "puppeteer-extra"
つまり、「puppeteer」ではなく「 puppeteer-extra」からpuppeteerオブジェクトをインポートするようにしてください。
次に、puppeteer-extra-plugin-stealth からStealthPluginをインポートします:
import StealthPlugin from "puppeteer-extra-plugin-stealth"
CommonJS を使用している場合は、次のように記述してください:
const puppeteer = require("puppeteer-extra")
const StealthPlugin = require("puppeteer-extra-plugin-stealth")
次に、use()メソッドを使用して Stealth プラグインをpuppeteerオブジェクトに登録します:
puppeteer.use(StealthPlugin())
素晴らしい!これで、プラグインがサポートするデフォルトの回避機能を Puppeteer に追加できました。
なお、StealthPlugin()コンストラクタは、有効にする回避手法に対応する文字列のセットを含むオプションのオブジェクトを受け取ります:
// 特定の回避テクニックのみを有効にする
puppeteer.use(StealthPlugin({
enabledEvasions: new Set(["chrome.app", "chrome.csi", "defaultArgs", "navigator.plugins"])
}))
それ以外の場合は、以下のロジックを使用して、Stealthプラグインから特定の回避戦略を動的に削除します:
const stealthPlugin = StealthPlugin()
puppeteer.use(stealthPlugin)
// ...
// 「user-agent-override」回避手法を削除
pluginStealth.enabledEvasions.delete("user-agent-override")
ステップ3:すべてを統合する
記事の冒頭で紹介したスクリプトに、Puppeteer ExtraとそのStealthプラグインを組み込みます:
import puppeteer from "puppeteer-extra"
import StealthPlugin from "puppeteer-extra-plugin-stealth"
(async () => {
// Stealthプラグインの設定
puppeteer.use(StealthPlugin())
// ブラウザの設定と起動
const browser = await puppeteer.launch()
// 新しい空白ページを開く
const page = await browser.newPage()
// ページをターゲットページに移動する
await page.goto("https://arh.antoinevastel.com/bots/areyouheadless")
// テスト結果のメッセージを取得
const resultElement = await page.$("#res")
const message = await resultElement.evaluate(e => e.textContent)
// 結果のメッセージを出力
console.log(`テストの結果は "%s" です`, message);
// 現在のブラウザセッションを終了
await browser.close()
})()
このスニペットを実行すると、次のように表示されます:
テストの結果は "You are not Chrome headless" です
これで完了です!ボット検出機能を備えた選択したページは、もはやあなたのPuppeteer自動スクリプトをボットとして識別できなくなりました。
おめでとうございます!これであなたはPuppeteerステルス忍者となり、もはやどのボット検出技術もあなたを怖がらせることはありません。
まとめ
この記事では、なぜボット検出がPuppeteerにとって課題なのか、そしてその対処法について理解できたはずです。Puppeteer Extraのおかげで、プラグインを使ってPuppeteerの機能を拡張できます。特に、Stealthプラグインはボット検出を回避するための強力な味方であり、ここではその使い方を学びました。
Puppeteer Extraがどれほど洗練されていても、Cloudflareのような高度なボット対策技術は、依然としてスクリプトを検知してブロックすることが可能です。別のブラウザ自動化パッケージを選択することもできますが、検知の原因はライブラリではなくブラウザそのものです。解決策は、あらゆるブラウザ自動化ライブラリと統合可能な、ボット対策回避機能を備えたスケーラブルなブラウザです。そのようなブラウザは存在し、その名は「スクレイピングブラウザ」です!
Bright Dataのスクレイピングブラウザは、Puppeteer、Playwright、Seleniumなどに対応した、拡張性の高いクラウドブラウザです。リクエストごとに出口IPを自動的にローテーションし、ブラウザフィンガープリント対策、CAPTCHA解決、自動リトライを自動的に処理します。これは、プロキシベースのアンロック機能によって実現されています。
Bright Dataのプロキシは、フォーチュン500企業や2万社以上の顧客に利用されています。この信頼性の高い世界規模のプロキシネットワークには、以下のものが含まれます:
- データセンター・プロキシ– 77万件以上のデータセンターIP。
- レジデンシャルプロキシ– 195カ国以上で7,200万以上のレジデンシャルIP。
- ISPプロキシ– 70万以上のISP IPアドレス。
- モバイルプロキシ– 700万以上のモバイルIPアドレス。