使用Selenium和Python修改Google Travel网站日期的技术问题
解决Google Travel酒店爬虫的日期选择问题
问题排查
首先看你的代码里有个明显错误:把酒店名称search_query[j]传给了日期输入框,完全搞混了变量;另外Google Travel的日期输入框是受控组件,直接send_keys经常不生效,加上页面元素可能有遮挡,才会触发ElementClickInterceptedException;还有用固定time.sleep等待页面加载,很容易因加载慢导致元素未就绪。
修复方案
1. 修正变量传递
把checkinElement.send_keys(search_query[j])改成checkinElement.send_keys(checkin_query[j]),确保日期参数传给日期输入框。
2. 用显式等待替代固定休眠
用WebDriverWait等待元素可交互,比固定休眠更可靠,不会浪费时间也不会因加载慢出错。
3. 解决日期输入的交互问题
如果直接点击输入框被遮挡,用ActionChains模拟鼠标移动点击;要是输入框还是不响应,就用JavaScript直接设置值并触发变化事件,绕过受控组件的限制。
4. 优化浏览器实例
别每次循环都新建浏览器,初始化一次复用就行,提升爬取效率。
修正后的完整代码
import time 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.webdriver.common.action_chains import ActionChains checkin_query = ['Tue, Aug 1', 'Wed, Aug 2', 'Thu, Aug 3'] search_query = ['JW Marriott Mumbai', 'Sofitel Mumbai'] options = webdriver.ChromeOptions() # 无头模式需加窗口大小参数,否则元素可能不可见 # options.add_argument('--headless') # options.add_argument('--window-size=1920,1080') # 只初始化一次浏览器 browser = webdriver.Chrome(options=options) wait = WebDriverWait(browser, 10) try: for checkin_date in checkin_query: for hotel in search_query: browser.get('https://www.google.com/travel/search') # 等待搜索框可点击,输入酒店名称 search_element = wait.until(EC.element_to_be_clickable((By.XPATH, '//input[contains(@placeholder,"Search for places, hotels and more")]'))) search_element.clear() search_element.send_keys(hotel) time.sleep(1) # 给下拉选项加载留时间 # 选择第一个搜索结果 dropdown_option = wait.until(EC.element_to_be_clickable((By.XPATH, '//li[@role="option"]'))) dropdown_option.click() time.sleep(2) # 等待页面跳转加载 # 处理日期输入:先尝试模拟点击+输入,失败则用JS强制设置 try: checkin_element = wait.until(EC.element_to_be_clickable((By.XPATH, '//input[contains(@placeholder,"Check-in")]'))) # 用ActionChains绕过元素遮挡 ActionChains(browser).move_to_element(checkin_element).click().perform() checkin_element.clear() checkin_element.send_keys(checkin_date) checkin_element.send_keys('\n') # 回车确认 except: # JS直接设置值并触发变化事件 checkin_element = wait.until(EC.presence_of_element_located((By.XPATH, '//input[contains(@placeholder,"Check-in")]'))) browser.execute_script("arguments[0].value = arguments[1];", checkin_element, checkin_date) browser.execute_script("arguments[0].dispatchEvent(new Event('change'));", checkin_element) time.sleep(2) # 可替换为等待价格元素出现的显式等待 print(f"已完成酒店【{hotel}】入住日期【{checkin_date}】的设置") # 这里可以添加抓取酒店价格的逻辑 finally: # 最后关闭浏览器 browser.quit()
额外提示
- 频繁操作可能触发Google反爬,建议在循环中加入随机延迟(比如
random.uniform(1,3)) - 若需要选择退房日期,可复用日期输入的逻辑,把XPath改成
//input[contains(@placeholder,"Check-out")]
内容的提问来源于stack exchange,提问作者Siddhesh Menon
相关产品推荐
相关产品推荐

