このPlaywright Stealthチュートリアルの内容:
- ボット検出とは何か、およびそれがPlaywrightにとって課題となる理由。
- Playwright Stealthとは何か。
- ブロックを回避するためにPythonとJavaScriptでPlaywright Stealthを使用する方法。
さっそく始めましょう!
ボット検出はPlaywrightにとって最大の障害
Playwrightは、ブラウザを自動化するためのPythonライブラリの1つで非常に人気があります。詳しく言えば、マイクロソフト社が直接開発および保守しているので信頼でき、広く普及しているのです。APIは高機能かつ直感的で、さまざまなプログラミング言語で通常のブラウザやヘッドレスブラウザを簡単に制御できます。つまり、Playwrightはクロスブラウザやクロスプラットフォームのボット開発、自動テスト、ウェブスクレイピングに最適なツールです。
Playwrightは、ブラウザを自動化するためのPythonライブラリの1つで非常に人気があります。詳しく言えば、マイクロソフト社が直接開発および保守しているので信頼でき、広く普及しているのです。APIは高機能かつ直感的で、さまざまなプログラミング言語で通常のブラウザやヘッドレスブラウザを簡単に制御できます。つまり、Playwrightはクロスブラウザやクロスプラットフォームのボット開発、自動テスト、ウェブスクレイピングに最適なツールです。
このライブラリの主な問題は、特にヘッドレスモードのブラウザが、ボット対策テクノロジーで簡単に検出およびブロックされる可能性があることです。どうしてそうなるのでしょうか?Playwrightが、ヘッドレスブラウザの制御時に特定のプロパティとヘッダーの値を自動的に変更するからです。たとえば、navigator.webdriver
Chrome設定をtrue
に変更します。
ボット検出ソリューションはこれらの設定値に注目して分析し、そのブラウザのユーザーが人間かボットかを判定します。この過程で疑わしい設定が検出されると、当該ユーザーはボットと判定され、直ちにブロックされます。
たとえば、ヘッドレスモードでこのボット検出テストがどのように動作するか見てみましょう。まず普通にブラウザでアクセスすると、ページから次の内容が表示されます。
完璧です。この結果は当然ですね!
では、標準のPlaywrightで同じページにアクセスして、その応答を抽出してみましょう。
import asyncio
from playwright.async_api import async_playwright
async def main():
async with async_playwright() as p:
# launch the browser
browser = await p.chromium.launch()
# open a new page
page = await browser.new_page()
# visit the target page
await page.goto("https://arh.antoinevastel.com/bots/areyouheadless")
# extract the answer contained on the page
answer_element = page.locator("#res")
answer = await answer_element.text_content()
# print the resulting answer
print(f'The result is: "{answer}"')
# close the browser and release its resources
await browser.close()
asyncio.run(main())
Pythonプログラムを実行すると、次のように出力されます。
The result is: "You are Chrome headless"
これは、ボット自動化テストページが、自動スクリプトから実行されたリクエストをヘッドレスブラウザからのものだと判定したからです。
このように、Playwrightはボット検出テクノロジーによって簡単にブロックされ得る、限界のあるツールです。その対策として、デフォルトの設定を手動で変更することも考えられますが、そんなことをしなくても、Playwright Stealthプラグインをインストールすればよいのです!
Playwright Stealthプラグイン:その内容と仕組み
playwright-stealth
は、ボット検出を回避するために、特定の設定値を変更してPlaywrightを拡張するPythonパッケージの1つです。Playwright Stealthはpuppeteer-extra-plugin-stealth
npmパッケージの移植版で、組み込みの回避モジュールを使用して、リークを回避し、自動ブラウザがボットと判定される原因となるプロパティを変更します。たとえば、ヘッドレスモードのChromeでデフォルトで設定される、navigator.webdriver
プロパティおよびUser-Agentヘッダー内の「HeadlessChrome」文字列を削除します。
Stealthプラグインの目的は、自動ヘッドレスブラウザのインスタンスが、sannysoft.comのすべてのボット検出テストを無事に通過できるようにすることです。この記事を書いている時点で、この目的は達成されています。ただし、公式ドキュメントに記載されているように、ヘッドレスブラウザを検出する方法はこれだけではありません。ですから、今日うまくいっても、明日はうまくいかない可能性があります。あらゆるボット検出メカニズムの回避を完全に実現できるわけではありませんが、Playwrightライブラリはボット検出プロセスを可能な限り困難にすることを目指しています。
Playwright Stealthを使用してボット検出を回避する方法
以下の手順でPlaywright Stealthをplaywright
Pythonスクリプトに統合し、ブラウザがウェブページからブロックされないようにしてみましょう。
手順1:Playwright Pythonプロジェクトをセットアップします
注:すでに利用できるPlaywright
Pythonプロジェクトがある場合は、この手順をスキップできます。
まず、マシンにPython 3がインストールされていることを確認します。インストールされていない場合は、インストーラをダウンロードして実行し、インストールウィザードの指示に従います。
次に、以下のコマンドを使用してplaywright-demo
という名前のPythonプロジェクトをセットアップします。
mkdir playwright-demo
cd playwright-demo
これらのコマンドにより、playwright-demo
フォルダーが作成され、ターミナルに入力されます。
Python仮想環境を初期化して、アクティブ化します。
python -m venv env
env/Scripts/activate
次のコマンドを起動してPlaywrightをインストールします。
pip install playwright
これには時間がかかります。しばらくお待ちください。
その後、以下のコマンドで必要なブラウザをインストールします。
playwright install
任意のPython IDEでプロジェクトフォルダーを開き、index.py
ファイルを作成します。次のように入力して初期化してください。
import asyncio
from playwright.async_api import async_playwright
async def main():
async with async_playwright() as p:
browser = await p.chromium.launch()
page = await browser.new_page()
# browser automation logic...
await browser.close()
asyncio.run(main())
上記のスクリプトで、Chromiumのインスタンスがヘッドレスモードで起動し、新しいページが開かれ、最後にブラウザが終了します。基本的なPlaywright Pythonスクリプトはこのようになります。
これをrunで実行します。
python index.py
素晴らしい!これでPlaywrightプロジェクトをStealthプラグインで拡張する準備が整いました。
手順2:Stealthプラグインをインストールして使います
Playwright Stealthプラグインを以下のコマンドでインストールします。
pip install playwright-stealth
作成したindex.py
ファイルを開き、Playwrightスクリプトに以下のimportを追加します。
from playwright_stealth import stealth_async
Sync APIを使用している場合は次のようにします。
from playwright_stealth import stealth_sync
Playwrightに登録するため、インポートされた関数に次のようにpage
オブジェクトを渡します。
await stealth_async(page)
Sync APIを使用している場合は次のようにします。
stealth_async(page)
stealth_async()
関数は、ボット検出を回避するために、いくつかのデフォルト設定値をオーバーライドしてpage
を拡張します。
できました!あとは、目的のページにアクセスしてテストを繰り返すだけです。
手順3:すべてをまとめます
記事の冒頭で示したPlaywrightスクリプトにStealthプラグインを統合します。
import asyncio
from playwright.async_api import async_playwright
from playwright_stealth import stealth_async
async def main():
async with async_playwright() as p:
# launch the browser
browser = await p.chromium.launch()
# open a new page
page = await browser.new_page()
# register the Playwright Stealth plugin
await stealth_async(page)
# visit the target page
await page.goto("https://arh.antoinevastel.com/bots/areyouheadless")
# extract the message contained on the page
message_element = page.locator("#res")
message = await message_element.text_content()
# print the resulting message
print(f'The result is: "{message}"')
# close the browser and release its resources
await browser.close()
asyncio.run(main())
もう一度実行すると、今度は次のように出力されます。
The result is: "You are not Chrome headless"
ほら、このとおり!目的のページにはボット検出機能があるのですが、あなたのPlaywright自動スクリプトをボットと判定できなくなっています。
お疲れ様です!Playwright Stealthの手法をマスターした今、もうボット検出テクノロジーを怖がる必要はありません。
追加:JavaScriptでPlaywright Stealthを使う
JavaScriptでPlaywrightを使っていて、同じ結果を得たい場合は、puppeteer-extra-plugin-stealth
npmパッケージを使用する必要があります。これはPuppeteer ExtraとPlaywright Extraの両方で有効です。これらのプロジェクトについてよく知らない方のために説明すると、これらは基本的に2つのブラウザ自動化ライブラリの拡張バージョンです。具体的には、プラグインを介してそれぞれPuppeteerとPlaywrightに拡張機能が追加されます。
たとえば、次のPlaywright JavaScriptスクリプトがあり、それをStealthプラグインと統合したいとすると、
import { chromium } from "playwright"
(async () => {
// set up the browser and launch it
const browser = await chromium.launch()
// open a new blank page
const page = await browser.newPage()
// navigate the page to the target page
await page.goto("https://arh.antoinevastel.com/bots/areyouheadless")
// extract the message contained on the page
const messageElement = page.locator('#res')
const message = await messageElement.textContent()
// print the resulting message
console.log(`The result is: "${message}"`)
// close the browser and release its resources
await browser.close()
})()
まず、playwright-extra
とpuppeteer-extra-plugin-stealth
をインストールします。
npm install playwright-extra puppeteer-extra-plugin-stealth
次に、playwright
の代わりにplaywright-extra
からchromium
をインポートし、puppeteer-extra-plugin-stealth
からStealthPlugin
をインポートします。
import { chromium } from "playwright-extra"
import StealthPlugin from "puppeteer-extra-plugin-stealth"
次に、以下のようにStealthプラグインを登録します。
chromium.use(StealthPlugin())
すべてをまとめると、次のようになります。
import { chromium } from "playwright-extra"
import StealthPlugin from "puppeteer-extra-plugin-stealth"
(async () => {
// configure the Stealth plugin
chromium.use(StealthPlugin())
// set up the browser and launch it
const browser = await chromium.launch()
// open a new blank page
const page = await browser.newPage()
// navigate the page to the target page
await page.goto("https://arh.antoinevastel.com/bots/areyouheadless")
// extract the message contained on the page
const messageElement = page.locator('#res')
const message = await messageElement.textContent()
// print the resulting message
console.log(`The result is: "${message}"`)
// close the browser and release its resources
await browser.close()
})()
完了です!これで、JavaScriptで記述したPlaywrightにStealthプラグインを統合できました。
まとめ
このガイドでは、ボットの検出がPlaywrightにとって課題となる理由と、その対処方法について説明しました。Playwright Stealth Pythonライブラリを利用すれば、デフォルトのブラウザ設定を拡張してボット検出を回避できます。ここで説明したように、同様のアプローチをJavaScriptにも適用できます。
Playwrightでどれほど工夫してブラウザ自動化スクリプトを記述しても、高度なボット検出システムがそれに制限を設けてくる構図は変わりません。別のブラウザ自動化パッケージの使用を検討することもできますが、検出される根本原因はライブラリではなくブラウザ側にあり、あらゆるブラウザ自動化ライブラリとシームレスに統合できるボット対策回避機能を備えた、拡張性の高いブラウザが究極の回答になります。そのようなブラウザは存在します。それがScraping Browserです。
Bright DataのScraping Browserは、Playwright、Puppeteer、Seleniumと互換性のある、拡張性の高いクラウドベースのブラウザです。Scraping Browserは、リクエストのたびに出口IPを自動的にローテーションし、ブラウザのフィンガープリント、自動再試行、CAPTCHAへの回答を自動で処理できます。これらの機能は、プロキシベースのロック解除機能を基盤として実現されています。
Bright Dataのプロキシはフォーチュン500企業に採用されており、お客様は20,000社を超えます。世界中に広がるBright Dataのプロキシネットワークの一部をご紹介いたします。
- データセンタープロキシ — 77万を超えるデータセンターIP。
- レジデンシャルプロキシ — 195か国を超える国の7,200万以上の住宅用IP。
- ISPプロキシ — 70万を超えるISP IP。
- モバイルプロキシ — 700万を超えるモバイルIP。