使用Selenium自动化Expedia日期选择器时send_keys方法失效问题求助
Hey there! I’ve struggled with Expedia’s finicky date picker widget before—those custom UI elements don’t always play nice with basic send_keys calls like simpler input fields do. Let’s figure out why your current code isn’t working and get you up and running.
Why Your Current Approach Fails
The elements you’re targeting (#d1-btn and #d2-btn) are trigger buttons, not actual input fields. When you click them, they open the calendar widget, but sending keys directly to the button itself does nothing—there’s no input attached to it to receive the text.
Solution 1: Target the Hidden Input Field
Expedia typically hides a real <input> element behind the button that you can interact with directly once the calendar is open. Here’s how to adjust your code:
from selenium import webdriver from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.common.by import By from selenium.webdriver.common.keys import Keys # Travel dates first_date = '08/29/2021' last_date = '09/03/2021' driver = webdriver.Chrome('./chromedriver') driver.maximize_window() wait = WebDriverWait(driver, 10) url = 'https://expedia.com' driver.get(url) # Open the start date picker start_date_btn = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, "#d1-btn"))) start_date_btn.click() # Target the hidden input field (usually has ID "d1") start_date_input = wait.until(EC.visibility_of_element_located((By.ID, "d1"))) start_date_input.send_keys(Keys.CONTROL + 'a') # Select existing text start_date_input.send_keys(Keys.BACK_SPACE) # Clear it start_date_input.send_keys(first_date) # Input your date # Repeat for end date end_date_btn = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, "#d2-btn"))) end_date_btn.click() end_date_input = wait.until(EC.visibility_of_element_located((By.ID, "d2"))) end_date_input.send_keys(Keys.CONTROL + 'a') end_date_input.send_keys(Keys.BACK_SPACE) end_date_input.send_keys(last_date)
Solution 2: Click Dates Directly in the Calendar Widget
If the hidden input approach doesn’t work (Expedia sometimes updates their DOM), you can interact directly with the calendar’s date cells. This requires making sure you’re on the correct month first:
from selenium import webdriver from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.common.by import By # Travel dates first_date = '08/29/2021' last_date = '09/03/2021' # Split dates into month/day/year for easier handling first_month, first_day, first_year = first_date.split('/') last_month, last_day, last_year = last_date.split('/') driver = webdriver.Chrome('./chromedriver') driver.maximize_window() wait = WebDriverWait(driver, 10) url = 'https://expedia.com' driver.get(url) # Handle start date start_date_btn = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, "#d1-btn"))) start_date_btn.click() # Wait for calendar to load calendar = wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, "[data-stid='date-picker-month']"))) # Optional: Add logic here to switch months if your date isn't visible # For example, click the "next month" button until the correct month is displayed # Click the start date start_date_cell = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, f"[data-day='{first_day}'][data-month='{int(first_month)-1}'][data-year='{first_year}']"))) start_date_cell.click() # Handle end date (calendar should still be open) last_date_cell = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, f"[data-day='{last_day}'][data-month='{int(last_month)-1}'][data-year='{last_year}']"))) last_date_cell.click()
Pro Tips
- Always use your browser’s DevTools (F12) to inspect the actual elements—Expedia’s DOM changes occasionally, so double-check selectors like
#d1or thedata-*attributes on date cells. - Prefer
element_to_be_clickableoverpresence_of_element_locatedwhen interacting with buttons or date cells—elements can exist in the DOM but still be unclickable. - If your target date is in a future/past month, add a loop to click the next/previous month buttons until the correct month is displayed.
内容的提问来源于stack exchange,提问作者Lenny_Liu

