Interactuando con una página web usando python y selenium

luis ramirez
GDG IPN
Published in
5 min readOct 24, 2020

Hacer web scraping se ha convertido en una herramienta muy poderosa para la extracción de datos y con ellos alimentar nuestras aplicaciones para realizar tareas increíbles. En esta ocasión usaremos ese poder para obtener las recompensas del mundial de League of Legends.

Haremos uso de selenium pues nos permite de manera muy dinámica explorar y obtener elementos de árbol de HTML e interactuar con los resultados de las acciones.

Instalamos selenium.

pip install selenium

Pongámonos en marcha con selenium. Usaremos python como lenguaje de programación, pero existe para otros lenguajes como Java, JS y más.

Aquí la documentación: https://selenium-python.readthedocs.io/

Es una librería que se basa en webdrivers para hacer sus funciones, que son básicamente abstracciones de un navegador web que puedes encontrar como descargar el que gustes y en la versión que necesites. Aquí van las instrucciones detalladas, si tienes alguna duda deja un comentario. https://selenium-python.readthedocs.io/installation.html

En este caso yo haré uso de Chrome.

Todo lo haremos en un archivo llamado app.py

Importamos selenium e indicamos que usaremos el dirver de chrome, en este caso debe estar en la misma carpeta donde harás el script o puedes indicar la ruta

from selenium import webdriverdriver = webdriver.Chrome()

Indicamos el punto de entrada o página de inicio

driver.get('https://lolesports.com/')

Lo primero que debemos hacer es iniciamos sesión con nuestra cuenta de Riot lo cual es la condición que nos piden para poder dar las recompensas.

Partimos de una página que se ve:

Debemos buscar el elemento que nos permita abrir el menú. Para ellos hacemos uso de las consultas a la estructura html con Xpath https://www.w3schools.com/xml/xpath_intro.asp y los waits.

Para su uso importamos

from selenium.webdriver.common.by import Byfrom selenium.webdriver.support.ui import WebDriverWaitfrom selenium.webdriver.support import expected_conditions as ECexplore_bar = WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.XPATH, "//a[@id='riotbar-explore']")))explore_bar.click()

Con esta instrucción le indicamos que espere a la página a que muestre el elemento <a id=”riotbar-explore” class=”riotbar-explore”> y le damos click.

Esperamos a que abra la barra y presiona y buscamos el botón de iniciar sesión.

login_button = WebDriverWait(driver, 5).until(EC.presence_of_element_located((By.XPATH, "//div[@class='riotbar-navmenu-category']")))login_button.click()

Lo cual nos redirigirá a la página de inicio de sesión. https://auth.riotgames.com/login#client_id=rso-web-client-prod&redirect_uri=https%3A%2F%2Flogin.lolesports.com%2Foauth2-callback&response_type=code&scope=openid&state=dU-S7Sv6XlES_IdVuMqCpWFTpl-wltuOpkCLUspNyjQ&ui_locales=es-mx

Ahora debemos buscar el formulario e ingresar nuestro usuario y contraseña.

username_input =  WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.XPATH, "//input[@name='username']")))username = input("Ingresa tu usuario username: ")username_input.send_keys(username)password_input = driver.find_element(By.XPATH, "//input[@name='password']")password = input("Ingresa tu contraseña: ")password_input.send_keys(password)submit_login_button = WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.XPATH, "//button[@class='mobile-button mobile-button__submit']")))submit_login_button.click()

Realizamos la búsqueda del elemento <input name=”username” spellcheck=”false” data-testid=”input-username” … y esperamos a que esté disponible, que será el tiempo que tarde en cargar esta página. Pedimos que ingresen por consola su nombre de usuario y repetimos el proceso para la contraseña y damos click en el botón de login.

En caso de tener errores en los datos de login realizamos una validación.

login_error_message = WebDriverWait(driver, 5).until(EC.presence_of_element_located((By.XPATH, "//span[@class='status-message text__web-error']")))if login_error_message:print("Hubo un problema iniciando sesión, revisa tu usuario o contraseña de Riot")driver.quit()

Si todo salió bien regresaremos a la página de inicio y abriremos la barra de navegación. En esta ocasión iremos al calendario para ver si hay un juego hoy o incluso si ya está en marcha.

explore_bar = WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.XPATH, "//a[@id='riotbar-explore']")))explore_bar.click()calendar_button = driver.find_element_by_link_text('CALENDARIO')calendar_button.click()

Lo cual abre la pantalla.

Ahora debemos buscar si el juego ya está en curso, para la página tiene un elemento especial para ir a la transmisión.

element = WebDriverWait(driver, 5).until(EC.element_to_be_clickable((By.XPATH, "//a[@href='/live/worlds']")))element.click()sys.exit()

En caso de ya estar ocurriendo solo terminamos la ejecución.

De lo contrario debemos buscar el horario del siguiente juego.

Análisemos esta estructura… Tenemos un div que alberga el día dónde ocurrieron o ocurrirán los juegos y otro con el horario y quienes juegan.

Para ello vamos obtener todos los divs que tienen relación con los juegos

event_dates = WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.XPATH, "//div[@class='Event']")))

Ahora obtendremos las estructuras de divs que pueden corresponder a la clase EventDate o EventMatch pues son las que contienen la información que nos interesa. Iteramos sobre cada una de ellas y buscamos el primer elemento que contenga la palabra Hoy o Mañana que nos indicarán cuándo va a ocurrir el siguiente partido (dependiendo de la hora en que estés corriendo el script, si es antes de las 12 am buscará Mañana y si es después buscará Hoy).

event_divs = event_dates.find_elements_by_xpath("//div[starts-with(@class,'Event')]")for idx, element in enumerate(event_divs):try:if element.find_element_by_class_name("weekday").text == ‘Hoy’ or element.find_element_by_class_name("weekday").text == ‘Mañana’:hora_inicio = event_divs[idx+1].find_element_by_class_name("hour").textexcept:pass

Ahora obtendremos las estructuras de divs que pueden corresponder a la clase EventDate o EventMatch pues son las que contienen la información que nos interesa. Iteramos sobre cada una de ellas y buscamos el primer elemento que contenga la palabra Hoy o Mañana que nos indicarán cuándo va a ocurrir el siguiente partido (dependiendo de la hora en que estés corriendo el script, si es antes de las 12 am buscará Mañana y si es después buscará Hoy).

Cuando ya obtuvimos la hora en que será el juego, pondremos un scheduler para que busque cuando el partido ya inicio y entre a verlo. Usaremos apscheduler https://apscheduler.readthedocs.io/en/stable/userguide.html

pip install apscheduler

Con un scheduler bloqueante puesto puesto que es el único proceso que está realizando nuestro script, agregaremos la tarea de entrar al juego.

from apscheduler.schedulers.background import BlockingSchedulersched = BlockingScheduler()if cuando == "Hoy":hora_inicio = datetime.now().replace(hour=hora_inicio, minute=10)else: cuando == "Mañana":hora_inicio = datetime.now().replace(hour=hora_inicio, minute=10) + timedelta(days=1)sched.add_job(open_game, 'date', run_date=hora_inicio)

Así queda el resultado final de App.py

Cualquier duda que tengas la puedes dejar en los comentarios y además te dejo el repositorio https://gitlab.com/luis_ramirez/data-structures-and-algorithms/-/blob/master/articles_medium/scraper_lol.py

Cualquier duda que tengas la puedes dejar en los comentarios y además te dejo el repositorio https://gitlab.com/luis_ramirez/data-structures-and-algorithms/-/blob/master/articles_medium/scraper_lol.py

--

--