2016-04-19 2 views
2

Я ударился головой, пытаясь получить цену комнаты, например this, например, щелкнув первый доступный (зеленый) вход для ввода даты, а затем щелкнув первый доступный входной билет даты, чтобы цена для минимального периода.Python Selenium + Datepicker Нажмите

Мой код - беспорядок, поэтому я был бы очень признателен, если бы кто-то мог опубликовать более чистый код, чтобы достичь этого.

Я использую Pelon selenium + scrapy, хотя что-то в Java, например, по-прежнему поможет.

UPDATE:

вот код:

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} 

Благодаря

+0

Не могли бы вы опубликовать то, что у вас есть? По крайней мере, соответствующие части .. – alecxe

+0

@alecxe я добавил код – psychok7

+0

@alecxe, кстати, это именно то, что, как я думал, было бы правильным, чтобы заставить его работать, если у вас есть идея, пожалуйста, дайте мне знать. Я начал получать «Элемент, который не найден в кеше» на клике, как я понял, что делаю что-то неправильно. – psychok7

ответ

1

Одна хитрая вещь об этом календаре, что сначала нужно навести определенный день, а затем переставить активный день и щелкните его. Вот рабочая реализация, которая выбирает первые доступные даты начала и окончания и печатает вычисленную цену:

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() 

На данный момент он выбирает 20/04/2016 и 23/04/2016 и печатают 180€.

Надеюсь, что это поможет.

+0

Позвольте мне попробовать это сегодня вечером, и я не знаю, как это произошло сразу после: – psychok7

+0

это работает :) .. Еще раз спасибо за вашу помощь, проведенную целый день, пытаясь понять это – psychok7

+0

hi alecxe, с этим решением, как я могу получить доступность для следующие месяцы? Я пытаюсь щелкнуть по следующей кнопке календаря после первого щелчка start_date с помощью 'self.driver.find_element_by_css_selector ('. ui-datepicker-next.ui-corner-all'). click()', но я получаю 'ElementNotVisibleException 'любые идеи, что я делаю неправильно? – psychok7

Смежные вопросы