Puppeteer에서 CAPTCHA 솔버 사용하기

작성: solvethree읽는 데 2분

공식 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 프로세스에 보관하세요. 예제는 해결과 브라우저 제출에 프록시 하나를 사용합니다.

작업의 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