Playwright の JSON リクエストで解決済みトークンを送信する
アプリケーションの既知の JSON POST をインターセプトし、CAPTCHA フィールドを solution.token に置き換えてください。アプリケーションが JavaScript の状態からリクエストを構築する場合、textarea に入力しても効果はありません。
以下の例は、自分が所有するアプリケーションの同一オリジンの送信エンドポイントを対象としています。リクエストを再構築せず、他の JSON フィールドとリクエストヘッダーを維持します。
このページの内容
例をアプリケーションに合わせる
- 1.
ソルバーを準備する
Node.js 22+、Playwright、公式 JavaScript SDK を使用します。SDK のインストール手順に従い、npm レジストリで入手できると想定せず、ドキュメントに記載されたパッケージのダウンロード方法を使用してください。
SOLVETHREE_API_KEYはブラウザーコードではなく、Node.js プロセス内に保持してください。 - 2.
サイトとプロキシを設定する
TARGET_URLに自分が所有するテストページを、SOLVETHREE_PROXYにそのページへのアクセスに使う HTTP または HTTPS プロキシの URL を設定します。この例では、ページのホスト名に対してアクションloginをリクエストします。そのホスト名には有効なワークスペースプロファイルが必要です。先にサイトプロファイルを設定してください。アプリケーションで別のアクションを使用している場合は変更してください。 - 3.
送信先と送信内容を正確に特定する
TARGET_SUBMIT_URLに、パスを含む JSON POST エンドポイントを設定します。ページと同じオリジンである必要があります。この例では、recaptchaTokenを含むオブジェクトと、アクセシブルネームが正確にSubmitであるボタンを想定しています。これらのアプリケーション固有の設定は、まとめて変更してください。
テストフィクスチャには、そのエンドポイントへ JSON オブジェクトを送信し、検査可能なレスポンスを返すページを使用してください。別のフィールドと CSRF フィールドを含め、どちらも変更されていないことを確認できるようにします。受信内容をそのまま返すだけのローカルフィクスチャでも JSON の書き換えは実演できますが、CAPTCHA が受理されたことは検証できません。提供された例でも実際に解決処理を行うため、設定済みでプロキシ経由でアクセス可能なサイトが必要です。
解決、インターセプト、送信を行う
import { chromium } from 'playwright';
import { Solvethree } from '@solvethree/sdk';
const client = new Solvethree({ apiKey: process.env.SOLVETHREE_API_KEY });
const target = new URL(process.env.TARGET_URL);
const proxy = new URL(process.env.SOLVETHREE_PROXY);
const result = await client.solve({ site: target.hostname, action: 'login', proxy: process.env.SOLVETHREE_PROXY });
const proxyConfig = { server: `${proxy.protocol}//${proxy.host}`, username: decodeURIComponent(proxy.username), password: decodeURIComponent(proxy.password) };
const submit = new URL(process.env.TARGET_SUBMIT_URL);
if (submit.origin !== target.origin) throw new Error('Use this demo with a same-origin submission URL');
const browser = await chromium.launch();
try {
const context = await browser.newContext({ proxy: proxyConfig, userAgent: result.solution.userAgent,
extraHTTPHeaders: { 'sec-ch-ua': result.solution.secChUa } });
const page = await context.newPage();
await page.route(submit.href, async route => {
if (route.request().method() !== 'POST') return route.continue();
const body = route.request().postDataJSON();
if (!body || typeof body !== 'object' || Array.isArray(body)) throw new Error('Expected the known JSON object');
await route.continue({ postData: JSON.stringify({ ...body, recaptchaToken: result.solution.token }),
headers: { ...route.request().headers(), 'content-type': 'application/json' } });
});
await page.goto(target.href);
const outcome = page.waitForResponse(r => r.url() === submit.href && r.request().method() === 'POST');
await page.getByRole('button', { name: 'Submit', exact: true }).click();
console.log('Application HTTP status:', (await outcome).status());
// recaptchaToken, the Submit button and this endpoint belong to this demo app.
// Adapt them to the real application, retaining its session/CSRF data.
await context.close();
} finally { await browser.close(); }client.solve はタスクを作成し、準備が完了するか例外をスローするまでポーリングします。その後、この例では solution.userAgent、solution.secChUa、解決時に指定したものと同じ単一のプロキシを使ってブラウザーコンテキストを作成します。SDK は解決結果をブラウザーに適用しません。適用するのはルートハンドラーです。
ブラウザーコンテキストは新規です。送信に認証やその他のセッション設定が必要な場合は、送信前にこのコンテキスト内で行ってください。この例では、既存のブラウザーセッションをインポートしません。
リクエスト全体ではなくトークンを置き換える
ルートはページ遷移の前に登録され、設定された送信先 URL のみに適用されます。POST 以外のリクエストは変更せずに続行します。POST の場合、ハンドラーは既存の JSON オブジェクトを読み取り、そのフィールドをコピーして、recaptchaToken だけを置き換えます。
これにより、フォーム値や CSRF データなどのボディフィールドが保持されます。ハンドラーはリクエストヘッダーもコピーし、コンテンツタイプを JSON に設定します。アプリケーションの既存のセッション処理と CSRF 処理は維持してください。解決済みトークンは、どちらの代わりにもなりません。
ルートの対象をすべてのリクエストに広げたり、トークンらしく見えるだけのフィールドを置き換えたりしないでください。自分が所有するアプリケーションの送信リクエストを調べ、実際のフィールド名を使用してください。この例は、ウィジェットの検出、任意のコールバックの呼び出し、任意のサードパーティページへの対応は行いません。インターセプトの仕組みについては、Playwright のネットワークドキュメントを参照してください。
アプリケーションのレスポンスを確認する
レスポンスの待機はクリック前に開始され、送信先 URL と POST メソッドに一致するレスポンスを対象にします。ログに記録されるステータスは、solvethree のタスクではなく、アプリケーションのレスポンスのものです。アプリケーション独自の成功条件に従って、そのレスポンスのボディまたは処理後のアプリケーションの状態を確認してください。タスクの準備完了も HTTP の成功ステータスも、それだけではアプリケーションがトークンを受理した証拠にはなりません。
- レスポンスの待機が完了しない。
対象の Submit ボタンが、設定した URL への POST を実行するか確認してください。
試してみましょう: ボタンのロケーター、エンドポイント、メソッドをアプリケーションに合わせて修正してください。無関係な通信にまでインターセプトの対象を広げないでください。
- ルートで JSON オブジェクトを読み取れない。
リクエストボディとコンテンツタイプを確認してください。
試してみましょう: このハンドラーは、JSON オブジェクトを受け取ることがわかっているエンドポイントにのみ使用してください。フォームデータ、配列、その他のペイロード形式には別の処理が必要です。
- タスクの準備は完了しているが、アプリケーションが送信を拒否する。
送信される JSON に
solution.tokenが含まれているか調べ、セッション/CSRF データ、アクション、返されたブラウザー識別情報、プロキシを確認してください。試してみましょう: 再度の解決に料金を支払う前に、リクエストの不一致を修正してください。ブラウザーには解決時と同じプロキシを使い続け、返された識別情報を使用してください。
- ブラウザーが開く前に解決処理が失敗する。
HTTP リクエストのエラーと、タスクの終端状態としての失敗を区別してください。タスクが失敗した場合は、
errorCodeとerrorを確認してください。試してみましょう: 同じ入力のまま再試行するのではなく、報告された入力、プロファイル、接続の問題を修正してください。API エラー処理を参照してください。
参照元とAPIリファレンス
最初のタスクを実行しましょう。
$5のワークスペースクレジットで始められます。