close menu
Підтримувані типи завдань
Методи API
Статті
GitHub icon
GitHub
Menu

Як обійти Cloudflare

У цій статті ви дізнаєтесь, як обійти сторінку Cloudflare "Verifying you are human" за допомогою NodeJS та автоматизації браузера Playwright.

Спочатку коротко розглянемо, як працює Cloudflare. Без Cloudflare адміністратори сайтів розміщують свої сторінки на сервері з публічною IP-адресою. Їхні доменні імена ведуть на цю IP-адресу, і ваш браузер безпосередньо з’єднується із сервером.

Коли використовується Cloudflare, адміністратори делегують керування DNS до Cloudflare, яка починає направляти домени на власні IP-адреси. На цих IP-адресах працюють спеціальні проксі-сервери, які фільтрують вхідні HTTP та HTTPS запити.

Нові відвідувачі бачать знайому сторінку з текстом: "Verifying you are human. This may take a few seconds.". Під час перевірки вам може знадобитися розв’язати капчу. Раніше використовувалась reCAPTCHA, але тепер використовується власна капча під назвою Turnstile.

Після успішної перевірки капчі браузер отримує унікальний токен у cookie з назвою cf_clearance. Ваш браузер використовує цей токен для запитів сторінок сайту через проксі Cloudflare. Якщо термін дії токена закінчився або Cloudflare вирішить, що токен поводиться як бот, токен буде анульовано, і ви знову побачите капчу.

Наш метод допоможе вам отримати цей токен за допомогою автоматизованої сесії браузера. Зверніть увагу, що цей метод не розкриває реальну IP-адресу сайту — ця інформація доступна лише Cloudflare та адміністраторам сайту. І це добре!

Ось як це зробити за допомогою NodeJS і Playwright:

// Install packages
// npx install playwright @antiadmin/anticaptchaofficial
import { chromium } from "playwright";
import ac from "@antiadmin/anticaptchaofficial";

// Specify the target website address
const websiteBehindCloudFlare = 'https://yourwebsite.com';

// Set your Anti-Captcha API key here:
ac.setAPIKey('API_KEY_HERE');
ac.setSoftId(0);

let browser = null;
let page = null;


(async () => {

    // Opening the browser
    try {
        console.log('Opening browser ..');
        browser = await chromium.launch({ headless: false });
        console.log('Creating new page ..');
        page = await browser.newPage();
    } catch (e) {
        console.log("Could not open browser: "+e.toString());
        return;
    }


    let params = null;

    try {

        // Doing several attempts to inject our code
        while (!params) {

            console.log('Navigating to the page')
            await page.goto(websiteBehindCloudFlare);

            console.log('Injecting our proxy code to replace window.turnstile');
            await page.evaluate(() => {
                window.turnstile = new Proxy(window.turnstile, {
                  get(target, prop) {
                    if (prop === "render") {
                      return function (a, b) {
                        const p = {
                          websiteURL: window.location.href,
                          websiteKey: b.sitekey,
                          action: b.action,
                          cData: b.cData,
                          chlPageData: b.chlPageData,
                          userAgent: navigator.userAgent,
                        };

                        // saving params in window.params
                        window.params = p;

                        // assigning callback to a variable
                        window.cfCallback = b.callback

                        // calling original render function
                        return target.render.apply(this, arguments);
                      };
                    }
                    return target[prop];
                  },
                });
            });

          console.log('Getting params');
          params = await page.evaluate(() => {
            return new Promise((resolve) => {
              setTimeout(() => resolve(window.params || null), 5000);
            });
          });

          if (!params) {
            console.log('Retrying..');
            await delay(3000);
          }
        }

        console.log("Extracted Turnstile Params:", params);

        console.log('Solving Turnstile captcha with Anti-Captcha')
        const token = await ac.solveTurnstileProxyless(websiteBehindCloudFlare, params.websiteKey, params.action, params.cData, params.chlPageData);

        // Running Cloudflare's callback function we previously assigned to window.cfCallback
        await page.evaluate((token) => {
            window.cfCallback(token)
        }, token);

        console.log('Waiting for redirects to finish')
        await delay(5000);

        // Get all cookies for current page
        const cookies = await page.context().cookies();
        // Find cf_clearance
        const cf_clearance = cookies.filter(c => c.name === 'cf_clearance');

        // Output cookies
        console.log('Cookies:', cookies);
        console.log('cf_clearance:', cf_clearance);



    } catch (e) {
      console.error('Could not inject proxy code:', e);
    }

    // close browser when needed
    // await browser.close();


})();

function delay(time) {
   return new Promise(function(resolve) {
       setTimeout(resolve, time)
   });
}

Що виконує наш код:

1. Відкрити вікно браузера та перейти на сторінку перевірки Cloudflare.
2. Замінити функцію render капчі Turnstile нашою proxy-функцією, яка перехоплює параметри ініціалізації та callback завершення капчі.
3. Надіслати параметри ініціалізації до API Anti-Captcha. Люди-оператори вирішують капчу за вас і повертають токен.
4. Викликати збережену раніше callback-функцію з токеном Turnstile як параметром.
5. Cloudflare внутрішньо перевіряє токен, встановлює cookie у браузері та перезавантажує сторінку.
6. З цим cf_clearance браузер отримує вміст сайту через проксі Cloudflare.