Panduan Lengkap untuk Menyamarkan Selenium dan Puppeteer dari Deteksi
Sistem perlindungan anti-bot modern dengan mudah mengenali browser otomatisasi berdasarkan puluhan tanda: dari variabel JavaScript hingga karakteristik perilaku WebDriver. Situs web menggunakan Cloudflare, DataDome, PerimeterX, dan solusi mereka sendiri yang memblokir hingga 90% permintaan dari Selenium dan Puppeteer dalam konfigurasi standar.
Dalam panduan ini, kita akan membahas semua metode penyamaran otomatisasi: dari pengaturan dasar hingga teknik lanjutan untuk menghindari deteksi. Anda akan mendapatkan solusi siap pakai dengan contoh kode untuk Python dan Node.js yang bekerja melawan sebagian besar sistem perlindungan.
Bagaimana situs mendeteksi otomatisasi
Sistem perlindungan anti-bot menganalisis browser berdasarkan banyak parameter secara bersamaan. Bahkan jika Anda menyembunyikan satu tanda, yang lainnya akan mengungkapkan otomatisasi. Memahami semua metode deteksi adalah kunci untuk penyamaran yang efektif.
Indikator WebDriver
Metode paling sederhana untuk mendeteksi adalah dengan memeriksa variabel JavaScript yang hanya ada di browser otomatisasi:
// Variabel ini mengungkapkan Selenium/Puppeteer
navigator.webdriver === true
window.navigator.webdriver === true
document.$cdc_ // Variabel spesifik ChromeDriver
window.document.documentElement.getAttribute("webdriver")
navigator.plugins.length === 0 // Browser otomatisasi tidak memiliki plugin
navigator.languages === "" // Daftar bahasa kosong
Cloudflare dan sistem serupa memeriksa properti ini terlebih dahulu. Jika salah satu dari mereka mengembalikan hasil positif — permintaan akan diblokir.
Fingerprinting Browser
Sistem canggih membuat sidik jari unik browser berdasarkan puluhan parameter:
- Canvas Fingerprinting — merender gambar tersembunyi dan menganalisis data piksel
- WebGL Fingerprinting — parameter renderer grafis dan kartu grafis
- Audio Context — karakteristik unik pemrosesan audio
- Fonts Fingerprinting — daftar font yang terpasang di sistem
- Screen Resolution — resolusi layar, kedalaman warna, area yang tersedia
- Timezone & Language — zona waktu, bahasa browser, lokal sistem
Browser otomatisasi sering memiliki kombinasi parameter yang tidak biasa. Misalnya, Headless Chrome tidak memiliki plugin, tetapi mendukung WebGL — kombinasi seperti itu sangat jarang ditemukan pada pengguna nyata.
Analisis Perilaku
Sistem modern melacak pola perilaku:
- Gerakan mouse — bot menggerakkan kursor dalam garis lurus atau tidak bergerak sama sekali
- Kecepatan tindakan — pengisian formulir instan, kecepatan klik yang tidak manusiawi
- Pola scrolling — lompatan tajam alih-alih scrolling yang halus
- Peristiwa keyboard — tidak ada jeda alami antara penekanan
- Frekuensi permintaan — interval yang terlalu teratur antara tindakan
Penting: DataDome dan PerimeterX menggunakan pembelajaran mesin untuk menganalisis perilaku. Mereka dilatih pada jutaan sesi dan dapat mengenali bot bahkan dengan penyamaran parameter teknis yang benar, jika perilakunya terlihat tidak alami.
Penyamaran Dasar Selenium
Selenium WebDriver dalam konfigurasi standar meninggalkan banyak jejak. Mari kita lihat pengaturan langkah demi langkah untuk meminimalkan deteksi dengan contoh Python dan ChromeDriver.
Menonaktifkan Flag WebDriver
Langkah pertama adalah menyembunyikan variabel navigator.webdriver. Ini dilakukan melalui Chrome DevTools Protocol:
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.chrome.options import Options
# Mengatur opsi Chrome
chrome_options = Options()
# Menonaktifkan flag otomatisasi
chrome_options.add_experimental_option("excludeSwitches", ["enable-automation"])
chrome_options.add_experimental_option('useAutomationExtension', False)
# Membuat driver
driver = webdriver.Chrome(options=chrome_options)
# Menghapus webdriver melalui CDP
driver.execute_cdp_cmd('Page.addScriptToEvaluateOnNewDocument', {
'source': '''
Object.defineProperty(navigator, 'webdriver', {
get: () => undefined
})
'''
})
driver.get('https://example.com')
Mengatur User-Agent dan Header Lainnya
Browser headless sering menggunakan string User-Agent yang usang atau spesifik. Anda perlu mengatur User-Agent yang relevan dari browser nyata:
# User-Agent Chrome yang relevan di 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}')
# Argumen tambahan untuk penyamaran
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')
# Ukuran jendela seperti pengguna nyata
chrome_options.add_argument('--window-size=1920,1080')
chrome_options.add_argument('--start-maximized')
Menambahkan Plugin dan Bahasa
Browser otomatisasi tidak memiliki plugin dan sering menunjukkan daftar bahasa yang kosong. Kita bisa memperbaikinya melalui 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'
});
'''
})
Contoh Lengkap Pengaturan Selenium
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
import random
def create_stealth_driver():
chrome_options = Options()
# Pengaturan dasar penyamaran
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}')
# Ukuran jendela
chrome_options.add_argument('--window-size=1920,1080')
chrome_options.add_argument('--start-maximized')
driver = webdriver.Chrome(options=chrome_options)
# Skrip penyamaran melalui 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
# Penggunaan
driver = create_stealth_driver()
driver.get('https://bot.sannysoft.com/') # Situs untuk memeriksa deteksi
Pengaturan Puppeteer untuk menghindari deteksi
Puppeteer memiliki masalah deteksi yang sama dengan Selenium. Namun, untuk Node.js ada perpustakaan siap pakai puppeteer-extra-plugin-stealth yang mengotomatiskan sebagian besar pengaturan penyamaran.
Instalasi puppeteer-extra
npm install puppeteer puppeteer-extra puppeteer-extra-plugin-stealth
Konfigurasi Dasar dengan Plugin Stealth
const puppeteer = require('puppeteer-extra');
const StealthPlugin = require('puppeteer-extra-plugin-stealth');
// Menggunakan plugin penyamaran
puppeteer.use(StealthPlugin());
(async () => {
const browser = await puppeteer.launch({
headless: 'new', // Mode headless baru 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();
// Mengatur viewport
await page.setViewport({
width: 1920,
height: 1080,
deviceScaleFactor: 1
});
// Mengatur 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');
// Header tambahan
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/');
// Screenshot untuk pemeriksaan
await page.screenshot({ path: 'test.png' });
await browser.close();
})();
Pengaturan Manual Tanpa Plugin
Jika Anda ingin kontrol penuh atau tidak dapat menggunakan perpustakaan pihak ketiga, atur penyamaran secara manual:
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch({
headless: 'new',
args: ['--no-sandbox', '--disable-setuid-sandbox']
});
const page = await browser.newPage();
// Mengoverride webdriver dan properti lainnya
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]
});
// Menyamarkan Chrome headless
Object.defineProperty(navigator, 'platform', {
get: () => 'Win32'
});
window.chrome = {
runtime: {}
};
// Mengoverride 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();
})();
Pengaturan untuk Menghindari Cloudflare
Cloudflare menggunakan metode deteksi canggih. Untuk menghindarinya, perlu menambahkan jeda acak dan emulasi tindakan:
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 acak
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)]);
// Mengunjungi halaman
await page.goto(url, { waitUntil: 'networkidle2' });
// Menunggu pemeriksaan Cloudflare (biasanya 5-10 detik)
await page.waitForTimeout(8000);
// Gerakan mouse acak
await page.mouse.move(100, 100);
await page.mouse.move(200, 200);
const content = await page.content();
await browser.close();
return content;
}
Melawan JavaScript Fingerprinting
JavaScript fingerprinting adalah pembuatan sidik jari unik browser berdasarkan banyak parameter. Bahkan jika Anda menyembunyikan webdriver, sistem menganalisis ratusan properti lain untuk mengidentifikasi otomatisasi.
Vektor Utama Fingerprinting
Sistem perlindungan anti-bot memeriksa parameter berikut:
| Parameter | Apa yang Diperiksa | Risiko Deteksi |
|---|---|---|
| navigator.webdriver | Keberadaan flag otomatisasi | Kritis |
| navigator.plugins | Jumlah dan jenis plugin | Tinggi |
| window.chrome | Keberadaan API Chrome | Sedang |
| navigator.permissions | API izin browser | Sedang |
| screen.colorDepth | Kedalaman warna layar | Rendah |
| navigator.hardwareConcurrency | Jumlah inti prosesor | Rendah |
Skrip Penyamar Kompleks
Skrip di bawah ini mengoverride sebagian besar properti bermasalah. Terapkan melalui CDP (Selenium) atau evaluateOnNewDocument (Puppeteer):
const stealthScript = `
// Menghapus webdriver
Object.defineProperty(navigator, 'webdriver', {
get: () => undefined
});
// Menambahkan objek chrome
window.chrome = {
runtime: {},
loadTimes: function() {},
csi: function() {},
app: {}
};
// Mengoverride permissions
const originalQuery = window.navigator.permissions.query;
window.navigator.permissions.query = (parameters) => (
parameters.name === 'notifications' ?
Promise.resolve({ state: Notification.permission }) :
originalQuery(parameters)
);
// Menyamarkan plugin
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"
}
];
}
});
// Bahasa
Object.defineProperty(navigator, 'languages', {
get: () => ['en-US', 'en']
});
// Platform
Object.defineProperty(navigator, 'platform', {
get: () => 'Win32'
});
// Vendor
Object.defineProperty(navigator, 'vendor', {
get: () => 'Google Inc.'
});
// Menghapus jejak Selenium
delete window.cdc_adoQpoasnfa76pfcZLmcfl_Array;
delete window.cdc_adoQpoasnfa76pfcZLmcfl_Promise;
delete window.cdc_adoQpoasnfa76pfcZLmcfl_Symbol;
// Battery API (tidak ada di headless)
if (!navigator.getBattery) {
navigator.getBattery = () => Promise.resolve({
charging: true,
chargingTime: 0,
dischargingTime: Infinity,
level: 1
});
}
`;
Menghapus Properti WebDriver
ChromeDriver dan implementasi WebDriver lainnya menambahkan variabel spesifik ke ruang lingkup global. Variabel ini dimulai dengan awalan cdc_ dan mudah dideteksi oleh sistem perlindungan.
Deteksi Variabel cdc
Memeriksa keberadaan variabel ini dapat dilakukan dengan skrip sederhana:
// Mencari semua variabel cdc
for (let key in window) {
if (key.includes('cdc_')) {
console.log('Variabel WebDriver terdeteksi:', key);
}
}
// Variabel tipikal ChromeDriver:
// cdc_adoQpoasnfa76pfcZLmcfl_Array
// cdc_adoQpoasnfa76pfcZLmcfl_Promise
// cdc_adoQpoasnfa76pfcZLmcfl_Symbol
// $cdc_asdjflasutopfhvcZLmcfl_
Metode 1: Menghapus melalui CDP
Cara paling andal adalah menghapus variabel sebelum memuat halaman melalui Chrome DevTools Protocol:
from selenium import webdriver
driver = webdriver.Chrome()
# Menghapus semua variabel cdc
driver.execute_cdp_cmd('Page.addScriptToEvaluateOnNewDocument', {
'source': '''
// Menghapus variabel cdc yang diketahui
const cdcProps = [
'cdc_adoQpoasnfa76pfcZLmcfl_Array',
'cdc_adoQpoasnfa76pfcZLmcfl_Promise',
'cdc_adoQpoasnfa76pfcZLmcfl_Symbol',
'$cdc_asdjflasutopfhvcZLmcfl_'
];
cdcProps.forEach(prop => {
delete window[prop];
});
// Menghapus semua variabel yang mengandung 'cdc_'
Object.keys(window).forEach(key => {
if (key.includes('cdc_') || key.includes('$cdc_')) {
delete window[key];
}
});
'''
})
Metode 2: Modifikasi ChromeDriver
Pendekatan yang lebih radikal adalah mengubah file biner ChromeDriver, mengganti string cdc_ dengan urutan karakter lain. Ini mencegah pembuatan variabel tersebut:
import re
def patch_chromedriver(driver_path):
"""
Memperbaiki ChromeDriver, mengganti 'cdc_' dengan string acak
"""
with open(driver_path, 'rb') as f:
content = f.read()
# Mengganti semua kemunculan 'cdc_' dengan 'dog_' (atau string lain dengan panjang yang sama)
patched = content.replace(b'cdc_', b'dog_')
with open(driver_path, 'wb') as f:
f.write(patched)
print(f'ChromeDriver telah dipatch: {driver_path}')
# Penggunaan
patch_chromedriver('/path/to/chromedriver')
Perhatian: Modifikasi file biner ChromeDriver dapat merusak fungsinya. Selalu buat cadangan sebelum melakukan patch. Metode ini tidak berfungsi dengan semua versi ChromeDriver.
Metode 3: Menggunakan undetected-chromedriver
Perpustakaan undetected-chromedriver secara otomatis mempatch ChromeDriver saat dijalankan:
pip install undetected-chromedriver
import undetected_chromedriver as uc
# Membuat driver dengan pemrograman otomatis
driver = uc.Chrome()
driver.get('https://nowsecure.nl/') # Situs untuk memeriksa deteksi
input('Tekan Enter untuk menutup...')
driver.quit()
Menyamarkan Canvas, WebGL, dan Audio API
Canvas, WebGL, dan Audio Fingerprinting adalah metode untuk membuat sidik jari unik berdasarkan karakteristik rendering grafis dan pemrosesan suara. Setiap kombinasi browser, OS, dan perangkat keras memberikan hasil yang unik.
Canvas Fingerprinting
Sistem menggambar gambar tersembunyi pada Canvas dan menganalisis piksel yang dihasilkan. Browser headless sering memberikan hasil yang tidak biasa karena tidak adanya akselerasi GPU.
// Kode tipikal Canvas Fingerprinting
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
ctx.textBaseline = 'top';
ctx.font = '14px Arial';
ctx.fillText('Browser fingerprint', 2, 2);
const fingerprint = canvas.toDataURL();
Untuk perlindungan, Anda dapat menambahkan kebisingan acak ke API Canvas:
const canvasNoiseScript = `
// Menambahkan kebisingan acak ke Canvas
const originalToDataURL = HTMLCanvasElement.prototype.toDataURL;
const originalToBlob = HTMLCanvasElement.prototype.toBlob;
const originalGetImageData = CanvasRenderingContext2D.prototype.getImageData;
// Fungsi untuk menambahkan kebisingan
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) {
// Menambahkan kebisingan minimal ke RGB (tidak terlihat oleh mata)
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);
};
// Mengoverride 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 memberikan informasi tentang kartu grafis dan driver. Browser headless sering menunjukkan SwiftShader (renderer perangkat lunak) alih-alih GPU nyata:
const webglMaskScript = `
// Menyamarkan parameter 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);
};
// Juga untuk 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);
};
}
`;
Audio Context Fingerprinting
Audio API juga memberikan sidik jari unik. Tambahkan kebisingan ke pemrosesan audio:
const audioMaskScript = `
// Menambahkan kebisingan ke 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);
// Menambahkan kebisingan minimal
for (let i = 0; i < array.length; i++) {
array[i] += Math.random() * 0.0001;
}
};
return analyser;
};
}
`;
Meniru Perilaku Manusia
Bahkan dengan penyamaran teknis yang sempurna, bot mengungkapkan diri mereka melalui perilaku. Sistem pembelajaran mesin menganalisis pola gerakan mouse, kecepatan tindakan, dan urutan peristiwa.
Jeda Acak Antara Tindakan
Jangan pernah menggunakan jeda tetap. Pengguna nyata membuat jeda dengan durasi yang bervariasi:
import random
import time
def human_delay(min_seconds=1, max_seconds=3):
"""Jeda acak yang meniru manusia"""
delay = random.uniform(min_seconds, max_seconds)
time.sleep(delay)
# Penggunaan
driver.get('https://example.com')
human_delay(2, 4) # Jeda 2-4 detik
element = driver.find_element(By.ID, 'search')
human_delay(0.5, 1.5) # Jeda singkat sebelum memasukkan
element.send_keys('search query')
human_delay(1, 2)
Gerakan Mouse yang Halus
Bot menggerakkan mouse dalam garis lurus atau teleport kursor. Pengguna nyata menciptakan jalur melengkung dengan percepatan dan perlambatan:
// Puppeteer: gerakan mouse yang halus
async function humanMouseMove(page, targetX, targetY) {
const steps = 25; // Jumlah titik perantara
const currentPos = await page.evaluate(() => ({
x: window.mouseX || 0,
y: window.mouseY || 0
}));
for (let i = 0; i <= steps; i++) {
const t = i / steps;
// Menggunakan easing untuk kelancaran
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);
}
// Menyimpan posisi
await page.evaluate((x, y) => {
window.mouseX = x;
window.mouseY = y;
}, targetX, targetY);
}
// Penggunaan
await humanMouseMove(page, 500, 300);
await page.mouse.click(500, 300);
Scrolling yang Alami
Pengguna nyata menggulir dengan halus, dengan jeda untuk membaca konten:
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) {
// Langkah gulir acak (200-500px)
const scrollStep = Math.floor(Math.random() * 300) + 200;
currentPosition += scrollStep;
// Gulir halus
await page.evaluate((pos) => {
window.scrollTo({
top: pos,
behavior: 'smooth'
});
}, currentPosition);
// Jeda untuk "membaca" konten (1-3 detik)
await page.waitForTimeout(Math.random() * 2000 + 1000);
}
}
// Penggunaan
await page.goto('https://example.com');
await humanScroll(page);
Memasukkan Teks yang Alami
Orang mengetik dengan kecepatan yang bervariasi, membuat kesalahan ketik, dan memperbaikinya:
async function humanTypeText(page, selector, text) {
await page.click(selector);
for (let char of text) {
// Jeda acak antara penekanan (50-200ms)
const delay = Math.random() * 150 + 50;
await page.waitForTimeout(delay);
// 5% kemungkinan kesalahan ketik
if (Math.random() < 0.05) {
// Mengetik karakter acak
const wrongChar = String.fromCharCode(97 + Math.floor(Math.random() * 26));
await page.keyboard.type(wrongChar);
await page.waitForTimeout(100 + Math.random() * 100);
// Menghapus (Backspace)
await page.keyboard.press('Backspace');
await page.waitForTimeout(50 + Math.random() * 50);
}
await page.keyboard.type(char);
}
}
// Penggunaan
await humanTypeText(page, '#search-input', 'example search query');
Integrasi Proxy untuk Anonimitas Penuh
Menyamarkan browser tidak ada gunanya jika semua permintaan berasal dari satu alamat IP. Sistem perlindungan anti-bot melacak jumlah permintaan dari setiap IP dan memblokir aktivitas yang mencurigakan. Proxy adalah komponen wajib dari setiap otomatisasi serius.
Memilih Jenis Proxy
Tugas yang berbeda memerlukan jenis proxy yang berbeda:
| Jenis Proxy | Keuntungan | Penerapan |
|---|---|---|
| Proxy Residental | Tampak seperti pengguna nyata | Scraping, otomatisasi |
| Proxy Data Center | Cepat dan murah | Pengujian, scraping |
| Proxy Terbalik | Menyembunyikan alamat IP asli | Akses data, scraping |