PuppeteerでCAPTCHAソルバーを使う

著者:solvethree読了時間:1分

公式 JavaScript SDK で reCAPTCHA v3 Enterprise トークンを取得し、Puppeteer を通じて solution.token をフォームに渡します。SDK はタスクを解決しますが、ブラウザーへの解決結果の適用やブラウザープラグインの提供は行いません。

以下の例は、g-recaptcha-response textarea と送信ボタンを持つ、所有する HTTPS フォームを対象としています。これらはデモのフォーム要件であり、reCAPTCHA で保護されたページに共通するインターフェースではありません。

このページの内容

依存関係と所有するフォームを準備する

  1. 1.

    Puppeteer と SDK をインストールする

    Node.js 22 以降を使用してください。npm で puppeteer と、https://solvethree.com/downloads/solvethree-sdk-0.1.0.tgz にある公式 SDK の tarball をインストールします。SDK は @solvethree/sdk としてインポートします。npm レジストリで公開されていると仮定せず、ダウンロード URL を使用してください。例は、拡張子が .mjs のファイルなど、ES モジュールとして保存します。

  2. 2.

    サイトプロファイルを設定する

    solvethree コンソールで所有するホスト名を設定し、そのプロファイルがワークスペースで有効になっていることを確認します。ホスト名とアクションを送信しても、そのプロファイルは作成されません。この例ではアクション login を使用しています。アプリケーションに設定されているアクションに変更してください。

  3. 3.

    環境変数を設定する

    TARGET_URL に所有する HTTPS フォームの URL、SOLVETHREE_PROXY に HTTP または HTTPS プロキシの URL、SOLVETHREE_API_KEY にワークスペースのキーを設定します。キーはページの JavaScript ではなく、Node.js プロセス内に保持してください。この例では、解決とブラウザーからの送信の両方に 1 つのプロキシを使用します。

タスクの site は、ページの完全な URL ではなく、TARGET_URL から抽出したホスト名です。reCAPTCHA では、site、action、および proxy または proxyCandidates のどちらか一方だけを送信してください。type や url フィールドは追加しないでください。この例では、Puppeteer が同じプロキシを直接使用できるように proxy を使用します。

解決してから同じ識別情報で Puppeteer を起動する

Puppeteer + Node.js · 自身が所有するHTTPSフォームの課題を解決
// Install puppeteer and the official solvethree SDK first.
import puppeteer from 'puppeteer';
import { Solvethree } from '@solvethree/sdk';

const target = new URL(process.env.TARGET_URL); // Your configured HTTPS page.
const proxy = new URL(process.env.SOLVETHREE_PROXY);
const client = new Solvethree({ apiKey: process.env.SOLVETHREE_API_KEY });
const result = await client.solve({
  site: target.hostname, action: 'login', proxy: process.env.SOLVETHREE_PROXY,
});
const browser = await puppeteer.launch({
  args: [`--proxy-server=${proxy.protocol}//${proxy.host}`],
});
try {
  const page = await browser.newPage();
  if (proxy.username) await page.authenticate({
    username: decodeURIComponent(proxy.username),
    password: decodeURIComponent(proxy.password),
  });
  await page.setUserAgent({ userAgent: result.solution.userAgent });
  await page.setExtraHTTPHeaders({ 'sec-ch-ua': result.solution.secChUa });
  await page.goto(target.href);
  // Adapt these selectors and any required callback to your own form.
  await page.waitForSelector('[name="g-recaptcha-response"]');
  await page.$eval('[name="g-recaptcha-response"]', (field, token) => {
    field.value = token;
    field.dispatchEvent(new Event('input', { bubbles: true }));
  }, result.solution.token);
  await Promise.all([
    page.waitForNavigation({ waitUntil: 'domcontentloaded' }),
    page.click('button[type="submit"]'),
  ]);
  // Check your application's success response here.
} finally {
  await browser.close();
}

client.solve はタスクを一度だけ作成し、準備完了になるか例外がスローされるまでポーリングします。この例では、その呼び出しから結果が返った後にのみ Puppeteer を起動します。ブラウザーはタスクのプロキシを使用し、プロキシの認証情報があれば認証を行い、ページに移動する前に solution.userAgent と solution.secChUa を適用します。

トークンを送信する際に、そのプロキシやブラウザー識別情報を無関係な値に置き換えないでください。後で proxyCandidates に切り替える場合は、SDK の successfulProxy ヘルパーを使って、成功した元のプロキシをブラウザー用に選択してください。

解決に失敗した場合は、同じ入力で再試行するのではなく、タスクの errorCode と error を確認してください。HTTP リクエストエラーは、最終的なタスクの失敗とは別のものです。finally ブロックはブラウザーでの処理後にローカルブラウザーを閉じます。ページを閉じても、リモートタスクはキャンセルされません。

デモのフォームに関する前提を置き換える

  • [name="g-recaptcha-response"] はデモの textarea を選択します。アプリケーションが別のフィールドやリクエストパラメーターでトークンを受け取る場合は、置き換えてください。送信する値は、タスク ID ではなく solution.token です。
  • button[type="submit"] はデモの送信ボタンを選択します。アプリケーションの実際のコントロールまたは送信の仕組みを使用してください。
  • この例ではトークンを設定し、input イベントを発火させます。これはアプリケーション固有のコールバックの代わりにはなりません。送信前に、必要なコールバック、CSRF 値、ログインフィールド、セッション設定を追加してください。
  • 最後の成功確認用コメントを、アプリケーションのレスポンスまたは処理後の状態に対するアサーションに置き換えてください。解決タスクが準備完了になっても、アプリケーションがトークンを受け付けたことは確認できません。

実行中のブラウザーを再利用する場合は、使用する BrowserContext を意識的に選択してください。新しいページが自動的に別のセッションになるわけではありません。無関係なワークフローのページを混在させず、フォームのセッション要件を一貫して満たしてください。

最初のタスクを実行しましょう。

$5のワークスペースクレジットで始められます。

ワークスペースを作成
PuppeteerでCAPTCHAソルバーを使う · solvethree