Menu

วิธีหลีกเลี่ยง Cloudflare

ในบทความนี้ คุณจะได้เรียนรู้วิธีหลีกเลี่ยงหน้าตรวจสอบ "Verifying you are human" ของ Cloudflare โดยใช้ NodeJS และการควบคุมเบราว์เซอร์ผ่าน Playwright

ก่อนอื่น มาทำความเข้าใจโดยย่อว่า Cloudflare ทำงานอย่างไร หากไม่มี Cloudflare ผู้ดูแลเว็บไซต์จะโฮสต์หน้าเว็บของตนบนเซิร์ฟเวอร์ที่มี IP สาธารณะ ชื่อโดเมนของพวกเขาจะชี้ไปยัง IP นั้น และเบราว์เซอร์ของคุณจะเชื่อมต่อกับเซิร์ฟเวอร์โดยตรง

เมื่อใช้ Cloudflare การจัดการ DNS จะถูกมอบหมายให้ Cloudflare ซึ่งจะชี้ชื่อโดเมนไปยัง IP ของตนเอง บน IP เหล่านั้น จะมีพร็อกซีเซิร์ฟเวอร์พิเศษที่ใช้กรองคำขอ HTTP และ HTTPS ที่เข้ามา

ผู้เข้าชมใหม่จะเห็นหน้าที่มีข้อความว่า: "Verifying you are human. This may take a few seconds." ในระหว่างการตรวจสอบนี้ คุณอาจต้องแก้ captcha เดิมทีพวกเขาใช้ reCAPTCHA แต่ปัจจุบันใช้ captcha ของตนเองที่ชื่อว่า Turnstile

เมื่อผ่านการตรวจสอบ captcha แล้ว เบราว์เซอร์จะได้รับโทเคนที่ไม่ซ้ำกันในคุกกี้ชื่อ cf_clearance เบราว์เซอร์ของคุณจะใช้โทเคนนี้เพื่อร้องขอหน้าเว็บไซต์ผ่านพร็อกซีของ Cloudflare หากโทเคนหมดอายุ หรือ Cloudflare พิจารณาว่าพฤติกรรมของโทเคนนั้นเหมือนบอท โทเคนนั้นจะถูกยกเลิกและคุณจะเห็นหน้า captcha อีกครั้ง

วิธีของเราจะช่วยให้คุณได้รับโทเคนนี้โดยใช้เซสชันเบราว์เซอร์แบบอัตโนมัติ โปรดทราบว่าวิธีนี้จะไม่เปิดเผย 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 ของ captcha
3. ส่งพารามิเตอร์เริ่มต้นไปยัง API ของ Anti-Captcha จะมีพนักงานจริงช่วยแก้ captcha และส่งโทเคนกลับมาให้คุณ
4. เรียกใช้ฟังก์ชัน callback ที่บันทึกไว้ก่อนหน้านี้ โดยใส่โทเคน Turnstile เป็นพารามิเตอร์
5. Cloudflare ตรวจสอบโทเคนภายใน ตั้งค่าคุกกี้ ให้กับเบราว์เซอร์ และโหลดหน้าใหม่
6. ด้วย cf_clearance นี้ เบราว์เซอร์จะสามารถดึงเนื้อหาของเว็บไซต์ผ่านพร็อกซีของ Cloudflare ได้