使用Selenium操作Booking.com时搜索内容提交后消失的问题求助
Booking.com Selenium自动化:搜索框输入后触发搜索内容被清空的问题解决
问题概述
在自动化操作Booking.com时,已成功向搜索框输入内容,但按下回车键或点击搜索按钮后,输入内容被清空,搜索未正常执行;尝试替换回车为点击搜索按钮、等待元素可点击后操作,均无效。
原有代码
from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.common.keys import Keys from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC import time import translateXMLfile from flask import Flask, jsonify from selenium.webdriver.chrome.options import Options def setup_driver(self): opts = Options() # Use webdriver.ChromeOptions() if self.HEADLESS: opts.add_argument('--headless') opts.add_argument("--window-size=%s" % self.WINDOW_SIZE) self.driver = webdriver.Chrome(options=opts) self.driver.maximize_window() self.driver.get('https://www.booking.com') time.sleep(2) def select_dates(self): wait = WebDriverWait(self.driver, 5) date = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, 'button[data-testid="date-display-field-end"]'))) date.click() next_button = self.driver.find_element(By.CSS_SELECTOR, "button[class='a83ed08757 c21c56c305 f38b6daa18 d691166b09 f671049264 deab83296e f4552b6561 dc72a8413c f073249358']") next_button.click() inday = translateXMLfile.iday oday = translateXMLfile.oday formatted_inday = f"{inday:02d}" formatted_oday = f"{oday:02d}" date_element_xpath = f"//span[contains(@aria-label, '{formatted_inday} October 2023')]" date_element_xpatho = f"//span[contains(@aria-label, '{formatted_oday} October 2023')]" checkin_date = self.driver.find_element(By.XPATH, date_element_xpath) checkout_date = self.driver.find_element(By.XPATH, date_element_xpatho) checkin_date.click() checkout_date.click() search = self.driver.find_element(By.ID,':re:') search.send_keys(translateXMLfile.name) self.driver.save_screenshot('1st test.png') search.send_keys(Keys.RETURN) time.sleep(10) self.driver.save_screenshot('2nd test.png')
核心原因
- 动态定位失效:搜索框使用的ID
:re:是页面动态生成的,每次加载都会变化,导致后续操作定位到错误元素或触发页面重置 - 反爬拦截:Booking.com的反自动化检测识别到Selenium特征后,会重置表单内容
- 操作逻辑不完整:未完整模拟用户操作流程(如未激活搜索框直接输入、回车触发了错误的表单事件)
解决步骤
1. 更换稳定的元素定位方式
放弃动态ID,使用页面中固定的data-testid属性定位元素,避免定位失效:
# 搜索框定位(替换原有ID定位) search_box = wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, 'input[data-testid="destination_form_field"]'))) # 先激活搜索框再操作 search_box.click() search_box.clear() search_box.send_keys(translateXMLfile.name)
2. 添加反爬配置,隐藏Selenium特征
在setup_driver方法中添加Chrome选项,绕过自动化检测:
def setup_driver(self): opts = Options() if self.HEADLESS: opts.add_argument('--headless') # 无头模式需配置真实UA opts.add_argument('user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36') opts.add_argument("--window-size=%s" % self.WINDOW_SIZE) # 隐藏自动化标识 opts.add_argument('--disable-blink-features=AutomationControlled') opts.add_experimental_option("excludeSwitches", ["enable-automation"]) opts.add_experimental_option('useAutomationExtension', False) self.driver = webdriver.Chrome(options=opts) # 移除navigator.webdriver标识 self.driver.execute_script("Object.defineProperty(navigator, 'webdriver', {get: () => undefined})") self.driver.maximize_window() self.driver.get('https://www.booking.com') # 用显式等待替代time.sleep,确保页面加载完成 wait = WebDriverWait(self.driver, 10) wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, 'input[data-testid="destination_form_field"]')))
3. 模拟真实用户点击搜索按钮
避免使用回车,定位稳定的搜索按钮并等待可点击后触发:
# 输入内容后点击搜索按钮 search_button = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, 'button[data-testid="search-button"]'))) search_button.click() # 等待搜索结果页面加载 wait.until(EC.url_contains('searchresults'))
4. 优化日期选择的定位逻辑
替换冗长易变的class选择器,使用data-testid定位日期控件:
# 日期触发按钮 date_trigger = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, 'button[data-testid="date-display-field-end"]'))) date_trigger.click() # 下月切换按钮 next_month_btn = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, 'button[data-testid="datepicker-next-month"]'))) next_month_btn.click()
修改后的完整select_dates方法
def select_dates(self): wait = WebDriverWait(self.driver, 10) # 选择日期 date_trigger = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, 'button[data-testid="date-display-field-end"]'))) date_trigger.click() next_month_btn = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, 'button[data-testid="datepicker-next-month"]'))) next_month_btn.click() inday = translateXMLfile.iday oday = translateXMLfile.oday formatted_inday = f"{inday:02d}" formatted_oday = f"{oday:02d}" # 定位入住/退房日期 checkin_date = wait.until(EC.element_to_be_clickable((By.XPATH, f"//span[contains(@aria-label, '{formatted_inday} October 2023')]"))) checkin_date.click() checkout_date = wait.until(EC.element_to_be_clickable((By.XPATH, f"//span[contains(@aria-label, '{formatted_oday} October 2023')]"))) checkout_date.click() # 处理搜索框 search_box = wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, 'input[data-testid="destination_form_field"]'))) search_box.click() search_box.clear() search_box.send_keys(translateXMLfile.name) self.driver.save_screenshot('1st test.png') # 点击搜索按钮 search_button = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, 'button[data-testid="search-button"]'))) search_button.click() # 等待搜索结果加载完成 wait.until(EC.url_contains('searchresults')) self.driver.save_screenshot('2nd test.png')
内容的提问来源于stack exchange,提问作者ADI
相关产品推荐
相关产品推荐

