Python Selenium + Datepicker Click

Me he estado golpeando la cabeza tratando de obtener el precio de una habitación como esta, por ejemplo, haciendo clic en la primera entrada disponible (verde) de registro de fecha y luego haciendo clic en la primera entrada disponible de pago y selección de fecha para que se genere el precio por el período mínimo.

Mi código es un desastre, así que realmente apreciaría si alguien pudiera publicar un código más limpio para lograrlo.

Estoy usando Python selenium + scrapy aunque algo en Java, por ejemplo, todavía ayudaría.

ACTUALIZAR:

Aquí está el código:

def availability(self, doc): url = doc['url'] + '#calendar' self.driver.get(url) is_active = True # We want to the availability/price for each day in a month. availabilities = [] # wait for the check in input to load wait = WebDriverWait(self.driver, 10) try: elem = wait.until( EC.visibility_of_element_located( (By.CSS_SELECTOR, ".dates-group input[name=startDateInput]") ) ) except TimeoutException: pass else: elem.click() # open calendar # wait for datepicker to load wait.until( EC.visibility_of_element_located( (By.CSS_SELECTOR, '.ui-datepicker:not(.loading)')) ) days = self.driver.find_elements_by_css_selector( "#ui-datepicker-div tr td" ) for cell in days: day = cell.text.strip() if not day: continue if "full-changeover" not in cell.get_attribute("class"): available = False else: available = True self.logger.warning('CELL "%s"', cell) self.logger.warning('DAY "%s"', day) self.logger.warning('available "%s"', available) # The first iteration was to list the availability, now we want to # click the first available element to get the price for cell in days: day = cell.text.strip() if not day: continue if "full-changeover" in cell.get_attribute("class"): self.logger.warning('CLICK IT "%s"', day) self.driver.implicitly_wait(10) x = self.driver.find_element_by_xpath("//table/tbody/tr/td/a[text()=" + day + "]") self.driver.implicitly_wait(10) x.click() # Element not found in the cache issue here # import ipdb; ipdb.set_trace() # self.logger.warning('CELL "%s"', cell) # self.logger.warning('DAY "%s"', day) # self.logger.warning('available "%s"', available) # elem.click() # close checkin calendar # Now lets click on the checkout input to get the price and minimum # number of days. We probably don't have to wait for the checkout # because its already loaded but you never know. try: elem = wait.until( EC.visibility_of_element_located( (By.CSS_SELECTOR, ".dates-group input[name=endDateInput]") ) ) except TimeoutException: pass else: # elem.click() # open calendar in checkout input # wait for datepicker to load wait.until( EC.visibility_of_element_located( (By.CSS_SELECTOR, '.ui-datepicker:not(.loading)')) ) days = self.driver.find_elements_by_css_selector( "#ui-datepicker-div tr td" ) for cell in days: day = cell.text.strip() if not day: continue # This is the first available date to checkout if "full-changeover" in cell.get_attribute("class"): self.logger.warning('CLICK IT "%s"', available) import ipdb; ipdb.set_trace() # Here we would get the generated price self.logger.warning('CELL "%s"', cell) self.logger.warning('DAY "%s"', day) self.logger.warning('available "%s"', available) import ipdb; ipdb.set_trace() return {'availabilities': availabilities, 'is_active': is_active} 

Gracias

Una cosa difícil acerca de este calendario es que primero debe pasar un día en particular y luego reubicar el día activo y hacer clic en él. Aquí hay una implementación de trabajo que selecciona las primeras fechas de inicio y finalización disponibles e imprime el precio calculado:

 from selenium import webdriver from selenium.webdriver import ActionChains from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC driver = webdriver.Firefox() driver.maximize_window() wait = WebDriverWait(driver, 10) url = 'https://www.homeaway.pt/arrendamento-ferias/p1418427a?uni_id=1590648' driver.get(url) # pick start date start_date = wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, ".quotebar-container input[name=startDateInput]"))) start_date.click() first_available_date = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, "#ui-datepicker-div td.full-changeover > a"))) ActionChains(driver).move_to_element(first_available_date).perform() driver.find_element_by_css_selector("#ui-datepicker-div td.full-selected.full-changeover > a").click() # pick end date (TODO: violates DRY principle, refactor!) end_date = wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, ".quotebar-container input[name=endDateInput]"))) end_date.click() first_available_date = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, "#ui-datepicker-div td.full-changeover > a"))) ActionChains(driver).move_to_element(first_available_date).perform() driver.find_element_by_css_selector("#ui-datepicker-div td.full-selected.full-changeover > a").click() # get the calculated price price = wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, ".price-quote .price-total"))) print(price.text) driver.close() 

Por el momento, selecciona el 20/04/2016 y el 23/04/2016 y imprime 180€ .

Espero que ayude.