Kembali ke blog

Cara Menghindari Deteksi Browser Headless saat Parsing: Penyamaran Selenium dan Puppeteer

Pelajari cara mengatasi perlindungan dari browser headless saat melakukan parsing: teknik penyamaran Selenium, Puppeteer, dan Playwright dengan contoh kode dan pengaturan proxy.

📅10 Januari 2026
```html

Situs modern telah belajar mengenali browser otomatis (Selenium, Puppeteer, Playwright) dan memblokir permintaan mereka. Browser headless meninggalkan puluhan jejak digital, yang digunakan sistem anti-bot untuk mendeteksi otomatisasi dalam milisekon. Dalam panduan ini, kita akan membahas semua metode penyamaran browser headless dengan contoh kode dalam Python dan JavaScript, agar parser Anda dapat berfungsi secara stabil tanpa pemblokiran.

Artikel ini ditujukan untuk pengembang yang terlibat dalam web scraping, otomatisasi pengujian, atau pengumpulan data dari situs yang dilindungi. Kita akan membahas rincian teknis deteksi dan solusi praktis untuk menghindari perlindungan.

Cara situs mendeteksi browser headless: metode utama

Sistem anti-bot menggunakan pemeriksaan multi-level pada browser, menganalisis ratusan parameter. Browser headless berbeda dari yang biasa dalam banyak tanda yang tidak dapat disembunyikan hanya dengan mengganti User-Agent. Memahami metode deteksi adalah langkah pertama menuju penyamaran yang efektif.

Penanda JavaScript otomatisasi

Metode yang paling umum adalah memeriksa properti JavaScript yang hanya muncul di browser otomatis:

  • navigator.webdriver — mengembalikan true di Selenium dan Puppeteer
  • window.chrome — tidak ada di Chrome headless
  • navigator.plugins.length — sama dengan 0 dalam mode headless
  • navigator.languages — sering kali array kosong atau hanya berisi "en-US"
  • navigator.permissions — API berfungsi berbeda dalam mode headless

Analisis Protokol Chrome DevTools

Puppeteer dan Playwright mengelola browser melalui Protokol Chrome DevTools (CDP). Keberadaan koneksi CDP dapat terdeteksi melalui pemeriksaan JavaScript khusus yang menganalisis objek window.cdc_ atau memeriksa anomali dalam perilaku peristiwa mouse dan keyboard.

Canvas dan WebGL Fingerprinting

Browser headless menghasilkan jejak Canvas dan WebGL yang identik, karena menggunakan rendering perangkat lunak alih-alih perangkat keras. Sistem anti-bot membuat elemen Canvas yang tidak terlihat, menggambar teks atau bentuk di atasnya, dan menghitung hash gambar. Jika ribuan pengguna memiliki hash yang identik — itu adalah tanda bot.

Analisis perilaku

Sistem modern (DataDome, PerimeterX, Cloudflare Bot Management) menganalisis gerakan mouse, kecepatan scroll, pola klik. Browser headless melakukan tindakan secara instan dan tanpa penundaan alami, yang mengungkapkan otomatisasi. Peristiwa juga dianalisis: di browser biasa, sebelum mengklik selalu terjadi peristiwa mousemove, sedangkan bot sering mengklik tanpa gerakan mouse sebelumnya.

Penting: Sistem anti-bot modern menggunakan pembelajaran mesin untuk menganalisis ratusan parameter secara bersamaan. Menyamarkan hanya satu parameter (misalnya, User-Agent) tidak akan melindungi dari pemblokiran — pendekatan komprehensif diperlukan.

Menghapus navigator.webdriver dan penanda JavaScript lainnya

Properti navigator.webdriver adalah cara paling sederhana untuk mendeteksi Selenium dan alat WebDriver lainnya. Di browser biasa, properti ini mengembalikan undefined, sedangkan di browser otomatis — true. Ini dapat dihapus dengan menjalankan kode JavaScript sebelum memuat halaman.

Selenium (Python): menghapus webdriver melalui CDP

Untuk Selenium, Anda perlu menggunakan Protokol Chrome DevTools untuk menjalankan JavaScript sebelum memuat halaman apa pun:

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

options = Options()
options.add_argument('--disable-blink-features=AutomationControlled')

driver = webdriver.Chrome(options=options)

# Menghapus navigator.webdriver melalui CDP
driver.execute_cdp_cmd('Page.addScriptToEvaluateOnNewDocument', {
    'source': '''
        Object.defineProperty(navigator, 'webdriver', {
            get: () => undefined
        });
    '''
})

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

Opsi --disable-blink-features=AutomationControlled menonaktifkan bendera yang ditambahkan Chrome dalam mode otomatisasi. Ini adalah perlindungan dasar yang perlu dikombinasikan dengan metode lainnya.

Puppeteer (Node.js): penyamaran melalui Page.evaluateOnNewDocument

Di Puppeteer, metode page.evaluateOnNewDocument() digunakan untuk menjalankan kode sebelum memuat halaman:

const puppeteer = require('puppeteer');

(async () => {
    const browser = await puppeteer.launch({
        headless: true,
        args: ['--disable-blink-features=AutomationControlled']
    });
    
    const page = await browser.newPage();
    
    // Menghapus webdriver dan penanda lainnya
    await page.evaluateOnNewDocument(() => {
        Object.defineProperty(navigator, 'webdriver', {
            get: () => undefined
        });
        
        // Menambahkan objek chrome
        window.chrome = {
            runtime: {}
        };
        
        // Emulasi plugin
        Object.defineProperty(navigator, 'plugins', {
            get: () => [1, 2, 3, 4, 5]
        });
    });
    
    await page.goto('https://example.com');
})();

Playwright: opsi penyamaran bawaan

Playwright memiliki penyamaran yang lebih canggih dari bawaan, tetapi pengaturan tambahan tetap diperlukan:

const { chromium } = require('playwright');

(async () => {
    const browser = await chromium.launch({
        headless: true,
        args: ['--disable-blink-features=AutomationControlled']
    });
    
    const context = await browser.newContext({
        userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
    });
    
    const page = await context.newPage();
    
    await page.addInitScript(() => {
        Object.defineProperty(navigator, 'webdriver', {
            get: () => undefined
        });
    });
    
    await page.goto('https://example.com');
})();

Menyamarkan Protokol Chrome DevTools

Puppeteer dan Playwright meninggalkan jejak koneksi CDP yang dapat terdeteksi melalui analisis objek window. Sistem anti-bot mencari variabel dengan awalan cdc_, $cdc_ atau __webdriver_, yang dibuat oleh Chrome saat terhubung melalui Protokol DevTools.

Menghapus variabel CDP

Skrip berikut menghapus semua variabel yang terkait dengan otomatisasi dari objek window:

await page.evaluateOnNewDocument(() => {
    // Menghapus semua variabel dengan awalan cdc_
    const cdcProps = Object.keys(window).filter(prop => 
        prop.includes('cdc_') || 
        prop.includes('$cdc_') || 
        prop.includes('__webdriver_')
    );
    
    cdcProps.forEach(prop => {
        delete window[prop];
    });
    
    // Mengganti document.__proto__ untuk menyembunyikan CDP
    const originalQuery = document.querySelector;
    document.querySelector = function(selector) {
        if (selector.includes('cdc_')) return null;
        return originalQuery.call(this, selector);
    };
});

Menggunakan versi Chromium yang dipatch

Ada build Chromium yang dimodifikasi yang tidak meninggalkan jejak CDP. Misalnya, pustaka puppeteer-extra dengan plugin puppeteer-extra-plugin-stealth secara otomatis menerapkan puluhan patch untuk menyamarkan CDP.

Pengaturan User-Agent dan header HTTP

Browser headless menggunakan string User-Agent yang usang atau tidak realistis. Misalnya, Puppeteer secara default menambahkan kata "HeadlessChrome" ke User-Agent. Selain itu, perlu mengatur header tambahan yang ada dalam permintaan browser biasa.

User-Agent yang relevan untuk penyamaran

Gunakan User-Agent terbaru dari browser nyata. Berikut adalah contoh untuk tahun 2024:

# Chrome 120 di Windows 10
Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36

# Chrome 120 di macOS
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

# Firefox 121 di Windows
Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:121.0) Gecko/20100101 Firefox/121.0

Pengaturan header di Selenium

from selenium.webdriver.chrome.options import Options

options = Options()
options.add_argument('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')

# Header tambahan melalui CDP
driver.execute_cdp_cmd('Network.setUserAgentOverride', {
    "userAgent": 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
    "platform": 'Win32',
    "acceptLanguage": 'en-US,en;q=0.9'
})

Pengaturan header di Puppeteer

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');

await page.setExtraHTTPHeaders({
    'Accept-Language': 'en-US,en;q=0.9',
    'Accept-Encoding': 'gzip, deflate, br',
    'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
    'Sec-Fetch-Site': 'none',
    'Sec-Fetch-Mode': 'navigate',
    'Sec-Fetch-User': '?1',
    'Sec-Fetch-Dest': 'document'
});

Header Sec-Fetch-* sangat penting — mereka muncul di Chrome 76+ dan ketidakadaan mereka mengungkapkan versi browser yang lebih lama atau bot.

Emulasi Canvas dan WebGL Fingerprint

Canvas dan WebGL fingerprinting adalah metode deteksi yang kuat, karena browser headless menghasilkan jejak yang identik. Sistem anti-bot membuat Canvas yang tidak terlihat, menggambar teks di atasnya, dan menghitung hash piksel. Jika ribuan permintaan memiliki hash yang sama — itu adalah bot.

Menambahkan noise ke Canvas

Skrip berikut menambahkan noise acak ke jejak Canvas, menjadikan setiap permintaan unik:

await page.evaluateOnNewDocument(() => {
    const originalToDataURL = HTMLCanvasElement.prototype.toDataURL;
    const originalToBlob = HTMLCanvasElement.prototype.toBlob;
    const originalGetImageData = CanvasRenderingContext2D.prototype.getImageData;
    
    // Fungsi menambahkan noise
    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) {
            imageData.data[i] += Math.floor(Math.random() * 10) - 5;
            imageData.data[i + 1] += Math.floor(Math.random() * 10) - 5;
            imageData.data[i + 2] += Math.floor(Math.random() * 10) - 5;
        }
        context.putImageData(imageData, 0, 0);
    };
    
    HTMLCanvasElement.prototype.toDataURL = function() {
        addNoise(this, this.getContext('2d'));
        return originalToDataURL.apply(this, arguments);
    };
});

Emulasi parameter WebGL

WebGL mengungkapkan informasi tentang kartu grafis dan driver. Dalam mode headless, parameter ini mengungkapkan rendering perangkat lunak:

await page.evaluateOnNewDocument(() => {
    const getParameter = WebGLRenderingContext.prototype.getParameter;
    WebGLRenderingContext.prototype.getParameter = function(parameter) {
        // Emulasi kartu grafis yang nyata
        if (parameter === 37445) {
            return 'Intel Inc.';
        }
        if (parameter === 37446) {
            return 'Intel Iris OpenGL Engine';
        }
        return getParameter.call(this, parameter);
    };
});

Parameter 37445 adalah UNMASKED_VENDOR_WEBGL, dan 37446 adalah UNMASKED_RENDERER_WEBGL. Dalam mode headless, mereka mengembalikan "Google SwiftShader", yang mengungkapkan otomatisasi.

Selenium Stealth: solusi siap pakai untuk Python

Pustaka selenium-stealth secara otomatis menerapkan puluhan patch untuk menyamarkan Selenium. Ini adalah solusi paling sederhana untuk pengembang Python yang tidak memerlukan pengaturan manual untuk setiap parameter.

Instalasi dan pengaturan dasar

pip install selenium-stealth
from selenium import webdriver
from selenium_stealth import stealth
from selenium.webdriver.chrome.options import Options

options = Options()
options.add_argument("--headless")
options.add_argument("--no-sandbox")
options.add_argument("--disable-dev-shm-usage")

driver = webdriver.Chrome(options=options)

# Menerapkan patch stealth
stealth(driver,
    languages=["en-US", "en"],
    vendor="Google Inc.",
    platform="Win32",
    webgl_vendor="Intel Inc.",
    renderer="Intel Iris OpenGL Engine",
    fix_hairline=True,
)

driver.get("https://bot.sannysoft.com")
driver.save_screenshot("test.png")

Pustaka ini secara otomatis menghapus navigator.webdriver, menambahkan window.chrome, mensimulasikan plugin, menyamarkan WebGL, dan menerapkan lebih dari 20 patch lainnya. Ini mencakup 80% kasus deteksi.

Pengaturan lanjutan dengan proxy

Untuk penyamaran penuh, gabungkan selenium-stealth dengan proxy residensial — mereka menyediakan alamat IP nyata dari pengguna rumah, yang sangat penting untuk menghindari sistem anti-bot yang canggih:

from selenium.webdriver.common.proxy import Proxy, ProxyType

proxy = Proxy()
proxy.proxy_type = ProxyType.MANUAL
proxy.http_proxy = "ip:port"
proxy.ssl_proxy = "ip:port"

capabilities = webdriver.DesiredCapabilities.CHROME
proxy.add_to_capabilities(capabilities)

driver = webdriver.Chrome(desired_capabilities=capabilities, options=options)
stealth(driver, languages=["en-US", "en"], vendor="Google Inc.", platform="Win32")

Puppeteer Extra Stealth Plugin untuk Node.js

Untuk Puppeteer, ada plugin puppeteer-extra-plugin-stealth, yang merupakan solusi paling canggih untuk menyamarkan browser headless dalam ekosistem JavaScript. Ini berisi 23 modul independen, masing-masing menyamarkan aspek tertentu dari otomatisasi.

Instalasi dan penggunaan dasar

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

puppeteer.use(StealthPlugin());

(async () => {
    const browser = await puppeteer.launch({ 
        headless: true,
        args: ['--no-sandbox', '--disable-setuid-sandbox']
    });
    
    const page = await browser.newPage();
    await page.goto('https://bot.sannysoft.com');
    await page.screenshot({ path: 'test.png' });
    await browser.close();
})();

Apa yang disamarkan oleh Stealth Plugin

Plugin ini secara otomatis menerapkan patch berikut:

  • Menghapus navigator.webdriver
  • Menambahkan objek window.chrome
  • Emulasi API navigator.permissions
  • Menyamarkan navigator.plugins dan navigator.mimeTypes
  • Emulasi Canvas dan WebGL fingerprint
  • Menyamarkan User-Agent dan bahasa
  • Memperbaiki anomali dalam iframe contentWindow
  • Emulasi Battery API, Media Devices, WebRTC

Pengaturan dengan proxy dan parameter tambahan

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

puppeteer.use(StealthPlugin());
puppeteer.use(AdblockerPlugin({ blockTrackers: true }));

(async () => {
    const browser = await puppeteer.launch({
        headless: true,
        args: [
            '--proxy-server=http://your-proxy:port',
            '--disable-web-security',
            '--disable-features=IsolateOrigins,site-per-process'
        ]
    });
    
    const page = await browser.newPage();
    
    // Autentikasi proxy
    await page.authenticate({
        username: 'your-username',
        password: 'your-password'
    });
    
    await page.setViewport({ width: 1920, height: 1080 });
    await page.goto('https://example.com', { waitUntil: 'networkidle2' });
})();

Playwright: pengaturan anti-deteksi

Playwright memiliki arsitektur yang lebih canggih dibandingkan dengan Puppeteer dan meninggalkan jejak otomatisasi yang lebih sedikit. Namun, untuk menghindari sistem anti-bot yang canggih, pengaturan tambahan diperlukan. Untuk Playwright, ada port plugin stealth — playwright-extra.

Instalasi playwright-extra

npm install playwright-extra playwright-extra-plugin-stealth playwright
const { chromium } = require('playwright-extra');
const stealth = require('playwright-extra-plugin-stealth');

chromium.use(stealth());

(async () => {
    const browser = await chromium.launch({ headless: true });
    const context = await browser.newContext({
        userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
        viewport: { width: 1920, height: 1080 },
        locale: 'en-US',
        timezoneId: 'America/New_York'
    });
    
    const page = await context.newPage();
    await page.goto('https://bot.sannysoft.com');
    await page.screenshot({ path: 'test.png' });
    await browser.close();
})();

Pengaturan konteks browser untuk penyamaran maksimal

Playwright memungkinkan pembuatan konteks browser yang terisolasi dengan pengaturan individu. Ini berguna untuk multi-akun atau parsing paralel:

const context = await browser.newContext({
    userAgent: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36',
    viewport: { width: 1440, height: 900 },
    locale: 'en-US',
    timezoneId: 'America/Los_Angeles',
    permissions: ['geolocation'],
    geolocation: { latitude: 37.7749, longitude: -122.4194 },
    colorScheme: 'light',
    deviceScaleFactor: 2,
    isMobile: false,
    hasTouch: false,
    // Pengaturan proxy untuk konteks
    proxy: {
        server: 'http://your-proxy:port',
        username: 'user',
        password: 'pass'
    }
});

Parameter geolocation dan timezoneId harus sesuai dengan alamat IP proxy, jika tidak, sistem anti-bot akan mendeteksi ketidakcocokan (misalnya, IP dari California, tetapi timezone New York).

Rotasi proxy untuk mengurangi risiko pemblokiran

Bahkan browser headless yang disamarkan dengan sempurna dapat diblokir jika menggunakan satu alamat IP untuk ratusan permintaan. Sistem anti-bot modern menganalisis frekuensi permintaan dari satu IP dan memblokir aktivitas yang mencurigakan. Rotasi proxy adalah elemen perlindungan yang wajib saat melakukan parsing.

Jenis proxy untuk parsing: perbandingan

Jenis proxy Kecepatan Trust Score Lebih baik untuk
Datacenter Sangat tinggi (50-200 ms) Rendah Situs sederhana, parsing massal
Residen Sedang (300-1000 ms) Tinggi Situs yang dilindungi, media sosial
Mobile Rendah (500-2000 ms) Sangat tinggi Aplikasi mobile, Instagram, TikTok

Untuk parsing situs yang dilindungi (marketplace, media sosial, platform iklan), disarankan menggunakan proxy residensial, karena mereka memiliki IP nyata dari pengguna rumah dan tidak masuk dalam daftar hitam sistem anti-bot.

Implementasi rotasi proxy di Puppeteer

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

puppeteer.use(StealthPlugin());

const proxyList = [
    'http://user1:pass1@proxy1:port',
    'http://user2:pass2@proxy2:port',
    'http://user3:pass3@proxy3:port'
];

async function scrapeWithRotation(urls) {
    for (let i = 0; i < urls.length; i++) {
        const proxy = proxyList[i % proxyList.length];
        
        const browser = await puppeteer.launch({
            headless: true,
            args: [`--proxy-server=${proxy}`]
        });
        
        const page = await browser.newPage();
        
        try {
            await page.goto(urls[i], { waitUntil: 'networkidle2' });
            const data = await page.evaluate(() => document.body.innerText);
            console.log(data);
        } catch (error) {
            console.error(`Error on ${urls[i]}:`, error);
        } finally {
            await browser.close();
        }
        
        // Delay antara permintaan
        await new Promise(resolve => setTimeout(resolve, 2000));
    }
}

scrapeWithRotation([
    'https://example1.com',
    'https://example2.com',
    'https://example3.com'
]);

Rotasi melalui proxy berbasis sesi

Beberapa penyedia proxy (termasuk ProxyCove) menawarkan rotasi berbasis sesi — setiap permintaan secara otomatis mendapatkan IP baru tanpa perlu memulai ulang browser. Ini diimplementasikan melalui format URL proxy khusus:

// Format: username-session-RANDOM:password@gateway:port
const generateSessionProxy = () => {
    const sessionId = Math.random().toString(36).substring(7);
    return `http://username-session-${sessionId}:password@gateway.proxycove.com:12321`;
};

const browser = await puppeteer.launch({
    args: [`--proxy-server=${generateSessionProxy()}`]
});

Cara memeriksa kualitas penyamaran: alat pengujian

Setelah mengatur penyamaran, perlu untuk memeriksa seberapa baik browser headless Anda meniru pengguna biasa. Ada beberapa situs khusus yang menganalisis puluhan parameter browser dan menunjukkan jejak otomatisasi yang tersisa.

Alat pengujian utama

  • bot.sannysoft.com — memeriksa lebih dari 15 parameter deteksi, termasuk webdriver, objek Chrome, plugin, Canvas
  • arh.antoinevastel.com/bots/areyouheadless — berspesialisasi dalam mendeteksi Chrome headless
  • pixelscan.net — analisis fingerprint yang canggih dengan visualisasi semua parameter
  • abrahamjuliot.github.io/creepjs — analisis paling mendetail (200+ parameter), menunjukkan tingkat kepercayaan browser
  • iphey.com — memeriksa alamat IP untuk kepemilikan proxy dan VPN

Otomatisasi pengujian

Buat skrip untuk memeriksa penyamaran secara otomatis setelah setiap perubahan pengaturan:

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

puppeteer.use(StealthPlugin());

async function testStealth() {
    const browser = await puppeteer.launch({ headless: true });
    const page = await browser.newPage();
    
    // Tes 1: Sannysoft
    await page.goto('https://bot.sannysoft.com');
    await page.screenshot({ path: 'test-sannysoft.png', fullPage: true });
    
    // Tes 2: Apakah Anda headless
    await page.goto('https://arh.antoinevastel.com/bots/areyouheadless');
    const headlessDetected = await page.evaluate(() => {
        return document.body.innerText.includes('You are not Chrome headless');
    });
    console.log('Headless terdeteksi:', !headlessDetected);
    
    // Tes 3: Properti Webdriver
    const webdriverPresent = await page.evaluate(() => navigator.webdriver);
    console.log('navigator.webdriver:', webdriverPresent);
    
    // Tes 4: Objek Chrome
    const chromePresent = await page.evaluate(() => !!window.chrome);
    console.log('window.chrome ada:', chromePresent);
    
    await browser.close();
}

testStealth();

Daftar periksa penyamaran yang berhasil

Browser headless Anda disamarkan dengan benar jika:

  • navigator.webdriver mengembalikan undefined
  • window.chrome ada dan berisi objek runtime
  • navigator.plugins.length lebih dari 0
  • Vendor dan renderer WebGL menunjukkan kartu grafis yang nyata, bukan SwiftShader
  • Fingerprint Canvas unik untuk setiap sesi
  • User-Agent sesuai dengan versi terbaru Chrome/Firefox
  • Alamat IP proxy tidak ada dalam daftar hitam (periksa melalui iphey.com)
  • Timezone dan locale sesuai dengan geolokasi alamat IP

Kesimpulan

Menyamarkan browser headless adalah tugas yang kompleks, memerlukan perhatian pada puluhan parameter. Sistem anti-bot modern menggunakan pembelajaran mesin dan menganalisis ratusan karakteristik browser secara bersamaan, sehingga penggantian User-Agent yang sederhana tidak lagi efektif. Untuk parsing yang sukses, perlu menggabungkan beberapa metode perlindungan.

Elemen utama dari penyamaran yang efektif: menghapus penanda otomatisasi JavaScript (navigator.webdriver, variabel CDP), emulasi Canvas dan WebGL fingerprint, pengaturan header HTTP yang realistis, dan penggunaan proxy berkualitas. Solusi siap pakai (selenium-stealth untuk Python, puppeteer-extra-plugin-stealth untuk Node.js) mencakup 80% kasus, tetapi untuk menghindari perlindungan yang canggih, pengaturan tambahan diperlukan.

Poin yang sangat penting adalah pemilihan proxy. Bahkan browser yang disamarkan dengan sempurna akan diblokir jika menggunakan alamat IP dari daftar hitam atau melakukan terlalu banyak permintaan dari satu IP. Untuk parsing situs yang dilindungi, kami merekomendasikan menggunakan proxy residensial dengan rotasi otomatis — mereka memberikan skor kepercayaan yang tinggi dan risiko pemblokiran yang minimal, karena menggunakan IP nyata dari pengguna rumah alih-alih alamat server.

Secara teratur uji kualitas penyamaran melalui layanan khusus (bot.sannysoft.com, pixelscan.net) dan sesuaikan pengaturan dengan perubahan dalam sistem anti-bot. Parsing adalah perlombaan senjata yang terus menerus antara pengembang bot dan pencipta perlindungan, sehingga konfigurasi yang berfungsi hari ini mungkin memerlukan pembaruan dalam beberapa bulan ke depan.

```