Quay lại blog

Cách ẩn việc sử dụng Selenium và Puppeteer

Tìm hiểu cách ẩn hiệu quả việc sử dụng Selenium và Puppeteer khỏi các hệ thống chống bot. Phương pháp thực tiễn, ví dụ mã và kỹ thuật che giấu tự động hóa đã được kiểm chứng.

📅26 tháng 12, 2025
```html

Hướng dẫn đầy đủ về cách che giấu Selenium và Puppeteer khỏi phát hiện

Các hệ thống chống bot hiện đại dễ dàng nhận diện các trình duyệt tự động hóa qua hàng chục dấu hiệu: từ các biến JavaScript đến các đặc điểm hành vi của WebDriver. Các trang web sử dụng Cloudflare, DataDome, PerimeterX và các giải pháp riêng của họ, chặn tới 90% yêu cầu từ Selenium và Puppeteer trong cấu hình tiêu chuẩn.

Trong hướng dẫn này, chúng ta sẽ xem xét tất cả các phương pháp che giấu tự động hóa: từ các cài đặt cơ bản đến các kỹ thuật nâng cao để vượt qua phát hiện. Bạn sẽ nhận được các giải pháp sẵn có với ví dụ mã cho Python và Node.js, hoạt động chống lại hầu hết các hệ thống bảo vệ.

Cách các trang web phát hiện tự động hóa

Các hệ thống chống bot phân tích trình duyệt dựa trên nhiều tham số cùng một lúc. Ngay cả khi bạn ẩn một dấu hiệu, các dấu hiệu khác sẽ tiết lộ tự động hóa. Hiểu tất cả các phương pháp phát hiện là chìa khóa để che giấu hiệu quả.

Các chỉ báo WebDriver

Phương pháp phát hiện đơn giản nhất là kiểm tra các biến JavaScript, chỉ có mặt trong các trình duyệt tự động hóa:

// Những biến này tiết lộ Selenium/Puppeteer
navigator.webdriver === true
window.navigator.webdriver === true
document.$cdc_ // Biến đặc trưng của ChromeDriver
window.document.documentElement.getAttribute("webdriver")
navigator.plugins.length === 0 // Các trình duyệt tự động hóa không có plugin
navigator.languages === "" // Danh sách ngôn ngữ trống

Cloudflare và các hệ thống tương tự kiểm tra các thuộc tính này trước tiên. Nếu ít nhất một thuộc tính trả về kết quả tích cực — yêu cầu sẽ bị chặn.

Fingerprinting trình duyệt

Các hệ thống tiên tiến tạo ra một dấu vân tay trình duyệt độc nhất dựa trên hàng chục tham số:

  • Canvas Fingerprinting — vẽ các hình ảnh ẩn và phân tích dữ liệu pixel
  • WebGL Fingerprinting — các tham số của bộ xử lý đồ họa và card đồ họa
  • Audio Context — các đặc điểm độc nhất của xử lý âm thanh
  • Fonts Fingerprinting — danh sách các phông chữ đã cài đặt trong hệ thống
  • Screen Resolution — độ phân giải màn hình, độ sâu màu, khu vực có sẵn
  • Timezone & Language — múi giờ, ngôn ngữ của trình duyệt, ngôn ngữ hệ thống

Các trình duyệt tự động hóa thường có các kết hợp không điển hình của những tham số này. Ví dụ, Headless Chrome không có plugin, nhưng hỗ trợ WebGL — sự kết hợp như vậy rất hiếm gặp ở người dùng thực.

Phân tích hành vi

Các hệ thống hiện đại theo dõi các mẫu hành vi:

  • Chuyển động chuột — bot di chuyển con trỏ theo các đường thẳng hoặc không di chuyển chút nào
  • Tốc độ hành động — điền biểu mẫu ngay lập tức, tốc độ nhấp chuột không giống con người
  • Mẫu cuộn — nhảy vọt thay vì cuộn mượt mà
  • Sự kiện bàn phím — không có độ trễ tự nhiên giữa các lần nhấn
  • Tần suất yêu cầu — khoảng thời gian quá đều đặn giữa các hành động

Quan trọng: DataDome và PerimeterX sử dụng học máy để phân tích hành vi. Chúng được đào tạo trên hàng triệu phiên và có thể nhận diện bot ngay cả khi các tham số kỹ thuật được che giấu đúng cách, nếu hành vi trông không tự nhiên.

Che giấu cơ bản với Selenium

Selenium WebDriver trong cấu hình tiêu chuẩn để lại nhiều dấu vết. Hãy xem xét từng bước cài đặt để giảm thiểu phát hiện với ví dụ cho Python và ChromeDriver.

Tắt cờ webdriver

Bước đầu tiên là ẩn biến navigator.webdriver. Điều này được thực hiện thông qua Giao thức DevTools của Chrome:

from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.chrome.options import Options

# Cài đặt tùy chọn Chrome
chrome_options = Options()

# Tắt cờ tự động hóa
chrome_options.add_experimental_option("excludeSwitches", ["enable-automation"])
chrome_options.add_experimental_option('useAutomationExtension', False)

# Tạo driver
driver = webdriver.Chrome(options=chrome_options)

# Xóa webdriver qua CDP
driver.execute_cdp_cmd('Page.addScriptToEvaluateOnNewDocument', {
    'source': '''
        Object.defineProperty(navigator, 'webdriver', {
            get: () => undefined
        })
    '''
})

driver.get('https://example.com')

Cấu hình User-Agent và các tiêu đề khác

Các trình duyệt headless thường sử dụng các chuỗi User-Agent lỗi thời hoặc đặc trưng. Cần phải thiết lập User-Agent hiện tại của một trình duyệt thực:

# User-Agent hiện tại của Chrome trên Windows
user_agent = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36'
chrome_options.add_argument(f'user-agent={user_agent}')

# Các tham số bổ sung để che giấu
chrome_options.add_argument('--disable-blink-features=AutomationControlled')
chrome_options.add_argument('--disable-dev-shm-usage')
chrome_options.add_argument('--no-sandbox')
chrome_options.add_argument('--disable-gpu')

# Kích thước cửa sổ giống như người dùng thực
chrome_options.add_argument('--window-size=1920,1080')
chrome_options.add_argument('--start-maximized')

Thêm plugin và ngôn ngữ

Các trình duyệt tự động hóa không có plugin và thường hiển thị danh sách ngôn ngữ trống. Chúng ta sẽ sửa điều này qua CDP:

driver.execute_cdp_cmd('Page.addScriptToEvaluateOnNewDocument', {
    'source': '''
        Object.defineProperty(navigator, 'languages', {
            get: () => ['en-US', 'en', 'ru']
        });
        
        Object.defineProperty(navigator, 'plugins', {
            get: () => [
                {
                    0: {type: "application/x-google-chrome-pdf", suffixes: "pdf", description: "Portable Document Format"},
                    description: "Portable Document Format",
                    filename: "internal-pdf-viewer",
                    length: 1,
                    name: "Chrome PDF Plugin"
                },
                {
                    0: {type: "application/pdf", suffixes: "pdf", description: ""},
                    description: "",
                    filename: "mhjfbmdgcfjbbpaeojofohoefgiehjai",
                    length: 1,
                    name: "Chrome PDF Viewer"
                }
            ]
        });
        
        Object.defineProperty(navigator, 'platform', {
            get: () => 'Win32'
        });
    '''
})

Ví dụ đầy đủ về cài đặt Selenium

from selenium import webdriver
from selenium.webdriver.chrome.options import Options
import random

def create_stealth_driver():
    chrome_options = Options()
    
    # Cài đặt cơ bản để che giấu
    chrome_options.add_experimental_option("excludeSwitches", ["enable-automation"])
    chrome_options.add_experimental_option('useAutomationExtension', False)
    chrome_options.add_argument('--disable-blink-features=AutomationControlled')
    
    # User-Agent
    user_agent = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36'
    chrome_options.add_argument(f'user-agent={user_agent}')
    
    # Kích thước cửa sổ
    chrome_options.add_argument('--window-size=1920,1080')
    chrome_options.add_argument('--start-maximized')
    
    driver = webdriver.Chrome(options=chrome_options)
    
    # Script che giấu qua CDP
    stealth_script = '''
        Object.defineProperty(navigator, 'webdriver', {get: () => undefined});
        Object.defineProperty(navigator, 'languages', {get: () => ['en-US', 'en']});
        Object.defineProperty(navigator, 'platform', {get: () => 'Win32'});
        
        window.chrome = {
            runtime: {}
        };
        
        Object.defineProperty(navigator, 'plugins', {
            get: () => [1, 2, 3, 4, 5]
        });
    '''
    
    driver.execute_cdp_cmd('Page.addScriptToEvaluateOnNewDocument', {
        'source': stealth_script
    })
    
    return driver

# Sử dụng
driver = create_stealth_driver()
driver.get('https://bot.sannysoft.com/')  # Trang web để kiểm tra phát hiện

Cấu hình Puppeteer để vượt qua phát hiện

Puppeteer có những vấn đề phát hiện tương tự như Selenium. Tuy nhiên, cho Node.js có một thư viện sẵn có là puppeteer-extra-plugin-stealth, tự động hóa hầu hết các cài đặt che giấu.

Cài đặt puppeteer-extra

npm install puppeteer puppeteer-extra puppeteer-extra-plugin-stealth

Cấu hình cơ bản với plugin stealth

const puppeteer = require('puppeteer-extra');
const StealthPlugin = require('puppeteer-extra-plugin-stealth');

// Kết nối plugin che giấu
puppeteer.use(StealthPlugin());

(async () => {
    const browser = await puppeteer.launch({
        headless: 'new', // Chế độ headless mới của Chrome
        args: [
            '--no-sandbox',
            '--disable-setuid-sandbox',
            '--disable-dev-shm-usage',
            '--disable-accelerated-2d-canvas',
            '--disable-gpu',
            '--window-size=1920,1080',
            '--disable-web-security',
            '--disable-features=IsolateOrigins,site-per-process'
        ]
    });
    
    const page = await browser.newPage();
    
    // Thiết lập viewport
    await page.setViewport({
        width: 1920,
        height: 1080,
        deviceScaleFactor: 1
    });
    
    // Thiết lập User-Agent
    await page.setUserAgent('Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36');
    
    // Các tiêu đề bổ sung
    await page.setExtraHTTPHeaders({
        'Accept-Language': 'en-US,en;q=0.9',
        'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8'
    });
    
    await page.goto('https://bot.sannysoft.com/');
    
    // Chụp ảnh để kiểm tra
    await page.screenshot({ path: 'test.png' });
    
    await browser.close();
})();

Cài đặt thủ công không cần plugin

Nếu bạn muốn kiểm soát hoàn toàn hoặc không thể sử dụng thư viện bên ngoài, hãy cài đặt che giấu thủ công:

const puppeteer = require('puppeteer');

(async () => {
    const browser = await puppeteer.launch({
        headless: 'new',
        args: ['--no-sandbox', '--disable-setuid-sandbox']
    });
    
    const page = await browser.newPage();
    
    // Ghi đè webdriver và các thuộc tính khác
    await page.evaluateOnNewDocument(() => {
        Object.defineProperty(navigator, 'webdriver', {
            get: () => undefined
        });
        
        Object.defineProperty(navigator, 'languages', {
            get: () => ['en-US', 'en']
        });
        
        Object.defineProperty(navigator, 'plugins', {
            get: () => [1, 2, 3, 4, 5]
        });
        
        // Che giấu Chrome headless
        Object.defineProperty(navigator, 'platform', {
            get: () => 'Win32'
        });
        
        window.chrome = {
            runtime: {}
        };
        
        // Ghi đè permissions
        const originalQuery = window.navigator.permissions.query;
        window.navigator.permissions.query = (parameters) => (
            parameters.name === 'notifications' ?
                Promise.resolve({ state: Notification.permission }) :
                originalQuery(parameters)
        );
    });
    
    await page.goto('https://example.com');
    await browser.close();
})();

Cấu hình để vượt qua Cloudflare

Cloudflare sử dụng các phương pháp phát hiện tiên tiến. Để vượt qua, cần thêm các độ trễ ngẫu nhiên và mô phỏng hành động:

const puppeteer = require('puppeteer-extra');
const StealthPlugin = require('puppeteer-extra-plugin-stealth');

puppeteer.use(StealthPlugin());

async function bypassCloudflare(url) {
    const browser = await puppeteer.launch({
        headless: 'new',
        args: [
            '--no-sandbox',
            '--disable-setuid-sandbox',
            '--disable-web-security'
        ]
    });
    
    const page = await browser.newPage();
    
    // User-Agent ngẫu nhiên
    const userAgents = [
        'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
        'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
        'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36'
    ];
    await page.setUserAgent(userAgents[Math.floor(Math.random() * userAgents.length)]);
    
    // Chuyển đến trang
    await page.goto(url, { waitUntil: 'networkidle2' });
    
    // Chờ kiểm tra Cloudflare (thường 5-10 giây)
    await page.waitForTimeout(8000);
    
    // Di chuyển chuột ngẫu nhiên
    await page.mouse.move(100, 100);
    await page.mouse.move(200, 200);
    
    const content = await page.content();
    await browser.close();
    
    return content;
}

Chiến đấu với JavaScript-fingerprinting

JavaScript-fingerprinting là việc tạo ra một dấu vân tay độc nhất của trình duyệt dựa trên nhiều tham số. Ngay cả khi bạn đã ẩn webdriver, các hệ thống phân tích hàng trăm thuộc tính khác để phát hiện tự động hóa.

Các vectơ chính của fingerprinting

Các hệ thống chống bot kiểm tra các tham số sau:

Tham số Điều gì được kiểm tra Rủi ro phát hiện
navigator.webdriver Sự hiện diện của cờ tự động hóa Nghiêm trọng
navigator.plugins Số lượng và loại plugin Cao
window.chrome Sự hiện diện của API Chrome Trung bình
navigator.permissions API quyền của trình duyệt Trung bình
screen.colorDepth Độ sâu màu của màn hình Thấp
navigator.hardwareConcurrency Số lượng lõi của bộ xử lý Thấp

Script che giấu tổng hợp

Script dưới đây ghi đè hầu hết các thuộc tính vấn đề. Triển khai nó qua CDP (Selenium) hoặc evaluateOnNewDocument (Puppeteer):

const stealthScript = `
    // Xóa webdriver
    Object.defineProperty(navigator, 'webdriver', {
        get: () => undefined
    });
    
    // Thêm đối tượng chrome
    window.chrome = {
        runtime: {},
        loadTimes: function() {},
        csi: function() {},
        app: {}
    };
    
    // Ghi đè permissions
    const originalQuery = window.navigator.permissions.query;
    window.navigator.permissions.query = (parameters) => (
        parameters.name === 'notifications' ?
            Promise.resolve({ state: Notification.permission }) :
            originalQuery(parameters)
    );
    
    // Che giấu plugins
    Object.defineProperty(navigator, 'plugins', {
        get: () => {
            return [
                {
                    0: {type: "application/x-google-chrome-pdf", suffixes: "pdf"},
                    description: "Portable Document Format",
                    filename: "internal-pdf-viewer",
                    length: 1,
                    name: "Chrome PDF Plugin"
                },
                {
                    0: {type: "application/pdf", suffixes: "pdf"},
                    description: "Portable Document Format",
                    filename: "internal-pdf-viewer",
                    length: 1,
                    name: "Chrome PDF Viewer"
                },
                {
                    0: {type: "application/x-nacl"},
                    description: "Native Client Executable",
                    filename: "internal-nacl-plugin",
                    length: 2,
                    name: "Native Client"
                }
            ];
        }
    });
    
    // Ngôn ngữ
    Object.defineProperty(navigator, 'languages', {
        get: () => ['en-US', 'en']
    });
    
    // Nền tảng
    Object.defineProperty(navigator, 'platform', {
        get: () => 'Win32'
    });
    
    // Nhà cung cấp
    Object.defineProperty(navigator, 'vendor', {
        get: () => 'Google Inc.'
    });
    
    // Xóa dấu vết Selenium
    delete window.cdc_adoQpoasnfa76pfcZLmcfl_Array;
    delete window.cdc_adoQpoasnfa76pfcZLmcfl_Promise;
    delete window.cdc_adoQpoasnfa76pfcZLmcfl_Symbol;
    
    // Battery API (không có trong headless)
    if (!navigator.getBattery) {
        navigator.getBattery = () => Promise.resolve({
            charging: true,
            chargingTime: 0,
            dischargingTime: Infinity,
            level: 1
        });
    }
`;

Xóa các thuộc tính WebDriver

ChromeDriver và các triển khai WebDriver khác thêm các biến đặc trưng vào phạm vi toàn cầu. Những biến này bắt đầu bằng tiền tố cdc_ và dễ dàng bị các hệ thống bảo vệ phát hiện.

Phát hiện các biến cdc

Kiểm tra sự hiện diện của các biến này có thể thực hiện bằng một script đơn giản:

// Tìm tất cả các biến cdc
for (let key in window) {
    if (key.includes('cdc_')) {
        console.log('Phát hiện biến WebDriver:', key);
    }
}

// Các biến điển hình của ChromeDriver:
// cdc_adoQpoasnfa76pfcZLmcfl_Array
// cdc_adoQpoasnfa76pfcZLmcfl_Promise
// cdc_adoQpoasnfa76pfcZLmcfl_Symbol
// $cdc_asdjflasutopfhvcZLmcfl_

Phương pháp 1: Xóa qua CDP

Cách đáng tin cậy nhất là xóa các biến trước khi tải trang thông qua Giao thức DevTools của Chrome:

from selenium import webdriver

driver = webdriver.Chrome()

# Xóa tất cả các biến cdc
driver.execute_cdp_cmd('Page.addScriptToEvaluateOnNewDocument', {
    'source': '''
        // Xóa các biến cdc đã biết
        const cdcProps = [
            'cdc_adoQpoasnfa76pfcZLmcfl_Array',
            'cdc_adoQpoasnfa76pfcZLmcfl_Promise',
            'cdc_adoQpoasnfa76pfcZLmcfl_Symbol',
            '$cdc_asdjflasutopfhvcZLmcfl_'
        ];
        
        cdcProps.forEach(prop => {
            delete window[prop];
        });
        
        // Xóa tất cả các biến chứa 'cdc_'
        Object.keys(window).forEach(key => {
            if (key.includes('cdc_') || key.includes('$cdc_')) {
                delete window[key];
            }
        });
    '''
})

Phương pháp 2: Chỉnh sửa ChromeDriver

Một cách tiếp cận quyết liệt hơn là thay đổi tệp nhị phân của ChromeDriver, thay thế chuỗi cdc_ bằng một chuỗi ký tự khác. Điều này ngăn chặn việc tạo ra các biến này:

import re

def patch_chromedriver(driver_path):
    """
    Patches ChromeDriver, replacing 'cdc_' with a random string
    """
    with open(driver_path, 'rb') as f:
        content = f.read()
    
    # Replace all occurrences of 'cdc_' with 'dog_' (or any other string of the same length)
    patched = content.replace(b'cdc_', b'dog_')
    
    with open(driver_path, 'wb') as f:
        f.write(patched)
    
    print(f'ChromeDriver patched: {driver_path}')

# Sử dụng
patch_chromedriver('/path/to/chromedriver')

Cảnh báo: Chỉnh sửa tệp nhị phân của ChromeDriver có thể làm hỏng hoạt động của nó. Luôn sao lưu trước khi vá. Phương pháp này không hoạt động với tất cả các phiên bản của ChromeDriver.

Phương pháp 3: Sử dụng undetected-chromedriver

Thư viện undetected-chromedriver tự động vá ChromeDriver khi khởi động:

pip install undetected-chromedriver
import undetected_chromedriver as uc

# Tạo driver với vá tự động
driver = uc.Chrome()

driver.get('https://nowsecure.nl/')  # Trang web để kiểm tra phát hiện
input('Nhấn Enter để đóng...')
driver.quit()

Che giấu Canvas, WebGL và Audio API

Canvas, WebGL và Audio Fingerprinting là các phương pháp tạo ra một dấu vân tay độc nhất dựa trên các đặc điểm của việc xử lý đồ họa và âm thanh. Mỗi sự kết hợp của trình duyệt, hệ điều hành và phần cứng tạo ra một kết quả độc nhất.

Canvas Fingerprinting

Các hệ thống vẽ một hình ảnh ẩn trên Canvas và phân tích các pixel thu được. Các trình duyệt headless thường cho kết quả không điển hình do thiếu tăng tốc GPU.

// Mã điển hình cho Canvas Fingerprinting
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
ctx.textBaseline = 'top';
ctx.font = '14px Arial';
ctx.fillText('Dấu vân tay trình duyệt', 2, 2);
const fingerprint = canvas.toDataURL();

Để bảo vệ, có thể thêm tiếng ồn ngẫu nhiên vào Canvas API:

const canvasNoiseScript = `
    // Thêm tiếng ồn ngẫu nhiên vào Canvas
    const originalToDataURL = HTMLCanvasElement.prototype.toDataURL;
    const originalToBlob = HTMLCanvasElement.prototype.toBlob;
    const originalGetImageData = CanvasRenderingContext2D.prototype.getImageData;
    
    // Hàm thêm tiếng ồn
    const addNoise = (canvas, context) => {
        const imageData = originalGetImageData.call(context, 0, 0, canvas.width, canvas.height);
        for (let i = 0; i < imageData.data.length; i += 4) {
            // Thêm tiếng ồn tối thiểu vào RGB (không nhìn thấy bằng mắt)
            imageData.data[i] += Math.floor(Math.random() * 3) - 1;
            imageData.data[i + 1] += Math.floor(Math.random() * 3) - 1;
            imageData.data[i + 2] += Math.floor(Math.random() * 3) - 1;
        }
        context.putImageData(imageData, 0, 0);
    };
    
    // Ghi đè toDataURL
    HTMLCanvasElement.prototype.toDataURL = function() {
        if (this.width > 0 && this.height > 0) {
            const context = this.getContext('2d');
            addNoise(this, context);
        }
        return originalToDataURL.apply(this, arguments);
    };
`;

WebGL Fingerprinting

WebGL cung cấp thông tin về card đồ họa và driver. Các trình duyệt headless thường hiển thị SwiftShader (trình xử lý đồ họa phần mềm) thay vì GPU thực:

const webglMaskScript = `
    // Che giấu các tham số WebGL
    const getParameter = WebGLRenderingContext.prototype.getParameter;
    WebGLRenderingContext.prototype.getParameter = function(parameter) {
        // UNMASKED_VENDOR_WEBGL
        if (parameter === 37445) {
            return 'Intel Inc.';
        }
        // UNMASKED_RENDERER_WEBGL
        if (parameter === 37446) {
            return 'Intel Iris OpenGL Engine';
        }
        return getParameter.call(this, parameter);
    };
    
    // Cũng cho WebGL2
    if (typeof WebGL2RenderingContext !== 'undefined') {
        const getParameter2 = WebGL2RenderingContext.prototype.getParameter;
        WebGL2RenderingContext.prototype.getParameter = function(parameter) {
            if (parameter === 37445) {
                return 'Intel Inc.';
            }
            if (parameter === 37446) {
                return 'Intel Iris OpenGL Engine';
            }
            return getParameter2.call(this, parameter);
        };
    }
`;

Fingerprinting Audio Context

Audio API cũng cung cấp một dấu vân tay độc nhất. Thêm tiếng ồn vào xử lý âm thanh:

const audioMaskScript = `
    // Thêm tiếng ồn vào Audio Context
    const AudioContext = window.AudioContext || window.webkitAudioContext;
    if (AudioContext) {
        const originalCreateAnalyser = AudioContext.prototype.createAnalyser;
        AudioContext.prototype.createAnalyser = function() {
            const analyser = originalCreateAnalyser.call(this);
            const originalGetFloatFrequencyData = analyser.getFloatFrequencyData;
            analyser.getFloatFrequencyData = function(array) {
                originalGetFloatFrequencyData.call(this, array);
                // Thêm tiếng ồn tối thiểu
                for (let i = 0; i < array.length; i++) {
                    array[i] += Math.random() * 0.0001;
                }
            };
            return analyser;
        };
    }
`;

Mô phỏng hành vi con người

Ngay cả với việc che giấu kỹ thuật hoàn hảo, bot vẫn có thể tự lộ diện qua hành vi. Các hệ thống học máy phân tích các mẫu chuyển động chuột, tốc độ hành động và trình tự sự kiện.

Độ trễ ngẫu nhiên giữa các hành động

Không bao giờ sử dụng độ trễ cố định. Người dùng thực tạo ra các khoảng dừng với độ dài khác nhau:

import random
import time

def human_delay(min_seconds=1, max_seconds=3):
    """Độ trễ ngẫu nhiên mô phỏng con người"""
    delay = random.uniform(min_seconds, max_seconds)
    time.sleep(delay)

# Sử dụng
driver.get('https://example.com')
human_delay(2, 4)  # Dừng 2-4 giây

element = driver.find_element(By.ID, 'search')
human_delay(0.5, 1.5)  # Độ dừng ngắn trước khi nhập

element.send_keys('search query')
human_delay(1, 2)

Chuyển động chuột mượt mà

Bot di chuyển chuột theo các đường thẳng hoặc dịch chuyển con trỏ. Người dùng thực tạo ra các quỹ đạo cong với gia tốc và giảm tốc:

// Puppeteer: chuyển động chuột mượt mà
async function humanMouseMove(page, targetX, targetY) {
    const steps = 25; // Số lượng điểm trung gian
    const currentPos = await page.evaluate(() => ({
        x: window.mouseX || 0,
        y: window.mouseY || 0
    }));
    
    for (let i = 0; i <= steps; i++) {
        const t = i / steps;
        // Sử dụng easing để mượt mà
        const ease = t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t;
        
        const x = currentPos.x + (targetX - currentPos.x) * ease;
        const y = currentPos.y + (targetY - currentPos.y) * ease;
        
        await page.mouse.move(x, y);
        await page.waitForTimeout(Math.random() * 10 + 5);
    }
    
    // Lưu vị trí
    await page.evaluate((x, y) => {
        window.mouseX = x;
        window.mouseY = y;
    }, targetX, targetY);
}

// Sử dụng
await humanMouseMove(page, 500, 300);
await page.mouse.click(500, 300);

Cuộn tự nhiên

Người dùng thực cuộn một cách mượt mà, với các khoảng dừng để đọc nội dung:

async function humanScroll(page) {
    const scrollHeight = await page.evaluate(() => document.body.scrollHeight);
    const viewportHeight = await page.evaluate(() => window.innerHeight);
    
    let currentPosition = 0;
    
    while (currentPosition < scrollHeight - viewportHeight) {
        // Bước cuộn ngẫu nhiên (200-500px)
        const scrollStep = Math.floor(Math.random() * 300) + 200;
        currentPosition += scrollStep;
        
        // Cuộn mượt mà
        await page.evaluate((pos) => {
            window.scrollTo({
                top: pos,
                behavior: 'smooth'
            });
        }, currentPosition);
        
        // Dừng để "đọc" nội dung (1-3 giây)
        await page.waitForTimeout(Math.random() * 2000 + 1000);
    }
}

// Sử dụng
await page.goto('https://example.com');
await humanScroll(page);

Nhập văn bản tự nhiên

Con người gõ với tốc độ khác nhau, mắc lỗi và sửa chữa chúng:

async function humanTypeText(page, selector, text) {
    await page.click(selector);
    
    for (let char of text) {
        // Độ trễ ngẫu nhiên giữa các lần nhấn (50-200ms)
        const delay = Math.random() * 150 + 50;
        await page.waitForTimeout(delay);
        
        // 5% cơ hội mắc lỗi
        if (Math.random() < 0.05) {
            // Gõ một ký tự ngẫu nhiên
            const wrongChar = String.fromCharCode(97 + Math.floor(Math.random() * 26));
            await page.keyboard.type(wrongChar);
            await page.waitForTimeout(100 + Math.random() * 100);
            // Xóa (Backspace)
            await page.keyboard.press('Backspace');
            await page.waitForTimeout(50 + Math.random() * 50);
        }
        
        await page.keyboard.type(char);
    }
}

// Sử dụng
await humanTypeText(page, '#search-input', 'example search query');

Tích hợp proxy để hoàn toàn ẩn danh

Che giấu trình duyệt là vô nghĩa nếu tất cả các yêu cầu đến từ một địa chỉ IP duy nhất. Các hệ thống chống bot theo dõi số lượng yêu cầu từ mỗi IP và chặn hoạt động nghi ngờ. Proxy là một thành phần bắt buộc của bất kỳ tự động hóa nghiêm túc nào.

Lựa chọn loại proxy

Các nhiệm vụ khác nhau yêu cầu các loại proxy khác nhau:

Loại proxy Lợi ích Ứng dụng
Địa chỉ IP tĩnh Đáng tin cậy và ổn định Tự động hóa lâu dài
Địa chỉ IP động Chi phí thấp hơn Tự động hóa ngắn hạn
Proxy trung gian Che giấu địa chỉ IP thực Tự động hóa ẩn danh
```