1. Escenario de acciones y su secuencia
Cuando empezamos a planificar un escenario de automatización, es importante entender que, como en los cuentos, hay que ir de lo simple a lo complejo. Imagínate que tu script es un héroe que se embarca en un viaje por las páginas de un sitio web. Cada paso está pensado y claramente configurado para no desviarse del camino.
Creación de un escenario paso a paso para la automatización
Hay que empezar por hacer un plan. ¿Qué quieres lograr? ¿Cargar una página, rellenar un formulario, hacer clic en un botón? Como dicen: "Quién no planea, planea fallar". No queremos un fallo, así que vamos a detallar los pasos propuestos.
from selenium import webdriver
from selenium.webdriver.common.by import By
# Creamos una instancia del driver. Usa el driver apropiado para tu navegador.
driver = webdriver.Chrome()
# Abrimos la página
driver.get('https://example.com/login')
# Rellenamos el usuario
driver.find_element(By.NAME, 'username').send_keys('mi_usuario')
# Rellenamos la contraseña
driver.find_element(By.NAME, 'password').send_keys('mi_contraseña_segura')
# Clicamos en el botón de login
driver.find_element(By.ID, 'login-button').click()
Así marcamos el ritmo de nuestro baile. Cada paso del escenario se ejecuta de forma secuencial, para que tu script pueda moverse fácilmente por el sitio.
Registro de los pasos realizados
Como cualquier héroe respetable, nuestro script debe dejar huellas, para que sepamos dónde estuvo y qué hizo. El logging es como el diario de tu script. Ayuda a rastrear la ejecución de los pasos e identificar errores si algo sale mal.
import logging
# Configuramos el logging
logging.basicConfig(level=logging.INFO)
# Ejemplo de registro de una acción
logging.info("Abrimos la página de login")
driver.get('https://example.com/login')
El logging no solo ayuda a depurar, sino que también brinda tranquilidad, sabiendo que tu script realiza cada paso como debe. Si algo sale mal, podrás volver atrás y ver en qué punto algo no funcionó.
2. Organización del código para lectura y modificación
Cuando el escenario se vuelve más complicado, es importante mantener el código ordenado. Imagina una fiesta de aniversario con muchos invitados y platos: si no se organiza todo, resultará en caos. En nuestro caso, caos en el código.
Configuración de la estructura del código
Para hacer cambios en el código con el mínimo esfuerzo, este debe estar bien organizado. Como un organizador de calcetines, hay que poner todo en orden. Usa funciones para separar acciones repetitivas en bloques separados.
def login_to_site(driver, username, password):
logging.info("Introduciendo el usuario")
driver.find_element(By.NAME, 'username').send_keys(username)
logging.info("Introduciendo la contraseña")
driver.find_element(By.NAME, 'password').send_keys(password)
logging.info("Clicando en el botón de login")
driver.find_element(By.ID, 'login-button').click()
# Usamos la función para iniciar sesión
login_to_site(driver, 'mi_usuario', 'mi_contraseña_segura')
El uso de funciones hace que el código sea más ordenado y permite realizar cambios fácilmente. Por ejemplo, si cambia el ID
del botón de inicio de sesión, solo necesitarás cambiarlo en una función y no en todo el código.
3. Ejemplo: Automatización del proceso de compra en un sitio web
Imaginemos que necesitamos configurar la automatización del proceso de compra en un sitio web, que incluye los siguientes pasos:
- Abrir el sitio e iniciar sesión en la cuenta.
- Ir al catálogo de productos y agregar un producto al carrito.
- Ir al carrito y realizar la compra.
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
# Inicialización del driver con configuración
def initialize_driver():
driver = webdriver.Chrome()
driver.implicitly_wait(10) # Espera implícita
return driver
# Función para iniciar sesión
def login(driver, username, password):
driver.get("https://example.com")
driver.find_element_by_id("username").send_keys(username)
driver.find_element_by_id("password").send_keys(password)
driver.find_element_by_id("login_button").click()
# Función para ir al catálogo de productos y agregar un producto al carrito
def add_product_to_cart(driver):
driver.get("https://example.com/catalog")
product = WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.CLASS_NAME, "product_item"))
)
product.click()
add_to_cart_button = driver.find_element_by_id("add_to_cart")
add_to_cart_button.click()
# Función para ir al carrito y finalizar la compra
def checkout(driver):
driver.get("https://example.com/cart")
checkout_button = WebDriverWait(driver, 10).until(
EC.element_to_be_clickable((By.ID, "checkout"))
)
checkout_button.click()
# Función para finalizar el driver
def close_driver(driver):
driver.quit()
# Script principal para ejecutar la secuencia de acciones
def main():
# Configuración de datos
username = "miusuario"
password = "miclave"
# Inicialización del driver
driver = initialize_driver()
try:
# Inicio de sesión
login(driver, username, password)
# Ir al catálogo y agregar producto al carrito
add_product_to_cart(driver)
# Ir al carrito y finalizar la compra
checkout(driver)
finally:
# Cerrar el driver
close_driver(driver)
# Ejecución del script principal
main()
Explicación de funciones
-
initialize_driver()
— función para inicializar el driver del navegador. Establece una espera implícita para todos los elementos y devuelve el objeto del driver. -
login()
— función para iniciar sesión en el sitio. Toma los parámetrosusername
ypassword
, que se usan para rellenar el formulario de inicio de sesión y clicar en el botón. -
add_product_to_cart()
— función para ir al catálogo, seleccionar un producto y agregarlo al carrito. -
checkout()
— función para ir al carrito y finalizar la compra. -
close_driver()
— función para cerrar el driver. -
main()
— función principal que gestiona la secuencia de acciones. En ella se realizan todas las llamadas a las funciones y se establecen los datos de inicio de sesión.
Ventajas de este enfoque
-
Legibilidad
— cada etapa está escrita como una función separada, lo que facilita la comprensión del código. -
Reutilización
— las funciones individuales se pueden usar de forma independiente del script principal, por ejemplo, para realizar acciones específicas en el sitio. -
Facilidad de prueba
— cada etapa se puede probar por separado para asegurarse de que todo funcione correctamente. -
Flexibilidad
— si es necesario, se pueden agregar otras funciones o cambiar el orden de las llamadas enmain()
.
GO TO FULL VERSION