Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

If you solve Turnstile on the cloudflare 5s challenge pages, don’t forget to specify cloudflareTaskType and related fields. userAgent is required.

Object structure

Parameter

Type

Required

Value

type

String

yes

TurnstileTask

websiteURL

String

yes

The page address, where the captcha is solved

websiteKey

String

yes

Turnstile key

proxyType

String

yes

http - regular http/https proxy
https - try this option only if "http" doesn’t work (required for some custom proxies)
socks4 - socks4 proxy
socks5 - socks5 proxy

proxyAddress

String

yes

The IP address of the IPv4/IPv6 proxy. Not allowed:

  • using hostnames

  • using transparent proxies (where you can see the client's IP)

  • using proxies on local machines

proxyPort

Integer

yes

Proxy port

proxyLogin

String

no

Proxy login

proxyPassword

String

no

Proxy password

cloudflareTaskType

String

no

cf_clearance - if cookies are required;
token - if required token from Turnstile

htmlPageBase64

String

yes, if cloudflareTaskType is equal to cf_clearance

Base64 encoded html page with captcha.

userAgent

String

yes, if cloudflareTaskType is specified.

Only the latest UAs from Chrome are supported.

pageAction

String

yes, if cloudflareTaskType is equal totoken

The actionfield, that can be found in the callback function to load the captcha.
If cloudflareTaskType is used, then action, is usually “managed“ or “non-interactive“.

data

String

yes, if cloudflareTaskType is equal totoken

The value of the data field can be taken from the cData parameter.

pageData

String

yes, if cloudflareTaskType is equal to token

The value of the pageData field can be taken from the chlPageData parameter.

Proxy for token method is not required.

...

Use the getTaskResult method to get the Turnstile solution. Depending on the system load, you will receive a response after a time ranging from 5 to 20 seconds.

Property

Type

Description

cf_clearance

String

Special cloudflare cookies, that you can set

token

String

Pass this token to the callback function

When specify cloudflareTaskType and when not? Or how to distinguish a normal Turnstile from a Cloudflare Challenge.

...

  • The form with the id challenge-form has an action attribute, containing the __cf_chl_f_tk= parameter:

  • There are two similar <script> tags on the page that create a new value in the window object:

...

Expand
titleExample of implementing the solution using Selenium on Node.js
Code Block
languagejs
const { Builder } = require('selenium-webdriver');
const chrome = require('selenium-webdriver/chrome');

(async function example() {
  const options = new chrome.Options();
  options.addArguments('--auto-open-devtools-for-tabs')

  const driver = new Builder()
    .forBrowser('chrome')
    .setChromeOptions(options)
    .build();

  try {
    driver.executeScript(`
    window.turnstile = new Proxy(window.turnstile, {
      get(target, prop) {
        if (prop === 'render') {
          return function(a, b) {
            let p = {
              type: "TurnstileTaskProxyless",
              websiteKey: b.sitekey,
              websiteURL: window.location.href,
              data: b.cData,
              pagedata: b.chlPageData,
              action: b.action,
              userAgent: navigator.userAgent
          }
          
          console.log(JSON.stringify(p))
          window.params = p;
          window.turnstileCallback = b.callback;
            return target.render.apply(this, arguments);
          }
        }
        return target[prop];
      }
    });
    `)

    driver.get('SITE WITH CAPTCHA');
    

    const params = await driver.executeScript(`
      return new Promise((resolve, reject) => {
        setTimeout(() => {
          resolve(window.params)
        }, 2000)
      })
    `);

    if (params) {
      const data = {
        clientKey: 'API KEY',
        task: {
          type: 'TurnstileTaskProxyless',
          websiteURL: params.websiteURL,
          websiteKey: params.websiteKey,
          data: params.data,
          action: params.action
        }
      }

      const createResult = await fetch('https://api.capmonster.cloud/createTask', {
        method: 'post',
        body: JSON.stringify(data)
      });

      const createTaskResult = await createResult.json()

      if (createTaskResult.taskId) {
        const asyncDelay = (timeout) =>
          new Promise(resolve => {
              setTimeout(() => {
                  resolve();
              }, timeout);
          });
        
        const getTaskResult = async (taskId) => {
          const taskResult = await fetch('https://api.capmonster.cloud/getTaskResult', {
            method: 'post',
            body: JSON.stringify({
              "clientKey":"API KEY",
              "taskId": createTaskResult.taskId
            })
          });
          const taskResponse = await taskResult.json();
          if (taskResponse.status === 'processing') {
            await asyncDelay(5000);
            return await getTaskResult(taskId)
          }
          return taskResponse;
        }
       
        const taskRes = await getTaskResult(createTaskResult.taskId)

        if (taskRes.solution) {
          await driver.executeScript(`
            window.turnstileCallback(${taskRes.solution.token});
          `);
        }
      }
      
    }

    //DO SOMETHING
  } finally {
    await driver.quit();
  }
})();