Problema: enviar la tarea requiere navegar un laberinto de páginas web tan complejas que he enviado la tarea al lugar equivocado varias veces. Además, aunque este proceso lleva solo 1-2 minutos, a veces parece un obstáculo insuperable (por ejemplo, cuando terminé una tarea demasiado tarde en la noche y apenas puedo recordar mi contraseña).
Solución: ¡ use Python para enviar tareas completadas automáticamente! Idealmente, podría guardar la tarea, escribir algunas teclas y cargar mi trabajo en segundos. Al principio parecía demasiado bueno para ser verdad, pero luego descubrí Selenium, una herramienta que se puede usar con Python para navegar por la web.
Cada vez que repetimos acciones tediosas en Internet con la misma secuencia de pasos, esta es una gran oportunidad para escribir un programa para automatizar el proceso. Con Selenium y Python, solo necesitamos escribir el script una vez, ¡y luego podemos ejecutarlo tantas veces como queramos y salvarnos de repetir tareas repetitivas (y en mi caso, es imposible enviar el trabajo al lugar equivocado)!
Aquí, revisaré una solución que desarrollé para enviar automáticamente (y correctamente) mis tareas. En el camino, cubriremos los conceptos básicos del uso de Python y selenio para el control web programático. Si bien este programa funciona (¡lo uso todos los días!), Es bastante individual, por lo que no podrá copiar y pegar el código de su aplicación. Sin embargo, los métodos generales aquí se pueden aplicar a un número ilimitado de situaciones. (Si desea ver el código completo, está disponible en GitHub ).
Un acercamiento
Antes de entrar en la parte divertida de la automatización, necesitamos descubrir la estructura general de nuestra solución. Comenzar a codificar sin un plan es una excelente manera de perder horas y frustrarse. Quiero escribir un programa para enviar las tareas de clase completadas al lugar correcto en Canvas ( el "sistema de gestión de aprendizaje" de mi universidad). Primero, necesito una manera de decirle al programa el nombre del trabajo que debe enviar y la clase. Tomé un enfoque simple y creé una carpeta para almacenar las tareas completadas con carpetas secundarias para cada clase. En las carpetas secundarias, pongo un documento terminado con el nombre de un trabajo específico. El programa puede encontrar el nombre de la clase por la carpeta y el nombre de la tarea por el nombre del documento.
Aquí hay un ejemplo donde el nombre de la clase es EECS491 y la tarea es la Tarea 3 - Salida en modelos gráficos grandes ".
Estructura de archivos (izquierda) y Asignación completa (derecha).
La primera parte del programa es un bucle que recorre las carpetas para encontrar el trabajo y la clase que almacenamos en una tupla de Python:
# os for file management
import os
# Build tuple of (class, file) to turn in
submission_dir = 'completed_assignments'
dir_list = list(os.listdir(submission_dir))
for directory in dir_list:
file_list = list(os.listdir(os.path.join(submission_dir,
directory)))
if len(file_list) != 0:
file_tup = (directory, file_list[0])
print(file_tup)
('EECS491', 'Tarea 3 - Inferencia en modelos gráficos más grandes.txt')
Esto se encarga de la gestión de archivos y ahora el programa conoce la clase y la tarea a incluir. El siguiente paso es usar Selenium para navegar a la página web correcta y cargar el trabajo.
Control web con selenio
Para comenzar con Selenium, importamos la biblioteca y creamos un controlador web, que es un navegador controlado por nuestro programa. En este caso, usaré Chrome como mi navegador y publicaré el controlador en el sitio web de Canvas donde envío los trabajos.
import selenium
# Using Chrome to access web
driver = webdriver.Chrome()
# Open the website
driver.get('https://canvas.case.edu')
Cuando abrimos la página web de Canvas, nos encontramos con el primer obstáculo: ¡el cuadro de inicio de sesión! Para evitar esto, necesitaremos ingresar el ID y la contraseña y presionar el botón de inicio de sesión.
Imagine que un controlador web es alguien que nunca antes ha visto una página web: necesitamos decir exactamente dónde hacer clic, qué imprimir y qué botones hacer clic. Hay varias formas de decirle a nuestro controlador web qué elementos encontrar, y todos usan selectores. Un selector es un identificador único para un elemento en una página web. Para encontrar un selector para un elemento específico, diga el campo "ID de CWRU", tenemos que mirar el código de la página web. En Chrome, esto se puede hacer presionando Ctrl + Shift + I o haciendo clic derecho en cualquier elemento y seleccionando Ver código. Esto abreChrome Developer Tools , una aplicación extremadamente útil que muestra el HTML subyacente en cualquier página web .
Para encontrar el selector para el campo "ID de CWRU", hice clic derecho en el campo, hice clic en Ver código y vi lo siguiente en las herramientas del desarrollador. La línea resaltada corresponde al elemento id_box (esta línea se llama etiqueta HTML).
Este HTML puede parecer abrumador, pero podemos ignorar la mayor parte de la información y centrarnos en las partes
id = "username"
y name = "username"
. (estos se conocen como atributos de etiqueta HTML).
Para seleccionar un campo
id
usando nuestro controlador web, podemos usar el atributo id
o name
que encontramos en las herramientas para desarrolladores. Los controladores web Selenium tienen muchas formas diferentes de seleccionar elementos en una página web y, a menudo, hay varias formas de seleccionar el mismo elemento:
# Select the id box
id_box = driver.find_element_by_name('username')
# Equivalent Outcome!
id_box = driver.find_element_by_id('username')
Nuestro programa ahora tiene acceso
id_box
y podemos interactuar con él de varias maneras, como ingresar teclas o presionar (si hemos seleccionado un botón).
# Send id information
id_box.send_keys('my_username')
Seguimos el mismo proceso para el campo de entrada de contraseña y el botón de inicio de sesión, seleccionando cada uno dependiendo de lo que vemos en las herramientas de desarrollador de Chrome. Luego enviamos información a los artículos o hacemos clic en ellos según sea necesario.
# Find password box
pass_box = driver.find_element_by_name('password')
# Send password
pass_box.send_keys('my_password')
# Find login button
login_button = driver.find_element_by_name('submit')
# Click login
login_button.click()
Tan pronto como iniciamos sesión, nos recibe esta barra de herramientas ligeramente intimidante:
nuevamente necesitamos navegar el programa a través de la página web, especificando los elementos exactos para hacer clic y la información para ingresar. En este caso, le digo al programa que seleccione los cursos del menú de la izquierda, y luego la clase correspondiente a la tarea que necesito aprobar:
# Find and click on list of courses
courses_button = driver.find_element_by_id('global_nav_courses_link')
courses_button.click()
# Get the name of the folder
folder = file_tup[0]
# Class to select depends on folder
if folder == 'EECS491':
class_select = driver.find_element_by_link_text('Artificial Intelligence: Probabilistic Graphical Models (100/10039)')
elif folder == 'EECS531':
class_select = driver.find_element_by_link_text('Computer Vision (100/10040)')
# Click on the specific class
class_select.click()
El programa encuentra la clase correcta usando el nombre de la carpeta que guardamos en el primer paso. En este caso, uso el método select
find_element_by_link_text
para encontrar una clase específica. El "texto de enlace" para un elemento es solo otro selector que podemos encontrar mirando la página:
este flujo de trabajo puede parecer un poco tedioso, ¡pero recuerda que solo tenemos que hacer esto una vez cuando escribimos nuestro programa! Después de eso, podemos hacer clic en "Ejecutar" tantas veces como queramos, y el programa irá a todas estas páginas por nosotros.
Utilizamos el mismo proceso de validación de una página, seleccionando un elemento, interactuando con un elemento para pasar por un par de pantallas más. Finalmente, llegamos a la página de envío de trabajo:
En este punto, podía ver la línea de meta, pero inicialmente esta pantalla me dejó perplejo. Podría haber hecho clic en el campo Seleccionar archivo con bastante facilidad, pero ¿cómo se suponía que debía seleccionar el archivo que quiero cargar? ¡La respuesta resulta ser increíblemente simple! Encontramos el campo
Choose File
usando un selector y usamos un método send_keys
para pasar la ruta exacta del archivo (nombrada file_location
en el código a continuación) al bloque:
# Choose File button
choose_file = driver.find_element_by_name('attachments[0][uploaded_data]')
# Complete path of the file
file_location = os.path.join(submission_dir, folder, file_name)
# Send the file location to the button
choose_file.send_keys(file_location)
Al enviar la ruta exacta del archivo, podemos omitir todo el proceso de navegación de la carpeta para encontrar el archivo que queremos. Después de enviar la ruta, obtenemos la siguiente pantalla que muestra que nuestro archivo está cargado y listo para ser enviado.
¡Ahora seleccionamos el botón "Enviar tarea", hacemos clic y nuestra tarea se envía!
# Locate submit button and click
submit_assignment = driver.find_element_by_id('submit_file_button')
submit_assignent.click()
Limpieza
La administración de archivos siempre es un paso crítico, y quiero asegurarme de no volver a enviar o perder trabajos antiguos. Pensé que la mejor solución sería guardar el archivo para colocarlo en una carpeta
completed_assignments
y mover los archivos a la carpeta submitted_assignments
tan pronto como se descarguen. El último bit de código usa el módulo os para mover el trabajo completado a la ubicación correcta.
# Location of files after submission
submitted_file_location = os.path.join(submitted_dir, submitted_file_name)
# Rename essentially copies and pastes files
os.rename(file_location, submitted_file_location)
Todo el código fuente está empaquetado en un script que puedo ejecutar desde la línea de comandos. Para limitar la posibilidad de errores, solo presento un trabajo a la vez, ¡lo cual no es gran cosa teniendo en cuenta que solo toma alrededor de 5 segundos iniciar el programa!
Esto es lo que parece cuando ejecuto el programa:
el programa me da la oportunidad de asegurarme de que este sea el trabajo correcto antes de cargarlo. Una vez que finaliza el programa, obtengo el siguiente resultado:
Mientras el programa se está ejecutando, puedo observar que Python se ejecuta por mí:
conclusiones
Las técnicas de automatización con Python son excelentes para muchas tareas, tanto generales como en mi campo de ciencia de datos. Por ejemplo, podríamos usar Selenium para descargar automáticamente nuevos archivos de datos todos los días (suponiendo que el sitio web no tenga una API ). Si bien las secuencias de comandos pueden parecer tediosas a primera vista, la ventaja es que podemos hacer que la computadora repita esta secuencia tantas veces como queramos, exactamente de la misma manera. El programa nunca perderá el foco e irá a Twitter. Seguirá los pasos exactamente en una secuencia perfecta (el algoritmo funcionará bien hasta que el sitio cambie).
Debo mencionar que debe tener cuidado antes de automatizar tareas críticas. Este ejemplo es un riesgo relativamente bajo, ya que siempre puedo regresar y volver a enviar tareas, y generalmente reviso dos veces el programa para que funcione. Los sitios web cambian, y si no cambia el programa a cambio, ¡podría terminar con un script que hace algo completamente diferente de lo que originalmente pretendía!
En términos de ROI, este programa me ahorra unos 30 segundos por tarea y tarda 2 horas en escribir. Entonces, si lo uso para completar 240 tareas, ¡obtendré un plus a tiempo! Sin embargo, la recompensa de este programa radica en desarrollar una solución genial al problema y enseña mucho en el proceso. Si bien mi tiempo podría haberse gastado más eficientemente completando tareas en lugar de descubrir cómo entregarlas automáticamente, disfruté muchísimo el desafío. Hay algunas cosas tan satisfactorias como la resolución de problemas, y Python resulta ser una herramienta bastante buena para eso. ...
Aprenda los detalles de cómo obtener una profesión solicitada desde cero o subir de nivel en habilidades y salario completando los cursos en línea pagos de SkillFactory:
- Curso de aprendizaje automático (12 semanas)
- Data Science (12 )
- (9 )
- «Python -» (9 )