Guia completo para mascarar Selenium e Puppeteer da detecção
Sistemas modernos de proteção contra bots reconhecem facilmente navegadores automatizados por dezenas de sinais: desde variáveis JavaScript até características do comportamento do WebDriver. Sites utilizam Cloudflare, DataDome, PerimeterX e soluções próprias que bloqueiam até 90% dos pedidos de Selenium e Puppeteer na configuração padrão.
Neste guia, vamos explorar todos os métodos de mascaramento da automação: desde configurações básicas até técnicas avançadas de contorno da detecção. Você receberá soluções prontas com exemplos de código para Python e Node.js que funcionam contra a maioria dos sistemas de proteção.
Como os sites detectam a automação
Sistemas de proteção contra bots analisam o navegador por múltiplos parâmetros ao mesmo tempo. Mesmo que você oculte um sinal, os outros revelarão a automação. Compreender todos os métodos de detecção é a chave para um mascaramento eficaz.
Indicadores do WebDriver
O método mais simples de detecção é verificar variáveis JavaScript que estão presentes apenas em navegadores automatizados:
// Essas variáveis revelam Selenium/Puppeteer
navigator.webdriver === true
window.navigator.webdriver === true
document.$cdc_ // Variável específica do ChromeDriver
window.document.documentElement.getAttribute("webdriver")
navigator.plugins.length === 0 // Navegadores automatizados não têm plugins
navigator.languages === "" // Lista de idiomas vazia
Cloudflare e sistemas semelhantes verificam essas propriedades em primeiro lugar. Se pelo menos uma retornar um resultado positivo — o pedido é bloqueado.
Fingerprinting do navegador
Sistemas avançados criam uma impressão digital única do navegador com base em dezenas de parâmetros:
- Canvas Fingerprinting — renderização de imagens ocultas e análise de dados de pixels
- WebGL Fingerprinting — parâmetros do renderizador gráfico e da placa de vídeo
- Audio Context — características únicas do processamento de áudio
- Fonts Fingerprinting — lista de fontes instaladas no sistema
- Screen Resolution — resolução da tela, profundidade de cor, área disponível
- Timezone & Language — fuso horário, idiomas do navegador, localidade do sistema
Navegadores automatizados frequentemente têm combinações não típicas desses parâmetros. Por exemplo, o Chrome sem cabeça não possui plugins, mas suporta WebGL — tal combinação é extremamente rara entre usuários reais.
Análise comportamental
Sistemas modernos rastreiam padrões de comportamento:
- Movimentos do mouse — bots movem o cursor em linhas retas ou não se movem de forma alguma
- Velocidade das ações — preenchimento instantâneo de formulários, velocidade de cliques não humana
- Padrões de rolagem — saltos bruscos em vez de rolagem suave
- Eventos de teclado — ausência de atrasos naturais entre as teclas pressionadas
- Frequência de pedidos — intervalos entre ações muito regulares
Importante: DataDome e PerimeterX utilizam aprendizado de máquina para analisar comportamentos. Eles foram treinados em milhões de sessões e podem reconhecer um bot mesmo com a mascaragem técnica correta, se o comportamento parecer não natural.
Mascaramento básico do Selenium
O Selenium WebDriver na configuração padrão deixa muitos rastros. Vamos considerar uma configuração passo a passo para minimizar a detecção usando Python e ChromeDriver.
Desativando o sinalizador do webdriver
O primeiro passo é ocultar a variável navigator.webdriver. Isso é feito através do Chrome DevTools Protocol:
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.chrome.options import Options
# Configuração das opções do Chrome
chrome_options = Options()
# Desativando o sinalizador de automação
chrome_options.add_experimental_option("excludeSwitches", ["enable-automation"])
chrome_options.add_experimental_option('useAutomationExtension', False)
# Criando o driver
driver = webdriver.Chrome(options=chrome_options)
# Removendo o webdriver através do CDP
driver.execute_cdp_cmd('Page.addScriptToEvaluateOnNewDocument', {
'source': '''
Object.defineProperty(navigator, 'webdriver', {
get: () => undefined
})
'''
})
driver.get('https://example.com')
Configurando User-Agent e outros cabeçalhos
Navegadores sem cabeça frequentemente usam strings de User-Agent desatualizadas ou específicas. É necessário definir um User-Agent atual de um navegador real:
# User-Agent atual do Chrome no 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}')
# Argumentos adicionais para mascaramento
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')
# Tamanho da janela como um usuário real
chrome_options.add_argument('--window-size=1920,1080')
chrome_options.add_argument('--start-maximized')
Adicionando plugins e idiomas
Navegadores automatizados não têm plugins e frequentemente mostram uma lista de idiomas vazia. Corrigimos isso através do CDP:
driver.execute_cdp_cmd('Page.addScriptToEvaluateOnNewDocument', {
'source': '''
Object.defineProperty(navigator, 'languages', {
get: () => ['pt-BR', 'pt', 'en']
});
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'
});
'''
})
Exemplo completo de configuração do Selenium
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
import random
def create_stealth_driver():
chrome_options = Options()
# Configurações básicas de mascaramento
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}')
# Tamanho da janela
chrome_options.add_argument('--window-size=1920,1080')
chrome_options.add_argument('--start-maximized')
driver = webdriver.Chrome(options=chrome_options)
# Script de mascaramento através do CDP
stealth_script = '''
Object.defineProperty(navigator, 'webdriver', {get: () => undefined});
Object.defineProperty(navigator, 'languages', {get: () => ['pt-BR', 'pt']});
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
# Uso
driver = create_stealth_driver()
driver.get('https://bot.sannysoft.com/') # Site para verificar a detecção
Configuração do Puppeteer para contornar a detecção
O Puppeteer tem os mesmos problemas de detecção que o Selenium. No entanto, para Node.js, existe uma biblioteca pronta chamada puppeteer-extra-plugin-stealth, que automatiza a maioria das configurações de mascaramento.
Instalando puppeteer-extra
npm install puppeteer puppeteer-extra puppeteer-extra-plugin-stealth
Configuração básica com o plugin stealth
const puppeteer = require('puppeteer-extra');
const StealthPlugin = require('puppeteer-extra-plugin-stealth');
// Conectando o plugin de mascaramento
puppeteer.use(StealthPlugin());
(async () => {
const browser = await puppeteer.launch({
headless: 'new', // Novo modo headless do 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();
// Definindo o viewport
await page.setViewport({
width: 1920,
height: 1080,
deviceScaleFactor: 1
});
// Definindo o 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');
// Cabeçalhos adicionais
await page.setExtraHTTPHeaders({
'Accept-Language': 'pt-BR,pt;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/');
// Captura de tela para verificação
await page.screenshot({ path: 'test.png' });
await browser.close();
})();
Configuração manual sem plugins
Se você deseja controle total ou não pode usar bibliotecas de terceiros, configure a mascaragem manualmente:
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch({
headless: 'new',
args: ['--no-sandbox', '--disable-setuid-sandbox']
});
const page = await browser.newPage();
// Redefinindo webdriver e outras propriedades
await page.evaluateOnNewDocument(() => {
Object.defineProperty(navigator, 'webdriver', {
get: () => undefined
});
Object.defineProperty(navigator, 'languages', {
get: () => ['pt-BR', 'pt']
});
Object.defineProperty(navigator, 'plugins', {
get: () => [1, 2, 3, 4, 5]
});
// Mascarando Chrome headless
Object.defineProperty(navigator, 'platform', {
get: () => 'Win32'
});
window.chrome = {
runtime: {}
};
// Redefinindo permissões
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();
})();
Configuração para contornar o Cloudflare
O Cloudflare utiliza métodos avançados de detecção. Para contornar, é necessário adicionar atrasos aleatórios e emular ações:
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 aleatório
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)]);
// Navegando para a página
await page.goto(url, { waitUntil: 'networkidle2' });
// Esperando a verificação do Cloudflare (geralmente 5-10 segundos)
await page.waitForTimeout(8000);
// Movimento aleatório do mouse
await page.mouse.move(100, 100);
await page.mouse.move(200, 200);
const content = await page.content();
await browser.close();
return content;
}
Combate ao fingerprinting JavaScript
O fingerprinting JavaScript é a criação de uma impressão digital única do navegador com base em muitos parâmetros. Mesmo que você tenha ocultado o webdriver, os sistemas analisam centenas de outras propriedades para identificar a automação.
Principais vetores de fingerprinting
Sistemas de proteção contra bots verificam os seguintes parâmetros:
| Parâmetro | O que é verificado | Risco de detecção |
|---|---|---|
| navigator.webdriver | Presença do sinalizador de automação | Crítico |
| navigator.plugins | Número e tipos de plugins | Alto |
| window.chrome | Presença da API do Chrome | Médio |
| navigator.permissions | API de permissões do navegador | Médio |
| screen.colorDepth | Profundidade de cor da tela | Baixo |
| navigator.hardwareConcurrency | Número de núcleos do processador | Baixo |
Script complexo de mascaramento
O script abaixo redefine a maioria das propriedades problemáticas. Implemente-o através do CDP (Selenium) ou evaluateOnNewDocument (Puppeteer):
const stealthScript = `
// Removendo o webdriver
Object.defineProperty(navigator, 'webdriver', {
get: () => undefined
});
// Adicionando objeto chrome
window.chrome = {
runtime: {},
loadTimes: function() {},
csi: function() {},
app: {}
};
// Redefinindo permissões
const originalQuery = window.navigator.permissions.query;
window.navigator.permissions.query = (parameters) => (
parameters.name === 'notifications' ?
Promise.resolve({ state: Notification.permission }) :
originalQuery(parameters)
);
// Mascarando 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"
}
];
}
});
// Idiomas
Object.defineProperty(navigator, 'languages', {
get: () => ['pt-BR', 'pt']
});
// Plataforma
Object.defineProperty(navigator, 'platform', {
get: () => 'Win32'
});
// Fornecedor
Object.defineProperty(navigator, 'vendor', {
get: () => 'Google Inc.'
});
// Removendo rastros do Selenium
delete window.cdc_adoQpoasnfa76pfcZLmcfl_Array;
delete window.cdc_adoQpoasnfa76pfcZLmcfl_Promise;
delete window.cdc_adoQpoasnfa76pfcZLmcfl_Symbol;
// Battery API (ausente em headless)
if (!navigator.getBattery) {
navigator.getBattery = () => Promise.resolve({
charging: true,
chargingTime: 0,
dischargingTime: Infinity,
level: 1
});
}
`;
Remoção de propriedades do WebDriver
O ChromeDriver e outras implementações do WebDriver adicionam variáveis específicas ao escopo global. Essas variáveis começam com o prefixo cdc_ e são facilmente detectadas pelos sistemas de proteção.
Detecção de variáveis cdc
Verificar a presença dessas variáveis pode ser feito com um simples script:
// Procurando todas as variáveis cdc
for (let key in window) {
if (key.includes('cdc_')) {
console.log('Variável WebDriver detectada:', key);
}
}
// Variáveis típicas do ChromeDriver:
// cdc_adoQpoasnfa76pfcZLmcfl_Array
// cdc_adoQpoasnfa76pfcZLmcfl_Promise
// cdc_adoQpoasnfa76pfcZLmcfl_Symbol
// $cdc_asdjflasutopfhvcZLmcfl_
Método 1: Remoção via CDP
O método mais confiável é remover as variáveis antes de carregar a página através do Chrome DevTools Protocol:
from selenium import webdriver
driver = webdriver.Chrome()
# Removendo todas as variáveis cdc
driver.execute_cdp_cmd('Page.addScriptToEvaluateOnNewDocument', {
'source': '''
// Removendo variáveis cdc conhecidas
const cdcProps = [
'cdc_adoQpoasnfa76pfcZLmcfl_Array',
'cdc_adoQpoasnfa76pfcZLmcfl_Promise',
'cdc_adoQpoasnfa76pfcZLmcfl_Symbol',
'$cdc_asdjflasutopfhvcZLmcfl_'
];
cdcProps.forEach(prop => {
delete window[prop];
});
// Removendo todas as variáveis que contêm 'cdc_'
Object.keys(window).forEach(key => {
if (key.includes('cdc_') || key.includes('$cdc_')) {
delete window[key];
}
});
'''
})
Método 2: Modificação do ChromeDriver
Uma abordagem mais radical é modificar o arquivo binário do ChromeDriver, substituindo a string cdc_ por outra sequência de caracteres. Isso evita a criação dessas variáveis:
import re
def patch_chromedriver(driver_path):
"""
Patche o ChromeDriver, substituindo 'cdc_' por uma string aleatória
"""
with open(driver_path, 'rb') as f:
content = f.read()
# Substituindo todas as ocorrências de 'cdc_' por 'dog_' (ou qualquer outra string do mesmo comprimento)
patched = content.replace(b'cdc_', b'dog_')
with open(driver_path, 'wb') as f:
f.write(patched)
print(f'ChromeDriver patchado: {driver_path}')
# Uso
patch_chromedriver('/path/to/chromedriver')
Atenção: Modificar o arquivo binário do ChromeDriver pode comprometer seu funcionamento. Sempre faça um backup antes de aplicar o patch. Este método pode não funcionar com todas as versões do ChromeDriver.
Método 3: Usando undetected-chromedriver
A biblioteca undetected-chromedriver automaticamente aplica patches ao ChromeDriver ao iniciar:
pip install undetected-chromedriver
import undetected_chromedriver as uc
# Criando o driver com patch automático
driver = uc.Chrome()
driver.get('https://nowsecure.nl/') # Site para verificar a detecção
input('Pressione Enter para fechar...')
driver.quit()
Mascaramento do Canvas, WebGL e Audio API
Canvas, WebGL e Audio Fingerprinting são métodos de criação de uma impressão digital única com base nas características de renderização gráfica e processamento de som. Cada combinação de navegador, SO e hardware gera um resultado único.
Canvas Fingerprinting
Sistemas desenham uma imagem oculta no Canvas e analisam os pixels resultantes. Navegadores sem cabeça frequentemente produzem resultados não típicos devido à ausência de aceleração de GPU.
// Código típico de Canvas Fingerprinting
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
ctx.textBaseline = 'top';
ctx.font = '14px Arial';
ctx.fillText('Impressão digital do navegador', 2, 2);
const fingerprint = canvas.toDataURL();
Para proteção, você pode adicionar ruído aleatório à API do Canvas:
const canvasNoiseScript = `
// Adicionando ruído aleatório ao Canvas
const originalToDataURL = HTMLCanvasElement.prototype.toDataURL;
const originalToBlob = HTMLCanvasElement.prototype.toBlob;
const originalGetImageData = CanvasRenderingContext2D.prototype.getImageData;
// Função para adicionar ruído
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) {
// Adicionando ruído mínimo ao RGB (invisível a olho nu)
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);
};
// Redefinindo 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
O WebGL fornece informações sobre a placa de vídeo e drivers. Navegadores sem cabeça frequentemente mostram SwiftShader (renderizador de software) em vez da GPU real:
const webglMaskScript = `
// Mascarando parâmetros do 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);
};
// Também para 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 do Audio Context
A API de áudio também fornece uma impressão digital única. Adicionamos ruído ao processamento de áudio:
const audioMaskScript = `
// Adicionando ruído ao 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);
// Adicionando ruído mínimo
for (let i = 0; i < array.length; i++) {
array[i] += Math.random() * 0.0001;
}
};
return analyser;
};
}
`;
Imitação do comportamento humano
Mesmo com uma mascaragem técnica perfeita, bots se revelam pelo comportamento. Sistemas de aprendizado de máquina analisam padrões de movimentos do mouse, velocidade das ações e sequência de eventos.
Atrasos aleatórios entre ações
Nunca use atrasos fixos. Usuários reais fazem pausas de duração variável:
import random
import time
def human_delay(min_seconds=1, max_seconds=3):
"""Atraso aleatório imitando um humano"""
delay = random.uniform(min_seconds, max_seconds)
time.sleep(delay)
# Uso
driver.get('https://example.com')
human_delay(2, 4) # Pausa de 2-4 segundos
element = driver.find_element(By.ID, 'search')
human_delay(0.5, 1.5) # Pausa curta antes da entrada
element.send_keys('consulta de pesquisa')
human_delay(1, 2)
Movimento suave do mouse
Bots movem o mouse em linhas retas ou teleportam o cursor. Usuários reais criam trajetórias curvas com aceleração e desaceleração:
// Puppeteer: movimento suave do mouse
async function humanMouseMove(page, targetX, targetY) {
const steps = 25; // Número de pontos intermediários
const currentPos = await page.evaluate(() => ({
x: window.mouseX || 0,
y: window.mouseY || 0
}));
for (let i = 0; i <= steps; i++) {
const t = i / steps;
// Usando easing para suavidade
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);
}
// Salvando a posição
await page.evaluate((x, y) => {
window.mouseX = x;
window.mouseY = y;
}, targetX, targetY);
}
// Uso
await humanMouseMove(page, 500, 300);
await page.mouse.click(500, 300);
Rolagem natural
Usuários reais rolam suavemente, com paradas para ler o conteúdo:
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) {
// Passo de rolagem aleatório (200-500px)
const scrollStep = Math.floor(Math.random() * 300) + 200;
currentPosition += scrollStep;
// Rolagem suave
await page.evaluate((pos) => {
window.scrollTo({
top: pos,
behavior: 'smooth'
});
}, currentPosition);
// Pausa para "ler" o conteúdo (1-3 segundos)
await page.waitForTimeout(Math.random() * 2000 + 1000);
}
}
// Uso
await page.goto('https://example.com');
await humanScroll(page);
Entrada de texto natural
As pessoas digitam em velocidades variadas, cometem erros de digitação e os corrigem:
async function humanTypeText(page, selector, text) {
await page.click(selector);
for (let char of text) {
// Atraso aleatório entre as teclas (50-200ms)
const delay = Math.random() * 150 + 50;
await page.waitForTimeout(delay);
// 5% de chance de erro de digitação
if (Math.random() < 0.05) {
// Digitando um caractere aleatório
const wrongChar = String.fromCharCode(97 + Math.floor(Math.random() * 26));
await page.keyboard.type(wrongChar);
await page.waitForTimeout(100 + Math.random() * 100);
// Deletando (Backspace)
await page.keyboard.press('Backspace');
await page.waitForTimeout(50 + Math.random() * 50);
}
await page.keyboard.type(char);
}
}
// Uso
await humanTypeText(page, '#search-input', 'consulta de pesquisa');
Integração de proxy para total anonimato
Mascarar o navegador é inútil se todos os pedidos vêm de um único endereço IP. Sistemas de proteção contra bots rastreiam o número de pedidos de cada IP e bloqueiam atividades suspeitas. Proxies são um componente obrigatório de qualquer automação séria.
Escolhendo o tipo de proxy
Diferentes tarefas exigem diferentes tipos de proxies:
| Tipo de proxy | Vantagens | Aplicação |
|---|---|---|
| Proxies residenciais | IP real, menos chance de bloqueio | Raspagem de dados, acesso a conteúdo geobloqueado |
| Proxies datacenter | Mais rápidos e baratos | Testes, automação em larga escala |
| Proxies móveis | IP de dispositivos móveis, alta anonimidade | Acesso a aplicativos móveis, testes de aplicativos |
Configuração de proxy no Selenium
Para usar um proxy no Selenium, você pode configurar as opções do Chrome:
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.chrome.options import Options
# Configuração do proxy
proxy = "http://username:password@proxy_ip:proxy_port"
chrome_options = Options()
chrome_options.add_argument(f'--proxy-server={proxy}')
# Criando o driver
driver = webdriver.Chrome(options=chrome_options)
driver.get('https://example.com')
Bibliotecas e ferramentas prontas
Existem várias bibliotecas e ferramentas que podem facilitar o processo de mascaramento e automação. Aqui estão algumas recomendadas:
- puppeteer-extra — uma extensão do Puppeteer que permite adicionar plugins como o stealth.
- undetected-chromedriver — uma biblioteca que contorna a detecção do ChromeDriver.
- SeleniumBase — uma biblioteca que simplifica o uso do Selenium com funcionalidades adicionais.
- Scrapy — um framework de raspagem de dados que pode ser integrado com proxies e técnicas de mascaramento.
Teste do nível de detecção
Após implementar as técnicas de mascaramento, é crucial testar o nível de detecção. Você pode usar serviços como:
- bot.sannysoft.com — um site que verifica se o seu navegador é detectável como um bot.
- browserleaks.com — um site que fornece informações sobre o seu navegador e pode ajudar a identificar possíveis vazamentos de informações.
Conclusão
Ocultar a automação de navegadores como Selenium e Puppeteer é um desafio, mas com as técnicas e ferramentas certas, é possível minimizar a detecção. A chave é entender como os sistemas de proteção funcionam e adaptar suas abordagens de acordo. Continue testando e ajustando suas configurações para garantir que sua automação permaneça invisível.