Demasiado bueno este curso! cada vez esta mejor!
Introducción, definiciones y ética
Introducción y definiciones
Ética y Legalidad
Configuración del entorno de trabajo con Jupyter
HTML: Requests y BeautifulSoup
Descargando una página web
Parseando HTML con BeautifulSoup
Extrayendo información
Manejo de errores
Descargando contenido
Contenido multimedia
Unificando el scraper
Scraping JavaScript con Selenium
Instalación y configuración de Selenium
Sitios dinámicos y Selenium
Selección de elementos
Interactuando con los elementos
Scrapeando escalas y tarifas
Construyendo Funciones
Construyendo la función para unificar el scraper
Demoras dinámicas
Comentarios finales
APIs
Introducción a APIs
Utilizando APIs: Construir una URL
Utilizando APIs: Tokens y Búsqueda
Obteniendo la discografía
Obteniendo los albums
Fin del proyecto + bonus
Scrapy, Tesseract y Proxies
Scrapy
Ejecutando el scraper con scrapy
Proxies
Tesseract
Conclusión y cierre del curso
Aún no tienes acceso a esta clase
Crea una cuenta y continúa viendo este curso
Aportes 16
Preguntas 1
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
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()
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:
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
¿Quieres ver más aportes, preguntas y respuestas de la comunidad? Crea una cuenta o inicia sesión.