一尘不染

Python Selenium + Datepicker请点击

selenium

我一直在努力尝试获取此类房间的价格,例如,通过单击第一个可用的(绿色)datepicker签入输入,然后单击第一个可用的datepicker签入输入,以便生成最短期间的价格。

我的代码很乱,所以如果有人可以发布更简洁的代码来实现这一目标,我将不胜感激。

我正在使用Python selenium + scrapy,尽管以Java为例仍然有用。

更新:

这是代码:

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}

谢谢


阅读 579

收藏
2020-06-26

共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/201623/04/2016并打印180€

希望能有所帮助。

2020-06-26