首页 > 解决方案 > 如何使用 webdriver 选择签入和签出

问题描述

我正在尝试抓取“Booking.com”网站,但我无法获得价格,因为我无法强制下面的代码在日期字段中选择日期,我使用了与发送相同的方法城镇字段发送日期字段。我管理此代码如下:

import re
import time
import csv

from datetime import datetime
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import TimeoutException
from bs4 import BeautifulSoup
from bs4.element import Tag

CITIES=["Bordeaux,france"]
driver = webdriver.Chrome() 
for city in CITIES:
    driver.get("https://www.booking.com/")
    driver.find_element_by_css_selector("#ss").send_keys(city)  # Enter City Name
    # Wait until autosuggestion come and click on first suggestion
    WebDriverWait(driver, 20).until(
        EC.presence_of_element_located((By.XPATH, '//*[@id="frm"]/div[2]/div/div[1]/ul[1]/li[1]')))
    driver.find_element_by_xpath('//*[@id="frm"]/div[2]/div/div[1]/ul[1]/li[1]').click()

    check_in_time = datetime.fromtimestamp(int(time.time())).strftime("%Y-%m-%d")
    check_out_time = datetime.fromtimestamp(int(time.time()) + 604800).strftime("%Y-%m-%d")

    # Waits for Datetime widget and select check In date
    try:
        WebDriverWait(driver, 10).until(EC.element_to_be_clickable(
            (By.XPATH, '//*[@id="frm"]/div[3]/div/div[1]/div[1]/div[2]/div/div[2]/div[1]/div')))
    except TimeoutException:
        driver.find_element_by_xpath('//*[@id="frm"]/div[3]/div/div[1]/div[1]/div[2]').click()
        WebDriverWait(driver, 10).until(EC.element_to_be_clickable(
            (By.XPATH, '//*[@id="frm"]/div[3]/div/div[1]/div[1]/div[2]/div/div[2]/div[1]/div')))
    table = driver.find_elements_by_xpath('//*[@id="frm"]/div[3]/div/div[1]/div[1]/div[2]/'
                                          'div/div[2]/div[2]/div[3]/div/div/div[1]/table//td')
    for x in table:
        if x.get_attribute("data-id") and datetime.fromtimestamp(int(x.get_attribute("data-id")[:-3])).strftime(
                "%Y-%m-%d") == check_in_time:
            x.click()

    # Waits for Datetime widget and select check Out date
    ### A voir 
    driver.find_element_by_xpath('//*[@id="frm"]/div[3]/div/div[1]/div[2]/div[2]/div/div[1]/div/div[2]').click()

    WebDriverWait(driver, 20).until(EC.element_to_be_clickable(
        (By.XPATH, '//*[@id="frm"]/div[3]/div/div[1]/div[2]/div[2]/div/div[2]/div[1]/div')))
    table = driver.find_elements_by_xpath('//*[@id="frm"]/div[3]/div/div[1]/div[2]/div[2]/div/div[2]/div[2]/'
                                          'div[3]/div/div/div[1]/table//td')
    for x in table:
        if x.get_attribute("data-id") and datetime.fromtimestamp(int(x.get_attribute("data-id")[:-3])).strftime(
                "%Y-%m-%d") == check_out_time:
            x.click()

    # Click Search Button
    driver.find_element_by_class_name('sb-searchbox__button').click()

任何帮助,将不胜感激。

标签: pythonseleniumbeautifulsoupwebdriver

解决方案


driver.get("https://www.booking.com/")

# Enter City Name
driver.find_element_by_css_selector("#ss").send_keys(city)

# Wait until autosuggestion come and click on first suggestion
condition = EC.visibility_of_element_located(
   (By.CSS_SELECTOR, '#ss + ul > li:nth-child(1)'))

WebDriverWait(driver, 20).until(condition).click()

check_in_date = datetime
    .fromtimestamp(int(time.time())).strftime("%Y-%m-%d")
check_out_date = datetime
    .fromtimestamp(int(time.time()) + 604800).strftime("%Y-%m-%d")

# choose check in date
select_date(check_in_date)

# choose check out date
select_date(check_out_date, False)

功能select_date

def select_date(date_to_select, isCheckInDate=True):
    data_mode = "checkin" if isCheckInDate else "checkout"

    # Wait datepicker visible
    try:
        locator = 'div[data-mode="{0}"] + div'.format(data_mode)
        WebDriverWait(driver, 10)
            .until(EC.visibility_of_element_located((By.CSS_SELECTOR, locator)))

    except TimeoutException:
        # click the `+` button to display the datepicker
        locator = 'div[data-mode="{0}"] button.sb-date-field__icon-btn'.format(data_mode)

        driver.find_element_by_css_selector(locator).click()

    dateFound = False

    # iterate 12 months
    for i in rang(0, 12):

        # the datepicker which will display two month per time
        # find the first visible month in datepicker

        locator = 'div[data-mode="{0}"] + div div.c2-calendar-inner'.format(data_mode)
        style = driver.find_element_by_css_selector(locator).get_attribute('style')

        margin_left = re.search(r'(\d+)', style).group(1)

        # find all days in first visible month indatepicker
        locator = 'div[data-mode="{0}"] + div div[data-offset="{1}"]' +
                  ' td[data-id]:not(.c2-day-s-disabled)'.format(data_mode, margin_left)

        days = driver.find_elements_by_css_selector(locator)

        for day in days:
            data_id = day.get_attribute("data-id")
            date = datetime.fromtimestamp(int(data_id[:-3])).strftime("%Y-%m-%d")
            print 'iterate date: ' + date

            if date == date_to_select:
                day.click()
                dateFound = True
                return

        # if not found in first visible month,
        # click the right arrow to scroll month 
        locator = 'div[data-mode="{0}"] + div  div.c2-button-further'.format(data_mode)
        driver.find_element_by_css_selector(locator).click()

    if dateFound == False:
        print 'Not found {0} date: {1}'.format(data_mode, date_to_select)

推荐阅读