python selenium 日历控件,Python Selenium + Datepicker点击

I have been banging my head around trying to get the price of a room like this for example by clicking the first available (green) datepicker checkin input and then clicking the first available datepicker checkout input so the price for the minium period is generated.

My code is a mess so i would really appreciate if someone could post a cleaner code to achieve that.

I am using Python selenium + scrapy although something in Java for example would still help.

UPDATE:

here is the code:

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}

Thanks

解决方案

One tricky thing about this calendar is that you first need to hover a particular day and then relocate the active day and click it. Here is a working implementation that selects the first available start and end dates and prints the calculated price:

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

At the moment, it selects 20/04/2016 and 23/04/2016 and prints 180€.

Hope that helps.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值