Aún no tienes acceso a esta clase

Crea una cuenta y continúa viendo este curso

Demoras dinámicas

18/30
Recursos

Aportes 16

Preguntas 1

Ordenar por:

¿Quieres ver más aportes, preguntas y respuestas de la comunidad? Crea una cuenta o inicia sesión.

Demasiado bueno este curso! cada vez esta mejor!

Obtuve este mensaje tratando de correr el código y me interrumpía le ejecución

Solución:
Esperar a que aparezca el mensaje y cerrarlo

side_down = WebDriverWait(driver, delay).until(EC.presence_of_element_located((By.XPATH, '//div[@id="normal-slidedown"]')))
    if side_down:
        driver.find_element_by_xpath('.//div[@class="slidedown-footer"]/button[@class="align-right secondary slidedown-button"]').click()```

También pueden usar:

driver.implicitly_wait(3)

Donde 3 son los segundos máximos que esperará el driver hasta que se rendericen los elementos.

Que gran curso! No había encontrado ningún curso que explique de la forma en que Martín lo hace. excelente. muy contento hasta ahora!

for vuelo in vuelos:
    vuelo.click()
    obtener_precios(vuelo)
    vuelo.click()
    ```
Me sale error(StaleElementReferenceException) al intentar dar click a todos los vuelos! No he logrado solucionarlo! Alguien sabe por qué?

Hola! Con esta parte de XPATH y Selenium me interesó mucho crear un web scraper para real state en Colombia, aquí pueden ver el código completo

https://github.com/Jeanfabra/real_state_web_scraper

Tengo inconvenientes con un error de tipo ElementClickInterceptedException, indicando que el botón que llamo no es clickeable, esto solo ocurre cuando llamo desde la función que integrea todo, desde las funciones para vuelo individual no ocurre.

Hice mi ejercicio con Avianca, este es el código que he creado:

import requests
from bs4 import BeautifulSoup

import requests
from selenium import webdriver

#para demoras estáticas
import time

#para demoras dinámicas
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium.common.exceptions import TimeoutException

url = 'https://booking.avianca.com/av/booking/avail?from=CLO&pointOfSale=CO&language=ES&tripType=one-way&departureDate=2021-04-19&to=MDE&nbAdults=1&nbChildren=0&nbInfants=0&FriendlyID=&FriendlyID=&FriendlyIDNegoF=&FriendlyIDNegoF=&accessMethod=default&backend=PRD'
r = requests.get(url)
r.status_code

#FUNCIONES

def obtener_precios(vuelo):
    '''
    retorna una lista de dicts con todos los precios
    '''
    tarifas = vuelo.find_elements_by_xpath('//div[@class="container container-branded-fare ng-star-inserted"]/button')
    precios= []
    for item in tarifas:
        nombre = item.find_element_by_xpath('.//span[@class="ff-name ff-name-branded-fare"]').text
        contenido = item.find_element_by_xpath('.//div[@class="included"]').text.replace("Esta tarifa incluye:","")
        valor = item.find_element_by_xpath('.//span[@class="amount amount-branded-fare"]').text
        dict_tarifa ={nombre:{'contenido':contenido, 'valor':valor}}
        precios.append(dict_tarifa)
        print(dict_tarifa)
    return precios

def obtener_tiempos(vuelo):
    '''
    Función que retorna un diccionario con los horarios de salida y llegada de cada
    vuelo, incluyendo la duración. 
    Nota: la duración del vuelo no es la hora de llegada - la hora de salida porque
    puede haber diferencia de horarios entre el origen y el destino.
    '''
    #Hora de Salida
    salida = vuelo.find_element_by_xpath('.//div[@class="departure-date"]').text
    #Hora de llegada
    llegada = vuelo.find_element_by_xpath('.//div[@class="arrival-date"]').text
    #Duración del vuelo
    duracion = vuelo.find_element_by_xpath('.//div[@class="duration"]').text

    tiempos = {'hora_salida': salida, 'hora_llegada': llegada, 'duracion': duracion}
    return tiempos

#función para unificar el scraper

def obtener_info(driver):
    
    #aveces la página carga los vuelos con una de estas dos versiones
    vuelos1 = driver.find_elements_by_xpath('//div[@class="bound-overview busOrTrain"]')
    vuelos2 = driver.find_elements_by_xpath('//div[@class="bound-overview"]')
    if len(vuelos1)>len(vuelos2):
        vuelos = vuelos1
    elif len(vuelos2)>len(vuelos1):
        vuelos = vuelos2    
    
    print(f'Se encontraron {len(vuelos)} vuelos.')
    print('Iniciando scraping...')
    
    info = []
    
    for vuelo in vuelos:
        #obtenemos los tiempos generales de cada vuelo
        tiempos = obtener_tiempos(vuelo)
        
        #Abre vuelo
        vuelo.find_element_by_xpath('.//button[@class="select-cabin-button"]').click()
        
        #Precios de la tarifa eco
        precios_eco = obtener_precios(vuelo)
        
        #Cierra vuelo
        vuelo.find_element_by_xpath('.//button[@class="select-cabin-button"]').click()
        
        info.append({'precios':precios_eco, 'tiempos': tiempos})
    return info


options = webdriver.ChromeOptions()
options.add_argument('--incognito')#acceso directo al modo incógnito del navegador
driver = webdriver.Chrome(options=options)
driver.get(url)

#Introducir demora estática
#time.sleep(10)

#Introducir una demora dinámica
delay = 10 #este es un máximo de tiempo de espera
try:
    #demora inteligente
    vuelo = WebDriverWait(driver, delay).until(EC.presence_of_element_located((By.XPATH,'//div[@class="bound-overview busOrTrain"]')))
    print('la página ha cargado')
    info_vuelos = obtener_info(driver)
except TimeoutException:
    print('La página tardó demasiado en cargar')
    info_vuelos = []
driver.close()


Para tratar con el tiempo de carga de cada página antes de poder examinarla podemos optar por dos soluciones:

Demora estática

Insertamos la demora estática una vez hemos solicitado la carga de la página

# Demora de 10 segundos
time.sleep(10)

Demora dinámica

Utilizando una función de Selenium que detectará cuando un elemento esté presente en la página como una señal de que ya ha cargado en un rango de tiempo. Si se excede este rango de tiempo, podemos lanzar una excepción.

# Importamos un conjunto de clases
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.boy import By
from selenium.common.exceptions import TimeOutException

delay = 10
try:
	# Demora dinámica
	vuelo = WebDriverWait(driver, delay).until(EC.presence_of_element_located((By.XPATH, '//li[@class="flight"]')))
except TimeOutException:
	# Cuando la página demoró demasiado en cargar
	print("Se excedió el tiempo de carga / Mensaje de error")

Para evitar fallos de carga de la página y de mensajes emergente que no dejen realizar el scraper, se implementan demoras dinámicas, estas a diferencia de las estáticas brindan un mejor rendimiento. Ya que no tienen que esperar el tiempo estático sino que esperan a que se cargue la página y si tarda menos del tiempo estipulado, empieza a hacer el scraper.

Para ello debemos importar varias librerías

from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium.common.exceptions import TimeoutException

Ya importadas las librerías, unificamos un poco mas el codigo y anexamos las demoras dinámicas

options = webdriver.ChromeOptions()
options.add_argument('--incognito')
driver = webdriver.Chrome(executable_path='./chromedriver', options=options)
driver.get(url)
#timer dinamico
delay = 10
try:
    myElem = WebDriverWait(driver, delay).until(EC.presence_of_element_located((By.XPATH, '//li[@class="flight"]')))
    print("Page is ready!")
    info = obtener_info(driver)
except TimeoutException:
    print("Loading took too much time!")
print(info)
driver.close()

importante =)

hice las demoras de la clase anterior asi

    element = WebDriverWait(driver, 10).until(lambda x: x.find_element_by_xpath('//li[@class="flight"]'))
#Modulos que nos ayudaran a que termine de cargar la pagina para que inicie el scraping
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium.common.exceptions import TimeoutException```

Para los que tengan mi problema (una ventana sobre prevenir el coranavirus) hice lo siguiente:

  • Al inicio de la función obtener_info puse esta línea:
    driver.find_element_by_xpath("//span[@class=‘close’]").click()
  • Y en la demora inteligente puse esto:
    vuelo = WebDriverWait(driver, delay).until(EC.visibility_of_element_located((By.XPATH, “//span[@class=‘close’]”)))
    Lo cual me sirve para esperar a que la ventana sobre el coronavirus sea visible en pantalla (presence no sirve ya que la venta siempre está “presente” pero fuera de visibilidad).

dios!!! en duración de video es poco, pero en practica!!! ahora si sentí que mi cerebro se esforzó con todos los ejercicios! y la creación de funciones ::brain

Con cada clase se aprende muchisimo!

interesante