このPuppeteerユーザーエージェントガイドでは、以下の内容を確認できます:
- ウェブスクレイピング
Puppeteerにおけるデフォルトユーザーエージェントの表示例- デフォルトのChromeヘッドレスユーザーエージェントを上書きする方法
Puppeteerでのユーザーエージェントローテーションの実装方法Puppeteer Extraを使用したユーザーエージェントの匿名化方法
さあ、始めましょう!
カスタムユーザーエージェントを設定する必要性
User-Agentヘッダーは、クライアントがHTTPリクエストでサーバーに自身を識別させるために設定する文字列です。通常、リクエストの発信元となるマシンやアプリケーションに関する情報が含まれます。このヘッダーは、ウェブブラウザ、HTTPクライアント、またはウェブリクエストを実行するあらゆるソフトウェアによって設定されます。
以下は、ChromeがWebページをリクエストする際に設定するユーザーエージェント文字列の例です:
Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36
上記のユーザーエージェント文字列は以下の構成要素から成り立っています:
Mozilla/5.0: 当初はMozillaブラウザとの互換性を示すために使用されていましたが、現在ではより広範な互換性のために含まれています。Windows NT 10.0; Win64; x64: オペレーティングシステム(Windows NT 10.0)、プラットフォーム(Win64)、システムアーキテクチャ(x64)を示します。AppleWebKit/537.36: Chromeが使用するブラウザエンジンを指します。(KHTML, like Gecko): KHTML および Gecko レイアウトエンジンとの互換性を示します。Chrome/127.0.0.0: ブラウザ名とバージョンを指定します。Safari/537.36: Safari との互換性を示します。
基本的に、ユーザーエージェント文字列は、リクエストが有名なブラウザから来ているのか、それとも別の種類のソフトウェアから来ているのかを明らかにすることができます。
ほとんどのウェブスクレイピングボットや自動化スクリプトが犯す誤りは、デフォルトまたは非ブラウザのユーザーエージェントを使用することです。これらの値は、ウェブページを保護するために設計されたボット対策によって容易に検出されます。User-Agentヘッダーを分析することで、サーバーはリクエストが自動化されたボットからのものである可能性を判断できます。
詳細については、ウェブスクレイピング用ユーザーエージェントのガイドをご覧ください。
Puppeteerのデフォルトユーザーエージェントとは?
Puppeteerは実世界のウェブブラウザの特殊バージョンを制御することでブラウザタスクを自動化します。デフォルトではFirefoxもサポートしていますが、特定のバージョンのChromeを実行します。したがって、Puppeteerのデフォルトユーザーエージェントは制御対象のChromeバージョンと一致すると推測されるかもしれません。しかし、実際にはそうではありません…
その理由は、Puppeteerがデフォルトでヘッドレスモードでブラウザを起動するためです。ヘッドレスモードで動作するブラウザは、一般的に特徴的なユーザーエージェントを設定します。現在のバージョンでは、Puppeteerのデフォルトユーザーエージェントは次のようになります:
Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/127.0.0.0 Safari/537.3
注目すべきは「HeadlessChrome」という文字列で、Chromeがヘッドレスモードで実行されていることを示しています。当然ながら、上記の文字列は最新版のヘッドレスChromeのユーザーエージェントと完全に一致します。
上記の文字列が実際にPuppeteerのデフォルトユーザーエージェントであることを確認するには、スクリプトを設定し、httpbin.io/user-agentページにアクセスします。このAPIエンドポイントはリクエストのUser-Agentヘッダーを返すため、あらゆるブラウザやHTTPクライアントが使用するユーザーエージェントを特定するのに役立ちます。
Puppeteerスクリプトを作成し、目的のページにアクセスしてAPIレスポンスをボディから取得し、出力します:
import puppeteer from "puppeteer";
(async () => {
// ブラウザを起動し新規ページを開く
const browser = await puppeteer.launch();
const page = await browser.newPage();
// 対象ページに接続
await page.goto("https://httpbin.io/user-agent");
// APIレスポンスを含む本文テキストを抽出
// それを出力
const bodyText = await page.evaluate(() => {
return document.body.innerText;
});
console.log(bodyText);
// ブラウザを閉じてリソースを解放
await browser.close();
})();
PuppeteerAPIの詳細については、 Puppeteerを使用したウェブスクレイピングのガイドをご覧ください。
上記のNode.jsコードを実行すると、以下の文字列が取得されます:
{
"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/127.0.0.0 Safari/537.36"
}
Puppeteerが設定するユーザーエージェントは、先に示した文字列と一致していることに注意してください。
問題はHeadlessChrome識別子にあり、これが反ボットシステムに警告を発する可能性があります。これらのシステムは、異常なユーザーエージェント文字列など、ボット活動を示す可能性のあるパターンを分析します。不審なリクエストはフラグが立てられ、それに応じてブロックされます。これが、Puppeteerのデフォルトユーザーエージェント文字列を変更することが非常に重要である理由です!
Puppeteerのユーザーエージェント変更方法
ユーザーエージェントの変更は非常に一般的で有用な操作であるため、Puppeteerは専用のメソッドを提供しています。具体的には、PageクラスがsetUserAgent()メソッドを公開しています。これにより、そのブラウザタブでWebページにアクセスする際、Puppeteerが 設定するUser-Agentを変更できます。
setUserAgent()を使用してPuppeteerのユーザーエージェントを変更するには以下のようにします:
await page.setUserAgent("<your_user_agent>");
ページオブジェクトに対してgoto()メソッドを呼び出して行われるすべての HTTP GET リクエストは、カスタムUser-Agentヘッダーを持つようになります。この変更は特定のページオブジェクトにのみ適用されることに注意してください。新しいページを開いて操作する場合、Puppeteer は前述のデフォルトのユーザーエージェントを使用します。
完全な例については、以下のスニペットを参照してください:
import puppeteer from "puppeteer";
(async () => {
// ブラウザを起動し新規ページを開く
const browser = await puppeteer.launch();
const page = await browser.newPage();
// カスタムユーザーエージェントを設定
await page.setUserAgent("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36");
// 対象ページに接続
await page.goto("https://httpbin.io/user-agent");
// APIレスポンスで本文テキストを抽出
// 結果を出力
const bodyText = await page.evaluate(() => {
return document.body.innerText;
});
console.log(bodyText);
// ブラウザを閉じてリソースを解放
await browser.close();
})();
上記スクリプトを実行すると、今回は以下の結果が得られます:
{
"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36"
}
素晴らしい!ページから抽出されたユーザーエージェント文字列が、コードで設定したユーザーエージェントと一致しています。これでPuppeteerのユーザーエージェント変更操作の実行方法がわかりました。
Puppeteerでのユーザーエージェントローテーションの実装
ヘッドレスブラウザのUser-Agentヘッダーを非ヘッドレスブラウザのものに置き換えるだけでは、ボット対策システムを回避できない場合があります。問題は、ブラウザ自動化スクリプトが非人間的な行動を示すパターンを示すことです。特に、同じIPアドレスから同じヘッダーで大量のリクエストを送信する場合に顕著です。
Puppeteerでボット検出リスクを最小化するには、リクエストを可能な限り多様化させる必要があります。効果的な手法として、リクエストごとに異なるユーザーエージェントを設定する方法があります。この戦略はユーザーエージェントローテーションと呼ばれ、ボットとしてフラグ付けされる可能性を低減します。
次のチュートリアルセクションでは、Puppeteerでユーザーエージェントローテーションを実装する方法を学びます!
ステップ #1: ランダムなユーザーエージェントを生成する
ランダムなユーザーエージェントを取得する主な方法は2つあります。1つ目は、有効なユーザーエージェントのリストを取得し、そのリストからランダムに1つを選択する方法です(Node.jsユーザーエージェントガイドを参照)。
二つ目の方法は、サードパーティのユーザーエージェント生成ライブラリを使用することです。JavaScriptで最も人気のあるのはuser-agentsパッケージで、有効なユーザーエージェントを生成できます。本ガイドではこの方法を採用します!
プロジェクトの依存関係にuser-agentsライブラリを追加するには、以下のnpmコマンドを実行します:
npm install user-agents
user-agentsは毎日更新されるため、常に最新のユーザーエージェントが含まれていることに注意してください。
ライブラリインストール後、PuppeteerスクリプトにUserAgentオブジェクトをインポートします:
import UserAgent from "user-agents";
以下のコードでランダムなユーザーエージェント文字列を生成できます:
const userAgent = new UserAgent().random().toString();
特定のデバイスやオペレーティングシステムなど、より高度なユーザーエージェントの取得方法については、公式ドキュメントを参照してください。
ステップ #2: ランダムなユーザーエージェントを設定する
setUserAgent()メソッドを呼び出して、ランダムなユーザーエージェント文字列をPuppeteerに渡します:
const userAgent = new UserAgent().random().toString();
await page.setUserAgent(userAgent);
ページオブジェクト経由で実行されるすべてのリクエストは、ランダムに生成されたカスタムユーザーエージェントを使用するようになります。
ステップ #3: 対象ページへのアクセス
制御されたヘッドレスブラウザでターゲットWebページを訪問するため、pageオブジェクトの goto()メソッドを呼び出します:
await page.goto("https://httpbin.io/user-agent");
ステップ #4: 全てを統合する
以下が最終的なPuppeteerユーザーエージェントローテーションスクリプトです:
import puppeteer from "puppeteer";
import UserAgent from "user-agents";
(async () => {
// ブラウザを起動し新規ページを開く
const browser = await puppeteer.launch();
const page = await browser.newPage();
// ランダムなユーザーエージェントを生成
const userAgent = new UserAgent().random().toString();
// ランダムなユーザーエージェントを設定
await page.setUserAgent(userAgent);
// ターゲットページに接続
await page.goto("https://httpbin.io/user-agent");
// APIレスポンスの本文テキストを抽出
// 表示
const bodyText = await page.evaluate(() => {
return document.body.innerText;
});
console.log(bodyText);
// ブラウザを閉じてリソースを解放
await browser.close();
})();
スクリプトを数回実行すると、異なるユーザーエージェントが表示されるはずです。
さあ、これで完了です!Puppeteerのユーザーエージェントローテーションロジックは見事に機能します。
puppeteer-extra-plugin-anonymize-uaを使用した Puppeteer のカスタムユーザーエージェント設定
上記のPuppeteerユーザーエージェント設定手法は有効ですが、重大な欠点があります。userAgent()メソッドは特定のページセッションでのみユーザーエージェントを変更し、すべてのブラウザタブに適用されるわけではありません。
Puppeteerがデフォルトのユーザーエージェントを絶対に使用しないようにするには、Puppeteer Extra のpuppeteer-extra-plugin-anonymize-uaプラグインを利用できます。このプロジェクトに不慣れな方のために説明すると、Puppeteer Extraはコミュニティ定義のプラグインサポートを追加することでPuppeteerを拡張します。詳細はPuppeteer Extra Stealthプラグインのガイドでご確認ください。
puppeteer-extra-plugin-anonymize-uaプラグインは、Puppeteerが設定するユーザーエージェントを匿名化します。puppeteer-extraと必要なプラグインをインストールするには、以下のコマンドを実行してください:
npm install puppeteer-extra puppeteer-extra-plugin-anonymize-ua
次に、puppeteer-extraからpuppeteer を、puppeteer-extra-plugin-anonymize-ua からAnonymizeUAPluginをインポートします:
import puppeteer from "puppeteer-extra";
import AnonymizeUAPlugin from "puppeteer-extra-plugin-anonymize-ua";
puppeteer-extra-plugin-anonymize-uaを設定し、ランダムなユーザーエージェントを生成して、Puppeteer Extra のuse()メソッドでプラグインとして登録します:
puppeteer.use(
AnonymizeUAPlugin({
customFn: () => new UserAgent().random().toString(),
})
);
次に、2つの別々のページオブジェクトを使用して、2つの異なるタブでページにアクセスしてみてください:
import puppeteer from "puppeteer-extra";
import AnonymizeUAPlugin from "puppeteer-extra-plugin-anonymize-ua";
import UserAgent from "user-agents";
(async () => {
// puppeteer-extra-plugin-anonymize-ua プラグインの設定と登録
puppeteer.use(
AnonymizeUAPlugin({
customFn: () => new UserAgent().random().toString(),
})
);
// ブラウザを起動し新規ページを開く
const browser = await puppeteer.launch();
// 新規ページを開く
const page1 = await browser.newPage();
// ターゲットページに接続
await page1.goto("https://httpbin.io/user-agent");
// APIレスポンスの本文テキストを抽出
// かつ出力
const bodyText1 = await page1.evaluate(() => {
return document.body.innerText;
});
console.log(bodyText1);
// 新しいページを開く
const page2 = await browser.newPage();
// ターゲットページに接続
await page2.goto("https://httpbin.io/user-agent");
// APIレスポンスで本文テキストを抽出
// 結果を出力
const bodyText2 = await page2.evaluate(() => {
return document.body.innerText;
});
console.log(bodyText2);
// ブラウザを閉じてリソースを解放
await browser.close();
})();
結果として、以下のように2つの異なるユーザーエージェントが表示されます:
{
"user-agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 17_5_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.5 Mobile/15E148 Safari/604.1"
}
{
"user-agent": "Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Mobile Safari/537.36"
}
2つのユーザーエージェントは異なり、どちらもPuppeteerのデフォルトユーザーエージェントではありません。これはpuppeteer-extra-plugin-anonymize-uaが customFn関数で指定されたランダムなユーザーエージェントで各ページオブジェクトをカスタマイズするためです。これにより、Puppeteerはデフォルトのユーザーエージェントを絶対に公開しません!
結論
本記事では、User-Agentヘッダー設定の重要性とPuppeteerのデフォルトユーザーエージェントを確認しました。その値を上書きし、ユーザーエージェントローテーションを実装して基本的なスクレイピング対策システムを回避する方法を学びました。ただし、より高度なシステムでは自動リクエストを検知・ブロックされる可能性があります。IP禁止を防ぐ にはPuppeteerでプロキシを設定できますが、それでも十分でない場合があります!
より効果的な解決策として、次世代ブラウザ「スクレイピングブラウザ」をお試しください。Puppeteerやその他のブラウザ自動化ツールと連携可能です。スクレイピングブラウザは、ブラウザフィンガープリンティングを回避しつつ、アンチボット技術を容易に迂回します。内部ではユーザーエージェントローテーション、IPローテーション、CAPTCHAの解決などの機能を活用しています。ブラウザ自動化がこれほど簡単になったことはありません!
今すぐ登録して無料トライアルを開始しましょう。