Controle do Mouse
A API de Mouse fornece controle completo sobre a entrada do mouse no nível da página, permitindo simular movimentos realistas do cursor, cliques, cliques duplos e operações de arrastar. Quando humanize=True é passado, as operações do mouse usam simulação humanizada: as trajetórias seguem curvas de Bezier naturais com temporização pela Lei de Fitts, perfis de velocidade minimum-jerk, tremor fisiológico e correção de overshoot, tornando a automação virtualmente indistinguível do comportamento humano.
Interface Centralizada de Mouse
Todas as operações do mouse são acessíveis via tab.mouse, fornecendo uma API limpa e unificada para todas as interações com o mouse.
Início Rápido
from pydoll.browser.chromium import Chrome
from pydoll.protocol.input.types import MouseButton
async with Chrome() as browser:
tab = await browser.start()
await tab.go_to('https://example.com')
# Mover cursor para posição
await tab.mouse.move(500, 300)
# Clicar na posição
await tab.mouse.click(500, 300)
# Clique direito
await tab.mouse.click(500, 300, button=MouseButton.RIGHT)
# Clique duplo
await tab.mouse.double_click(500, 300)
# Arrastar de uma posição para outra
await tab.mouse.drag(100, 200, 500, 400)
Métodos Principais
move: Mover Cursor
Move o cursor do mouse para uma posição específica na página:
# Movimento padrão (único evento CDP, sem simulação)
await tab.mouse.move(500, 300)
# Movimento humanizado (trajetória curva com temporização natural)
await tab.mouse.move(500, 300, humanize=True)
Parâmetros:
x: Coordenada X de destino (pixels CSS)y: Coordenada Y de destino (pixels CSS)humanize(keyword-only): Simular movimento curvo semelhante ao humano (padrão:False)
click: Clicar na Posição
Move para a posição e realiza um clique do mouse:
from pydoll.protocol.input.types import MouseButton
# Clique esquerdo (padrão, instantâneo)
await tab.mouse.click(500, 300)
# Clique direito
await tab.mouse.click(500, 300, button=MouseButton.RIGHT)
# Clique duplo via click_count
await tab.mouse.click(500, 300, click_count=2)
# Clique humanizado com movimento natural
await tab.mouse.click(500, 300, humanize=True)
Parâmetros:
x: Coordenada X de destinoy: Coordenada Y de destinobutton(keyword-only): Botão do mouse, sendoLEFT,RIGHTouMIDDLE(padrão:LEFT)click_count(keyword-only): Número de cliques (padrão:1)humanize(keyword-only): Simular comportamento semelhante ao humano (padrão:False)
double_click: Clique Duplo na Posição
Método de conveniência equivalente a click(x, y, click_count=2):
down / up: Controle de Botão de Baixo Nível
Pressionar ou soltar botões do mouse independentemente:
# Pressionar botão esquerdo na posição atual
await tab.mouse.down()
# Soltar botão esquerdo
await tab.mouse.up()
# Botão direito
await tab.mouse.down(button=MouseButton.RIGHT)
await tab.mouse.up(button=MouseButton.RIGHT)
Esses são primitivos que operam na posição atual do cursor e não possuem parâmetro humanize.
drag: Arrastar e Soltar
Move do ponto inicial ao final mantendo o botão do mouse pressionado:
# Arrastar padrão (instantâneo)
await tab.mouse.drag(100, 200, 500, 400)
# Arrastar humanizado com movimento natural
await tab.mouse.drag(100, 200, 500, 400, humanize=True)
Parâmetros:
start_x,start_y: Coordenadas iniciaisend_x,end_y: Coordenadas finaishumanize(keyword-only): Simular arrasto semelhante ao humano (padrão:False)
Habilitando a Humanização
Todos os métodos do mouse usam humanize=False por padrão. Para habilitar simulação humanizada com trajetórias naturais em curvas de Bezier e temporização realista, passe humanize=True:
# Movimento humanizado, trajetória curva natural com temporização pela Lei de Fitts
await tab.mouse.move(500, 300, humanize=True)
# Clique humanizado: movimento curvo + pausa pré-clique + press + release
await tab.mouse.click(500, 300, humanize=True)
# Arrasto humanizado, curvas e pausas naturais
await tab.mouse.drag(100, 200, 500, 400, humanize=True)
Isso é recomendado quando a evasão de detecção é importante, por exemplo ao interagir com sites que empregam detecção de bots.
Modo Humanizado
Quando humanize=True é passado, o módulo de mouse aplica múltiplas camadas de realismo:
Trajetórias com Curvas de Bezier
O mouse segue uma trajetória curva natural em vez de uma linha reta. Os pontos de controle são deslocados aleatoriamente perpendiculares à linha início→fim, com posicionamento assimétrico (mais curvatura no início do movimento, como um alcance balístico real).
Temporização pela Lei de Fitts
A duração do movimento segue a Lei de Fitts: MT = a + b × log₂(D/W + 1). Distâncias maiores levam proporcionalmente mais tempo, correspondendo ao comportamento de controle motor humano.
Perfil de Velocidade Minimum-Jerk
O cursor segue um perfil de velocidade em forma de sino, iniciando lento, acelerando até a velocidade máxima no meio e depois desacelerando no final. Isso corresponde à trajetória de movimento humano mais suave possível.
Tremor Fisiológico
Ruído gaussiano pequeno (σ ≈ 1px) é adicionado a cada quadro, simulando tremor da mão. A amplitude do tremor escala inversamente com a velocidade, com mais tremor quando o cursor está lento ou parado e menos durante movimentos balísticos rápidos.
Overshoot e Correção
Para movimentos rápidos de longa distância (~70% de probabilidade), o cursor ultrapassa o alvo em 3–12% da distância, depois faz um pequeno sub-movimento corretivo de volta ao alvo. Isso corresponde a dados reais de controle motor humano.
Pausa Pré-Clique
Cliques humanizados incluem uma pausa pré-clique (50–200ms) que simula o tempo natural de estabilização antes de pressionar o botão.
Cliques Humanizados Automáticos em Elementos
Quando você usa element.click(humanize=True), a API do Mouse é utilizada para produzir um movimento realista com curva de Bezier da posição atual do cursor até o centro do elemento antes de clicar, tornando cliques em elementos indistinguíveis do comportamento humano.
# Clique padrão: press/release CDP bruto
button = await tab.find(id='submit')
await button.click()
# Com deslocamento do centro
await button.click(x_offset=10, y_offset=5)
# Clique humanizado: movimento com curva de Bezier + clique
await button.click(humanize=True)
O rastreamento de posição é mantido entre cliques em elementos. Clicar no elemento A, depois no elemento B, produz um caminho curvo natural de A até B.
Configuração Personalizada de Temporização
Todos os parâmetros de humanização são configuráveis via MouseTimingConfig:
from pydoll.interactions.mouse import MouseTimingConfig
config = MouseTimingConfig(
fitts_a=0.070, # Intercepto da Lei de Fitts (segundos)
fitts_b=0.150, # Inclinação da Lei de Fitts (segundos/bit)
frame_interval=0.012, # Intervalo base entre eventos mouseMoved
curvature_min=0.10, # Curvatura mínima como fração da distância
curvature_max=0.30, # Curvatura máxima
tremor_amplitude=1.0, # Sigma do tremor em pixels
overshoot_probability=0.70, # Chance de overshoot em movimentos rápidos
min_duration=0.08, # Duração mínima do movimento
max_duration=2.5, # Duração máxima do movimento
)
# Aplicar à instância de mouse do tab
tab.mouse.timing = config
Veja o dataclass MouseTimingConfig para todos os parâmetros disponíveis.
Rastreamento de Posição
A API de Mouse rastreia a posição do cursor entre operações:
# Posição inicial é (0, 0)
await tab.mouse.move(100, 200)
# Posição agora é (100, 200)
await tab.mouse.click(300, 400)
# Posição agora é (300, 400)
# Métodos de baixo nível usam a posição rastreada
await tab.mouse.down() # Pressiona em (300, 400)
await tab.mouse.up() # Solta em (300, 400)
Estado da Posição
A posição do mouse é rastreada internamente. WebElement.click() utiliza automaticamente tab.mouse quando disponível, então o rastreamento de posição é mantido entre cliques em elementos.
Modo Debug
Ative o modo debug para visualizar o movimento do mouse na página. Quando ativo, pontos coloridos são desenhados em um canvas de sobreposição transparente:
- Pontos azuis: trajetória do cursor durante o movimento
- Pontos vermelhos: posições de clique
# Ativar em tempo de execução via propriedade
tab.mouse.debug = True
# Agora todos os movimentos desenham pontos coloridos
await tab.mouse.click(500, 300)
# Desativar quando terminar
tab.mouse.debug = False
Isso é útil para ajustar parâmetros de temporização e verificar que as trajetórias parecem naturais.
Exemplos Práticos
Clicar em um Botão com Movimento Realista
async def click_button_naturally(tab):
# element.click() usa automaticamente tab.mouse para movimento humanizado
button = await tab.find(id='submit')
await button.click()
Arrastar um Slider
async def drag_slider(tab):
slider = await tab.find(css_selector='.slider-handle')
bounds = await slider.get_bounds_using_js()
start_x = bounds['x'] + bounds['width'] / 2
start_y = bounds['y'] + bounds['height'] / 2
end_x = start_x + 200 # Arrastar 200px para a direita
await tab.mouse.drag(start_x, start_y, end_x, start_y)
Passar o Mouse Sobre Elementos
async def hover_menu(tab):
menu = await tab.find(css_selector='.dropdown-trigger')
bounds = await menu.get_bounds_using_js()
await tab.mouse.move(
bounds['x'] + bounds['width'] / 2,
bounds['y'] + bounds['height'] / 2,
)
# O menu agora deve estar visível via CSS :hover
Aprenda Mais
- Interações Humanas: Visão geral de todas as interações humanizadas
- Controle de Teclado: Simulação realista de teclado