PythonDS: Data Science no Python e mais...

Python, Micropython, C, Arduino, ESP-8266, Raspberry Pi e outras aventuras tecno-nerds

Logo Python

RPA para automação de interface gráfica com Py Auto GUI

Explore a poderosa biblioteca PyAutoGUI para manipular mouse, teclado área de transferência, etc. e interagir com diversos tipos de aplicações na criação RPAs independentes de tecnologias proprietárias. Uma das dificuldades que nos deparamos ao criar robôs para automatizar tarefas repetitivas é a variedade de sistemas ERPs utilizados por diferentes empresas, que muitas vezes requerem uma tecnologia específica ou, ao menos, o conhecimento dos componentes usandos na construção dos mesmos, além disso há muitas situações em que para conclusão de uma tarefa é necessária a interação entre diversas aplicações diferentes ou navegação por janelas do mesmo software.

PyAutoGUI endereça as dificuldades mencionadas acima, trabalhando de maneira independente ou em conjunto com outras bibliotecas de automação de processos, através da habilitação de seus robôs a controlarem as ações do mouse, teclado, área de transferência e conteúdo das telas. Este tutorial permite o estudo das principais funcionalidades da biblioteca passo a passo e pode ser complementado pelo tutorial em vídeo disponível em https://youtu.be/Jik11gN5PPE, cuja primeira aula pode ser exibida a partir do vídeo a seguir.

PASSO ZERO - O test-drive: Antes de entrarmos nos detalhes do funcionamento e estudarmos as principais funções da biblioteca e ideias para sua aplicação prática. Vamos ver uma pequena demonstração da mágica em ação. Crie um novo programa, digite o código abaixo e execute-o.

import pyautogui
pyautogui.moveTo(797, 521, duration=1)
pyautogui.moveRel(-150, 0, duration=0.5)
pyautogui.moveRel(0, -150, duration=0.5)
for k in range(0, 3):
pyautogui.moveRel(300, 0, duration=0.5)
pyautogui.moveRel(0, 300, duration=0.5)
pyautogui.moveRel(-300, 0, duration=0.5)
pyautogui.moveRel(0, -300, duration=0.5)
pyautogui.alert('Parabéns! Você criou seu primeiro fantasma digital.')

1. Preparação do ambiente: Usando o instalador de pacotes do Python pip, além da biblioteca pyautogui, deve-se instalar a biblioteca pyperclip que é útil para recuperar informações da área de transferência, em seguida testamos a importação e rodamos duas funções básicas da pyautogui que são utlizadas sempre que estamos iniciando um projeto para mapear o tamanho do monitor em utilização .size() e a localização atual do mouse .position().

C:\> pip install pyautogui
... (Omitimos as linhas do resultado da instalação)
...
C:\> pip install pyperclip
... (Omitimos as linhas do resultado da instalação)
...
C:\> python
Python 3.7.2 (tags/v3.7.2:9a3ffc0492, Dec 23 2018, 23:09:28) [MSC v.1916 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import pyautogui
>>> _
>>> pyautogui.size()
Size(width=1920, height=1080)
>>> pyautogui.position()
Point(x=628, y=1052)

As funções acima são chamadas sem necessidade de parâmetros e retornam coordenadas x e y relativas, no primeiro caso, à largura e altura do monitor e no segundo caso um ponto específico na tela.
A primeira informação é usada como base para os limites de atuação do mouse e, em casos mais avançados, pode ser usada também para programar comportamento/ações dos bots em posições relativas. O código abaixo apresenta uma forma simplificada para calcular uma posição na tela (centro) de acordo com o tamanho obtido com .size().

>>> x, y = pyautogui.size()
>>> x
1920
>>> y
1080
>>> centro = (x/2, y/2)
>>> centro
(960.0, 540.0)
>>> pyautogui.moveTo(centro, duration=0.5)

Quanto às coordenadas de posição, estas são as informações mais comumente usadas para saber em qual local o botão, campo ou qualquer elemento da aplicação sendo automatizada está localizada para que as ações sejam realizadas.
Para utilizar a função .position(), com o shell com o cursor ativo, mover o mouse até a posição desejada e mantê-lo parado (com cuidado para não clicar). Feito isso, executar a função.
No código abaixo, no primeiro exemplo chamados a função apenas para exibir a posição na tela e no segundo atribuímos as coordenadas a uma variável que poderá ser reutilizada em outras funções de pyautogui, em ambos casos usamos o valor obtido para mover o mouse até o ponto desejado e depois dar um clique simples com o mouse.

>>> pyautogui.position()
Point(x=1893, y=20)
>>> pyautogui.moveTo(1893, 20, duration=0.5)
>>> botao_fechar = pyautogui.position()
>>> botao_fechar
Point(x=1893, y=20)
>>> pyautogui.moveTo(botao_fechar, duration=0.5)
>>> pyautogui.click()

Vídeo complementar de estudo desta seção:

ATENÇÃO: atualmente a biblioteca Py AutoGUI controla apenas as ações no monitor principal, portanto, não há suporte para manipulação de bots em telas secundárias em configurações com múltiplos monitores.

2. Ações básicas para automação de interface gráfica de usuário: Tanto as funções de manipulação do mouse quanto as demais de Py AutoGUI são bem intuitivas, praticamente apenas o uso de linguagem natural (em inglês) das ações que um usuário comum executaria ao usar um sistema qualquer, por isso, após iniciar o trabalho com a biblioteca percebemos uma extrema facilidade em seu uso.
Por exemplo, para clicar com o mouse, no local onde o mouse se encontra simplesmente execute a função click()! Quer mover o mouse para uma posição na tela? Execute moveTo(). Ah! Mas eu quero robôs interativos, capazes de alertar o usuário para uma situação importante ou pedir uma confirmação de uma ação. Sem problemas, use alert() ou confirm()...
Essa seção e as seguintes apresentam as principais funções da biblioteca, divididas por ações de mouse, teclado e área de transferência e, antes de finalizar, apresentamos um pequeno exemplo de integração das funções num programa que copia o conteúdo de uma tela, interage com o usuário para confirmar se pode usar o conteúdo copiado e em seguida cola o conteúdo em um campo de uma aplicação.

>>> pyautogui.moveTo(x, y, duration=1) #Mover para uma localização
>>> pyautogui.moveRel(x, y, duration=1) #Mover para uma posição relativa
>>> pyautogui.click(x, y) #Clique simples em uma posição
>>> pyautogui.click(x, y, button='right') #Clique simples com botão direito
>>> pyautogui.doubleClick(x, y) #Clique duplo
>>> pyautogui.dragTo(x, y) #Arrastar a seleção
>>> pyautogui.scroll(100) #Rolar a tela 100 cliques para cima
>>> pyautogui.scroll(-100) #Rolar a tela 100 cliques para baixo

Parâmetros comuns à maioria das funções:

...

>>> pyautogui.press(tecla) #Pressiona a tecla informada
>>> pyautogui.press('enter') #Pressiona a tecla [ENTER]
>>> pyautogui.press('win') #Pressiona a tecla Iniciar do Windows
>>> pyautogui.hotkey(teclas) #Aciona comandos relativos a atalhos de teclas
>>> pyautogui.hotkey('ctrl', 'c') #Copia conteúdo selecionado
>>> pyautogui.typewrite(texto) #Digita o texto no local atual do cursor
>>> pyautogui.typewrite('Teste') #Digita a palavra Teste

...

>>> pyautogui.hotkey('ctrl', 'c') #Copia conteúdo selecionado
>>> paste() #Cola o conteúdo da área de transferência no local ativo
>>> conteudo = paste() #Registra o conteúdo da área de transferência em uma variável
>>> pyautogui.typewrite(conteudo) #Digita o texto da variável conteúdo

Para permitir que as ações sejam realizadas de maneira correta, a manipulação de conteúdo da área de transferência funciona melhor quando executado a partir de um script ao invés de execução interativa no shell, por isso no exemplo acima de cópia e cola, funcionaria melhor em um arquivo .py criado para execução posterior. Se quiser pode testar os comandos no shell, mas em alguns casos os resultados podem não corresponder ao esperado.

ATENÇÃO: quando um robô criado com PyAutoGUI está em funcionamento ele literalmente assume o controle de teclado e mouse, portanto, não é possível manter o bot ativo e continuar executando outras ações manuais, por isso, sua maior utilidade é para automação de etapas de processos (como assitente de um usuário) ou automação de tarefas completas em que o usuário possa manter o computador ativo, mas não utilizá-lo enquanto o bot está trabalhando.

>>> pyautogui.alert(argumentos) #Cria uma caixa de diálogo com um alerta simples
>>> pyautogui.confirm(argumentos) #Pede uma confirmação ao usuário
>>> pyautogui.prompt(argumentos) #Pede ao usuário para digitar algum dado
>>> pyautogui.password(argumentos) #Entrada de senhas com ocultação de caracteres

Parâmetros (argumentos) comuns às funções:

Veja exemplos práticos de uso dos quatro tipos de caixa de diálogo:

3. Ideias para aplicação prática: A seguir são apresentados alguns exemplos, simples mas de uso prático onde são abordados os tópicos listados antes de cada exemplo.

"""
Programa aplica na prática diversos tipos de caixa de interação
com o usuário, que poderiam ser usadas dentro de um RPA como forma
de confirmar etapas, pedir dados complementares ou alertar sobre situações
com necessidade de atenação especial.
"""

import pyautogui

k = 0
while True:
#Senha original digitada no código apenas como exemplo.
#Isto não é uma boa prática.
senha = 'Janio'
digitado = pyautogui.password(text='Digite sua senha:', title='Testa senha: Senha')

#Lógica simples para confirmar se a senha digitada é correta
if senha == digitado:
pyautogui.alert(text='Senha correta', title='Testa senha: Acesso concedido')
mensagem = pyautogui.prompt(text='Digite uma mensagem para o robô',
title='Testa senha: Mensagem')
confirma = pyautogui.confirm(text=f'Confirma a mensagem digitada?\n{mensagem}',
buttons=('Sim', 'Não'), title='Testa senha: Confirmação')

if confirma == 'Sim':
print(f'A mensagem digitada foi: "{mensagem}".')
break
else:
pyautogui.alert(text='Senha incorreta.\nTente novamente', title='Testa senha: Acesso negado')
k += 1

if k >= 3:
pyautogui.alert(text='ATENÇÃO: Acesso negado.\nNúmero de tentativas excedido!',
title='Testa senha: Acesso negado')
print('Não houve mensagem digitada')
break

if k >= 1:
print(f'Ocorreram {k} tentativas erradas de digitação da senha')

"""
Programa aplica na prática as funções estudadas neste material
No exemplo simulamos a navegação por uma tela, seleção e cópia
de parte do conteúdo de uma janela e posteriormente a colagem
do conteúdo em um campo de outra aplicação e o clique em um botão
para salvar as informações gravadas.
"""

import pyautogui
from time import sleep
from pyperclip import paste

inicio_texto = (770, 616) #Substituir coordenadas pelo início do texto a copiar
final_texto = (700, 616) #Substituir coordenadas pelo início do texto a copiar
campo_da_app = (600, 400) #Substituir coordenadas pelo local do campo a receber a cópia
botao_salvar = (116, 63) #Substituir coordenadas do botão de confirmação/salvamento na aplicação

pyautogui.moveTo(inicio_texto, duration=0.5)
pyautogui.click()
pyautogui.dragTo(final_texto)
sleep(1)

pyautogui.hotkey('ctrl', 'c', logScreenshot=True)
sleep(1)

conteudo = paste()

resposta = pyautogui.confirm('Deseja colocar o texto no campo XPTO', buttons=('Sim', 'Não'))
if resposta == 'Sim':
pyautogui.click(campo_da_app)
sleep(1)
pyautogui.typewrite(conteudo)
sleep(2)
pyautogui.moteTo(botao_salvar, duration=0.5)
pyautogui.click(logScreenshot=True)

Para estes dois últimos tópicos não há necessidade de exemplos, mas de comentários sobre o que poderíamos mudar no uso das funções ou dos programas de exemplo para atentar para estes dois importantes pontos quando usamos PyAutoGUI.
Sobre a questão das travas, a sua remoção seria o simples uso das funções dos programas com remoção ou redução das etapas de checagens de condições (if's) ou com menos caixas de diálogos para confirmações ou preenchimento complementar por parte do usuário. Para isso, entretanto, se faz necessário um estudo aprofundado do processo cliente do sistema automatizado, pois a remoção indevida de condições pode gerar situações indesejadas ou mesmo prejuízo para os negócios por exemplo por uma aprovação efetuada por um robô sem checar requisitos obrigatórios, lançamentos incorretos em sistemas ERPs, etc., por outro lado, o excesso de caixas de diálogos e confirmações a cada passo do robô, pode tornar sua eficiência reduzida e, em alguns casos, até perder o sentido em automatizar a tarefa.
Quanto às condições de escape, uma abordagem que já está inserida nos exemplos, são as próprias condições e exigências de confirmação, mas além delas temos o uso integrado da funções sleep para dar tempo para que a ação seja executada adequadamente ou que o usuário aborte manualmente o programa se notar algum comportamente indevido. Um artífico que pode ajudar na segurança, é inserir pontos de espera mais longos em etapas críticas, como antes do salvamento de uma ação no sistema, permitindo cancelar pela simples ação manual do usuário de fechar a janela ativa (removendo-a do alvo do robô). Por fim, a biblioteca tem uma função nativa de escape ativada pelo atributo FAILSAFE que por padrão é definido como True (Verdadeiro para ativo), permitindo que uma movimentação abrupta do mouse para cima e para esquerda aborte qualquer ação em execução.

Considerações finais:
Começamos esse material adjetivando a biblioteca PyAutoGUI como poderosa, o que é verdade, mas para concluir o estudo recorremos aos heróis dos quadrinhos e à célebre frase do Tio Ben ao recém empoderado Homem-Aranha: Com grandes poderes vem grandes responsabilidades. Apesar da origem fictícia da frase, a alegoria é bem adequada às ferramentas que acabaram de ser apresentadas, pois apesar de seu grande poder é necessário bastante cuidado e uma boa análise de processos de negócio antes da implementação de automações com seu uso, pois devido ao fato de não ter necessidade de usar o próprio código do programa sendo automatizada e nem mesmo mapeamento explícito de elementos (campos, tags, etc.), ao mesmo tempo suas funções permitem automatizar virtualmente qualquer ação que um ser humano comum faria com teclado e mouse, mas gera também o problema de sistemas web que mudam a localização de componentes de acordo com o navegador, ou com a situação da janela, tempos de processamento em diversos sistemas que mudam de acordo com a velocidade da rede, etc. e sobretudo a dependência das dimensões da tela que está sendo usada.
Isso tudo não deve ser fator de desmotivação, mas apenas de alerta para os cuidados necessários durante o desenvolvimento de robôs, para o melhor aproveitamento das possibilidades na expansão do poder de outras bibliotecas e linguagens de criação de RPAs, com isso em mente, PyAutoGUI tem a grande vantagem de poder ser utilizada em conjunto com qualquer biblioteca do Python automatizando etapas específicas, aproveitando as possibilidades de manipulação de arquivos de bibliotecas como Pandas, OS e Glob, apenas para mencionar algumas das mais utilizadas para estes fins.

Explore as possibilidades e nos enviem suas impressões e resultados através dos contatos listados em nossa página inicial.

Referências

Bibliotecas Python utilizadas:

Biblioteca Documentação PyPi Página Oficial
PyAutoGUI pypi.org/project/PyAutoGUI pyautogui.readthedocs.io
Pyperclip pypi.org/project/pyperclip pyperclip.readthedocs.io

Livros e artigos sugeridos: