PyAutoGUI – Módulo de automatización multiplataforma



Introducción

PyAutoGUI es un módulo para automatizar tareas en múltiples sistemas operativos. “Automatizar” es generalmente entendido como controlar el mouse y el teclado, aunque en este caso en particular se incluyen otras herramientas como cuadros de diálogo y capturas de pantalla. Es similar a AutoPy, pero a diferencia de éste, PyAutoGUI corre en Python 2 y 3.

La API del módulo es bastante simple. Lamentablemente las funciones no siguen las nomenclaturas recomendadas por la guía de estilo del lenguaje -una decisión absurda a mi juicio- y en algunos casos tampoco hacen honor a la máxima “tendría que haber una única forma obvia de hacerlo” del Zen de Python. A fin de compensar estas “pseudofalencias” (si es que podemos llamarlas así) me tomé el atrevimiento de obviar algunas características para mantener la simpleza; aunque claro, siempre puedes consultar la documentación completa en pyautogui.readthedocs.io.

Sin más prefacios, comencemos.

Instalación

Puedes instalar PyAutoGUI junto con todas sus dependencias vía pip.

pip install pyautogui

O bien descargar el código desde la página de PyPI e instalar las dependencias manualmente (PyMsgBox, PyTweening, Pillow y pyscreeze).

Para poder ejecutar correctamente PyAutoGUI en Linux, además, deben instalarse las siguientes dependencias.

pip install python3-xlib
sudo apt-get install scrot
sudo apt-get install python3-tk
sudo apt-get install python3-dev

En Max OS se requiere lo siguiente:

pip install pyobjc-core
pip install pyobjc

En Windows el paquete no requiere ninguna instalación adicional.

Operaciones con el mouse

  • Obtener la posición del mouse:

    >>> import pyautogui
    >>> pyautogui.position()
    (510, 254)
    
  • Mover el mouse a una posición determinada:

    >>> pyautogui.moveTo(300, 200)
    

    El código ubica el cursor en la posición X=300 Y=200, siendo el origen de coordenadas la esquina superior izquierda.

    Por defecto la transición ocurre instantáneamente. A través del parámetro duration podemos indicarle al módulo que el movimiento debe tomar una determinada cantidad de segundos.

    # Tomarse 3 segundos para mover el mouse.
    >>> pyautogui.moveTo(300, 200, 3)
    

    Además podemos configurar cómo debe realizarse la transición de la posición actual a la posición indicada, que por defecto se produce de forma lineal, vía un cuarto parámetro llamado tween. Las opciones son:

    • linear (valor por defecto)
    • easeInBack
    • easeInBounce
    • easeInCirc
    • easeInCubic
    • easeInElastic
    • easeInExpo
    • easeInOutBack
    • easeInOutBounce
    • easeInOutCirc
    • easeInOutCubic
    • easeInOutElastic
    • easeInOutExpo
    • easeInOutQuad
    • easeInOutQuart
    • easeInOutQuint
    • easeInOutSine
    • easeInQuad
    • easeInQueart
    • easeInQuint
    • easeInSine
    • easeOutBack
    • easeOutBounce
    • easeOutCirc
    • easeOutCubic
    • easeOutElastic
    • easeOutExpo
    • easeOutQuad
    • easeOutQueart
    • easeOutQuint
    • easeOutSine

     
    Por ejemplo:

    >>> pyautogui.moveTo(300, 200, 3, pyautogui.easeInBack)
    

    La función moveRel es similar a la anterior, pero los valores de X e Y se especifican en forma relativa a la posición actual del cursor, de modo que también pueden utilizarse valores negativos.

    # Mover el mouse arriba y a la derecha.
    >>> pyautogui.moveRel(50, -100, 1)
    
  • Simular un clic del mouse:

    >>> pyautogui.click()
    >>> pyautogui.doubleClick()
    >>> pyautogui.tripleClick()
    

    Las tres funciones operan por defecto con el clic derecho. Para cambiar esto indicamos el parámetro button que puede tomar los valores left (por defecto), middle o right.

    # Doble clic izquierdo.
    >>> pyautogui.doubleClick(button="right")
    

    También podemos indicar en qué posición de la pantalla debe efectuarse:

    >>> pyautogui.click(50, 100)
    

    De igual forma operan las funciones mouseUp y mouseDown, para generar una presión hacia arriba y otra hacia abajo, respectivamente.

    # Simula pyautogui.click().
    >>> pyautogui.mouseDown()
    >>> pyautogui.mouseUp()
    
  • Arrastrar y soltar (drag & drop):

    >>> pyautogui.dragTo(500, 400)
    

    Por defecto el mouse se arrastra manteniendo presionado el botón derecho. dragTo() acepta los mismos parámetros que click().

    Generalmente es recomendable que la operación no ocurra de inmediato para que funcione correctamente en todas las plataformas:

    # Recomendable.
    >>> pyautogui.dragTo(500, 400, duration=0.3)
    

    Para especificar la posición en términos relativos, usamos dragRel():

    >>> pyautogui.dragRel(100, 50)
    

    El método de arrastrar y soltar es básicamente similar a:

    pyautogui.mouseDown()
    pyautogui.moveTo(x, y)
    pyautogui.mouseUp()
    

    (Siempre y cuando no se indique el parámetro duration).

  • Desplazar el mouse (scroll):

    # Scroll hacia arriba.
    >>> pyautogui.scroll(400)
    # Scroll hacia abajo.
    >>> pyautogui.scroll(-400)
    

    El valor que debe pasarse a la función es sumamente dependiente de la plataforma, así que te recomiendo que pruebes algunos números arbitrarios para ver cuál se adapta a tus necesidades.

Operaciones con el teclado

  • Presionar y soltar una tecla:

    pyautogui.press("a")
    pyautogui.press("enter")
    
  • Escribir un texto:

    pyautogui.typewrite("Recursos Python")
    # "\n" provoca la presión de la tecla Enter.
    pyautogui.typewrite("Recursos\nPython")
    
  • Realizar combinaciones de teclas:

    # CTRL + F5.
    pyautogui.hotkey("ctrl", "f5")
    
  • Ver una lista de las teclas disponibles vía:

    >>> pyautogui.KEYBOARD_KEYS
    
  • Tanto typewrite() como hotkey() aceptan interval para indicar, en segundos, el intervalo entre una tecla y otra.

    pyautogui.typewrite("Recursos Python", interval=0.2)
    

Mensajes y cuadros de diálogo

PyAutoGUI incluye el módulo PyMsgBox, que permite crear mensajes y cuadros de diálogo utilizando internamente Tk.

# Desplegar un mensaje.
pyautogui.alert("¡Hola, mundo!", "Desde PyAutoGUI")

La función alert muestra un mensaje en pantalla con un título, y retorna el texto del botón presionado ("OK" por defecto) o bien None si se cerró la ventana. Para cambiar el texto del botón, añadimos un tercer argumento.

pyautogui.alert("¡Hola, mundo!", "Desde PyAutoGUI", button="Aceptar")

Si queremos que el mensaje muestre varias opciones hacemos uso de confirm():

# Botones.
OPT_CLOSE = "Sí, cerrar"
OPT_SAVE_AND_CLOSE = "Guardar todo y cerrar"
OPT_KEEP_WORKING = "No, seguir trabajando"

# Crear el mensaje.
opt = pyautogui.confirm(
    "¿Desea cerrar el programa?",
    "Confirmación",
    [OPT_CLOSE, OPT_SAVE_AND_CLOSE, OPT_KEEP_WORKING]
)

# Tomar decisión en base al botón presionado.
if opt == OPT_CLOSE:
    # ...
elif opt == OPT_SAVE_AND_CLOSE:
    # ...
elif opt == OPT_KEEP_WORKING:
    # ...

Para solicitar que el usuario ingrese un texto el módulo provee la función prompt.

# La función retorna None si se cerró la ventana o presionó "Cancel".
user = pyautogui.prompt("Ingrese su nombre de usuario", "Iniciar sesión")

Es posible indicar un valor por defecto y un tiempo límite en milisegundos, de modo que una vez transcurrido se cerrará el diálogo automáticamente.

# Valor por defecto "usuario1" y cerrar a los 5 segundos.
user = pyautogui.prompt("Ingrese su nombre de usuario", "Iniciar sesión",
                        default="usuario1", timeout=5000)

Capturas de pantalla

  • Capturar imagen de la pantalla:

    >>> screenshot = pyautogui.screenshot()
    

    Como PyAutoGUI trabaja internamente con Pillow, screenshot es una instancia de PIL.Image.Image.

  • Capturar una porción de la pantalla:

    >>> screenshot = pyautogui.screenshot(region=(50, 50, 400, 300))
    

    region es una tupla con la estructura (X, Y, Ancho, Alto).

  • Obtener el color de un píxel como una tupla (R, G, B):

    >>> screenshot.getpixel((500, 400))
    (225, 228, 229)
    

    Para saber si un píxel equivale a cierto color, puedes usar:

    >>> pyautogui.pixelMatchesColor(500, 400, (225, 228, 229))
    True
    

    Si bien este código es similar a screenshot.getpixel((500, 400)) == (225, 228, 229), tiene un ingrediente extra llamado tolerance que indica cuánto puede variar el color para que la búsqueda sea menos restrictiva.

    # El color no coincide exactamente pero es cercano.
    >>> pyautogui.pixelMatchesColor(500, 400, (220, 230, 232), tolerance=10)
    True
    

  • Ubicar una imagen dentro de la pantalla:

    # Retorna una tupla del tipo (X, Y, Ancho, Alto).
    >>> pyautogui.locateOnScreen("imagen.png")
    (759, 44, 96, 48)
    

    La función también acepta imagenes abiertas por Pillow:

    >>> from PIL import Image
    >>> image = Image.open("imagen.png")
    >>> pyautogui.locateOnScreen(image)
    (759, 44, 96, 48)
    

    Si la imagena aprece varias veces en la pantalla, locateAllOnScreen() retorna un iterador con todas las coincidencias:

    >>> list(pyautogui.locateAllOnScreen("imagen2.png"))
    [(1060, 629, 17, 20), (1177, 629, 17, 20)]
    
  • Ubicar una imagen dentro de una región de la pantalla:

    # También aplicable a locateAllOnScreen().
    >>> pyautogui.locateOnScreen("imagen.png", region=(0, 0, 1100, 300))
    (759, 44, 96, 48)
    

    Especificar una región aumenta considerablemente el tiempo de procesamiento de la función.

  • Ubicar una imagen teniendo en cuenta únicamente la escala de grises:

    # También aplicable a locateAllOnScreen().
    >>> pyautogui.locateOnScreen("imagen.png", grayscale=True)
    (759, 44, 96, 48)
    

    grayscale=True aumenta la velocidad de la función en alrededor de 30%.

Otras operaciones

  • Obtener el tamaño de la pantalla:

    >>> pyautogui.size()
    (1366, 768)
    
  • Determinar si un par de coordenadas están dentro de los límites:

    >>> pyautogui.onScreen(100, 500)
    True
    >>> pyautogui.onScreen(1400, 700)
    False
    


4 comentarios.

  1. Hola, como puedo hacer para instalarlo para windows en el link que aparece en la parte de arriba aparecen muchas dependencias y no lo logro encontrar el correcto.

    • Recursos Python says:

      Hola, lo ideal sería vía pip install pyautogui que instalará todas las dependencias necesarias. ¿Estás obteniendo algún error?

      Saludos

  2. Buenos días,

    Por favor, ¿podrías indicarme cómo hacer para que el programa escriba correctamente el carácter “\”? La función typewrite() omite ese símbolo (también he probado con “\\”. Puede que con la función hotkey() pero o no he sabido escribir bién el comando o tampoco funciona…

    Muchas gracias,
    Un saludo

    • Recursos Python says:

      Hola. Usando pyautogui.typewrite("\\") me escribe el carácter correctamente en Windows 8. ¿Qué sistema operativo estás usando?

      Un saludo.

Deja un comentario