ウェブスクレイピングにpuppeteer-humanizeを使う:2025ガイド

なぜpuppeteer-humanizeが人間の行動を模倣してウェブスクレイピングを強化し、ユーザー行動分析を回避するのか、その理由を探ってみましょう。
4 分読
Puppeteer humanize web scraping

この記事であなたは学ぶだろう:

  • ユーザー行動分析に対して、バニラPuppeteerでは不十分な理由。
  • パペッティア・ヒューマナイズとは何か?
  • ステップバイステップのチュートリアルセクションでウェブスクレイピングのためにそれを使用する方法。
  • ウェブデータをスクレイピングするこのアプローチに残された課題。

さあ、飛び込もう!

ユーザー行動分析:標準的なPuppeteerでは不十分な理由

ユーザー行動分析(UBA)とは、ユーザーがウェブページをどのように操作しているかについてのデータを収集し、分析するプロセスである。ウェブスクレイピングでは、その主な目的は、ボットを識別するために異常または疑わしい行動を発見することです。

この洗練された対ボット技術が人気を集めている。というのも、最新のAIを搭載したボットは、より人間に近くなるよう進化し続けているからだ。そのため、従来のボット検知手法は、もはやボットに対して有効でない可能性がある。

UBAに対抗するため、自動化ライブラリの中には、人間の行動をよりリアルに模倣しようとするものがある。例えば、ヒューリスティックや機械学習を利用してマウスの動きをシミュレートしている。しかし、ほとんどの場合、タイピングはまだロボットのように見える傾向があり、これは問題である。

ここで、Puppeteerスクリプトがフォームに入力する必要があるとします。type()関数を使ってキー入力の間にわずかな遅延を加えたとしても、そのインタラクションは自然には見えないだろう。

Quotes to Scrapeのログインフォームを例にとってみよう:

import puppeteer from "puppeteer";

(async () => {
  // set up a new browser instance in headful mode
  const browser = await puppeteer.launch({
    headless: false, // set to false so you can watch the interaction
    defaultViewport: null,
  });
  const page = await browser.newPage();

  // connect to the target page
  await page.goto("https://quotes.toscrape.com/login");

  // simulate typing with a delay of 200ms between each character
  await page.type("input[name=\"username\"]", "username", { delay: 200 });
  await page.type("input[name=\"password\"]", "password", { delay: 200 });

  // ...

  // close the browser and release its resources
  await browser.close();
})();

このようなやりとりになる:

ボットのようなインタラクション

上記のアプローチは、単に入力フィールドの値を直接設定するよりも現実的ではあるが、それでも人間には見えない。問題は、タイピングがスムーズで一貫性があり、ミスがないように見えることだ。自問してみてほしい。どんな実際のユーザーが、迷いもタイプミスもなく、まったく同じ間隔ですべての文字をタイプしているだろうか?

ご想像の通り、高度なUBAシステムはこのようなスクリプトを簡単に見破ることができる。そこで、puppeteer-humanizeのようなツールが活躍する!

パペッティア・ヒューマナイズとは

puppeteer-humanizeはNode.jsのライブラリで、Puppeteerのオートメーション、特にテキスト入力フィールドとのインタラクションをより人間らしくします。これは、ユーザーの行動を分析する一般的なボット検出方法を回避するのに役立ちます。

そのために、puppeteer-humanizeは、通常のパペッティアとのやりとりにリアルな不完全さを注入する:

  1. 誤植のシミュレーション
  2. バックスペースキーを使ってミスを修正する。
  3. 削除したテキストをランダムな遅延で再入力する。
  4. キーストローク間にランダムな遅延を導入し、タイピング速度を変化させる。

これにより、自動タイピングがより自然で、機械的でないように見える。しかし、このライブラリはタイピング動作とフォーム入力を人間的にすることだけに焦点を当てていることに注意する必要がある。つまり、包括的なアンチボット・バイパス・ソリューションではない。

また、最後のコミットは2021年であり、GANベースのマウス動作シミュレーションのような高度な機能はまだサポートされていないことに留意してほしい。したがって、その範囲はタイピング動作のみに限定されたままだ。

ウェブスクレイピングのためのpuppeteer-humanizeの使い方

以下の手順に従って、puppeteer-humanizeを使用して、より人間に近いスクレイピングボットを構築する方法を学んでください。これにより、特にスクリプトがフォームにデータを入力する必要がある場合に、UBAシステムによって検出される可能性が低くなります。

ターゲットはQuotes to Scrapeのログインフォームである:

この例は単に、現実的なフォーム入力をシミュレートする方法を示すためのものです。実際のスクレイピングシナリオでは、明確な許可がない限り、ログインフォームの背後にあるコンテンツをスクレイピングすることは避けてください

では、puppeteer-humanizeを使ってウェブ・スクレイピングをする方法を見てみよう!

ステップ1:プロジェクトのセットアップ

Node.jsプロジェクトがまだセットアップされていない場合は、npm initでプロジェクトフォルダーに作成できます:

npm init -y

上記のコマンドを実行すると、プロジェクト・ディレクトリにpackage.jsonファイルが生成されます。プロジェクトフォルダ内にscript.jsファイルを作成し、ここにJavaScriptスクレイピングロジックを配置します:

your-project-folder/
├── package.json
└── script.js

次に、お気に入りのJavaScript IDEでそのフォルダを開きます。Visual Studio Codeなら完璧です。

IDEでpackage.jsonファイルを修正し、以下の行を追加する:

"type": "module"

これは、プロジェクトがESM(ECMAScript Modules)を使用するように設定するもので、最近のNode.jsプロジェクトでは、標準のCommonJS形式よりも一般的に推奨されています。

素晴らしい!これでpuppeteer-humanizeを利用して、スクレイピングスクリプトでリアルなインタラクションをシミュレートする準備が整いました。

ステップ2:puppeteer-humanizeをインストールして使い始める

puppeteer-humanizeは元々Puppeteer Extraのプラグインでしたが、現在はそうではありません。そのため、使用するにはインストールが必要です:

  • forad/puppeteer-humanize:人間のような振る舞いをシミュレートするライブラリ。
  • puppeteer:ブラウザ自動化ライブラリの中核。

以下のコマンドで両方をインストールする:

npm install @forad/puppeteer-humanize puppeteer

次に、script.jsファイルを開き、次のような基本的なPuppeteerスクリプトを初期化します:

import puppeteer from "puppeteer";

(async () => {
  // set up a new browser instance in headful mode
  const browser = await puppeteer.launch({
    headless: false, // set to false so you can watch the interaction
    defaultViewport: null,
  });
  const page = await browser.newPage();

  // ...

  // close the browser and release its resources
  await browser.close();
})();

素晴らしい!これで、人間のように見えるスクレイピング・インタラクションを実装し始めることができる。

ステップ#3: ターゲットページへの接続と入力要素の選択

Puppeteerを使って目的のページに移動する:

await page.goto("https://quotes.toscrape.com/login");

次に、同じページをブラウザで開き、ログインフォームを右クリックして「Inspect」を選択し、フォーム要素を調べます:

このフォームには

  • input[name="username"]で選択できるユーザー名入力フィールド。
  • input[name="password"]で選択できるパスワード入力フィールド。

スクリプト内でこれらの入力要素を選択するには、Puppeteerの$()メソッドを使用します:

const usernameInput = await page.$("input[name=\"username\"]");
const passwordInput = await page.$("input[name=\"password\"]");

⚠️重要puppeteer-humanizeロケータと連動しません。つまり、$()$$() を使って 要素のハンドルを直接取得しなければなりません。

もし両方の入力がページ上に見つかったら、実際のユーザーと同じように入力と対話する準備をする:

if (usernameInput && passwordInput) {
  // interaction...
}

素晴らしい!次は、実際のユーザーであるかのように入力する番だ。

ステップ4:タイピング機能の設定

まず、puppeteer-humanizeから typeInto関数をインポートする:

import { typeInto } from "@forad/puppeteer-humanize";

そして、それを使って以下のように、人間のようなフォーム入力インタラクションを設定する:

const typingConfig = {
  mistakes: {
    chance: 10, // 10% chance of introducing a typo that gets corrected
    delay: {
      min: 100, // minimum delay before correcting a mistake (in ms)
      max: 500, // maximum delay before correcting a mistake (in ms)
    },
  },
  delays: {
    all: {
      chance: 100, // 100% chance to add delay between each keystroke
      min: 100, // minimum delay between characters (in ms)
      max: 200, // maximum delay between characters (in ms)
    },
  },
};

// strings to fill into the input elements
const username = "username";
const password = "password";

// apply the human-like typing logic to both inputs
await typeInto(usernameInput, username, typingConfig);
await typeInto(passwordInput, password, typingConfig);

上記のタイピング設定:

  • 時折、誤字脱字を紹介し、リアルな訂正を加える。
  • 各キーストロークの間にランダムな遅延を追加し、自然なタイピング速度の変化を模倣します。

このような行動は、自動化をより人間的に見せ、UBAテクノロジーによる検知の可能性を制限する。

素晴らしい!これで、あなたのPuppeteerスクリプトは、より本物の人間のように動作するはずだ。

ステップ #5: フォームに記入し、ウェブスクレイピングの準備をする

以下のコードを使用してフォームに入力できます:

const submitButton = page.locator("input[type=\"submit\"]");
await submitButton.click();

Quotes to Scrapeのログインフォームは単なるテストページであることに留意してください。詳しくは、ユーザー名と パスワードを入力してアクセスして下さい。フォームを送信すると、スクレイピングしたいデータを含むページにリダイレクトされます:

ログインフォームの送信

その時点で、通常のPuppeteer APIを使って、実際のスクレイピングロジックを実装することができます:

// wait for the page to load
await page.waitForNavigation();

// scraping logic...

さて、この記事の焦点はパペッティア・ヒューマナイズだ。そのため、ここではスクレイピングの部分については取り上げません。
Quotes to ScrapeからデータをスクレイピングしてCSVにエクスポートすることに興味がある方は、Puppeteerを使ったウェブスクレイピングの完全なチュートリアルをお読みください。

ステップ6:すべてをまとめる

これでscript.jsは以下のようになる:

import puppeteer from "puppeteer";
import { typeInto } from "@forad/puppeteer-humanize";

(async () => {
  // set up a new browser instance in headful mode
  const browser = await puppeteer.launch({
    headless: false, // set to false so you can watch the interaction
    defaultViewport: null,
  });
  const page = await browser.newPage();

  // visit the target page
  await page.goto("https://quotes.toscrape.com/login");

  // select the login form inputs
  const usernameInput = await page.$("input[name=\"username\"]");
  const passwordInput = await page.$("input[name=\"password\"]");

  // if they are not both null, interact with them
  if (usernameInput && passwordInput) {
    // configure the typing behavior
    const typingConfig = {
      mistakes: {
        chance: 10, // 10% chance of introducing a typo that gets corrected
        delay: {
          min: 100, // minimum delay before correcting a mistake (in ms)
          max: 500, // maximum delay before correcting a mistake (in ms)
        },
      },
      delays: {
        all: {
          chance: 100, // 100% chance to add delay between each keystroke
          min: 100, // minimum delay between characters (in ms)
          max: 200, // maximum delay between characters (in ms)
        },
      },
    };

    // test strings to fill into the input elements
    const username = "username";
    const password = "password";

    // apply the human-like typing logic to both inputs
    await typeInto(usernameInput, username, typingConfig);
    await typeInto(passwordInput, password, typingConfig);

    // submit the form
    const submitButton = page.locator("input[type=\"submit\"]");
    await submitButton.click();

    // wait for the page to load
    await page.waitForNavigation();

    // scraping logic...
  }

  // close the browser and release its resources
  await browser.close();
})();

上記のpuppeteer-humanizeスクリプトを起動する:

node script.js

結果はこうなる:

タイピングのやり取りがいかに自然であるかに注目してほしい。

ご覧のように、Puppeteerボットは、より自然な方法でログインフォームを操作します。現実的なスピードで入力し、時折タイプミスをし、それを修正します。これがpuppeteerの人間化する力です!

ウェブスクレイピングへのこのアプローチの課題

puppeteer-humanizeは間違いなく、ユーザーの行動を分析するテクノロジーに検知される可能性を減らす大きな味方だ。それでも、アンチスクレイピング、アンチスクレイピング、アンチボットの技術は、ユーザー行動だけにとどまらない!

まず、Puppeteerがプログラムでブラウザを制御するには、ブラウザをインスツルメンテーションしなければならないことを覚えておいてほしい。そのため、ブラウザが自動化されていることがわかるような微妙な変化や兆候が生じます。このような情報漏えいを減らすために、Puppeteer Stealthの使用も検討すべきです。

puppeteer-humanizeとPuppeteer Stealthの両方を導入していても、やり取り中にCAPTCHAに遭遇することがあります。そのような場合は、Playwright を使った CAPTCHA バイパスの記事をご覧ください。

これらのツールやガイドは、より耐性のあるスクレイピングのセットアップを構築するのに役立ちますが、それらに依存する回避策の多くは、永遠に続くわけではありません。高度に洗練されたボット対策ソリューションを使用しているサイトを扱っている場合、成功のチャンスは大幅に減少します。さらに、複数のプラグインを追加すると、メモリとディスクの使用量が重くなり、セットアップの拡張が難しくなります。

その時点で、問題はPuppeteerそのものではなく、Puppeteerが制御するブラウザの限界にある。真のブレークスルーは、Puppeteerをウェブスクレイピング専用に構築されたヘッドフルなクラウドベースのブラウザと統合することで得られる。このソリューションには、回転プロキシ、高度なCAPTCHA解決、リアルなブラウザフィンガープリントなどのビルトインサポートが含まれています。これこそがBright DataのBrowser APIなのです!

結論

このチュートリアルでは、バニラPuppeteerがユーザー行動分析に対して不十分である理由と、puppeteer-humanizeでそれに対処する方法を学びました。特に、ステップバイステップのチュートリアルを通して、このアプローチをウェブスクレイピングのワークフローに統合する方法を学びました。

この方法は単純なアンチボットシステムを回避するのに役立つが、高い成功率を保証するものではない。特に、CAPTCHA、IPバン、または最新のAIを搭載したアンチボット技術に依存しているサイトをスクレイピングする場合はそうである。その上、このセットアップを拡張するのは複雑な場合がある。

スクレイピングスクリプト、あるいはAIエージェントを実際のユーザーのように動作させることが目的であれば、このユースケースのために作られたブラウザの使用を検討する必要があります:Bright Dataのエージェントブラウザです。

無料のBright Dataアカウントを作成して、当社のAI対応スクレイピングインフラストラクチャ全体にアクセスしてください!