Selenium中.send_keys()仅输入字符串首字符问题排查(Python)
谷歌航班输入框填充脚本不稳定问题解析
问题描述
我正在编写脚本填充谷歌航班页面的目的地输入框,但代码表现极不稳定:有时能正常输入完整字符串“Barcelona”,有时仅输入首字母“B”,偶尔还会出现错误提示:“element click intercepted: Element (redacted html code) is not clickable at point (547, 472). Other element would receive the click”。
用户提供的原始代码:
from selenium import webdriver from selenium.webdriver.chrome.service import Service from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.common.by import By from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.common.keys import Keys from selenium.webdriver.chrome.options import Options import os #Give path to chrome driver using service argument so it doesn't throw the path deprecation warning script_dir = os.path.dirname(__file__) #<-- absolute dir the script is in chromedriver_path = '/path/to/chromedriver' abs_chromedriver_path = os.path.join(script_dir, chromedriver_path) driver_service = Service(executable_path = abs_chromedriver_path) browser = webdriver.Chrome(service = driver_service) url = 'https://www.google.com/travel/flights' selector = "div[aria-placeholder='Where from?'] input" phrase = "Barcelona" browser.get(url) WebDriverWait(browser, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, selector))).click() WebDriverWait(browser, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, selector))).send_keys(phrase) WebDriverWait(browser, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, selector))).send_keys(Keys.ENTER)
异常原因分析
- 元素点击被拦截:谷歌航班页面加载时可能弹出cookie授权窗口、欢迎提示等遮罩元素,这些元素会覆盖在输入框上方,导致Selenium尝试点击输入框时,实际点击到了遮罩元素,触发
element click intercepted错误。 - 输入框未完全激活:
element_to_be_clickable仅判断元素处于可点击状态,但有时元素还未真正获取焦点,此时调用send_keys会导致输入不完整(仅输入首字母)。 - 重复等待导致元素实例不一致:每次操作都重新调用
WebDriverWait获取元素,可能拿到不同状态的元素引用,操作不同步引发输入异常。
修复方案及优化代码
针对上述问题,优化后的代码如下:
from selenium import webdriver from selenium.webdriver.chrome.service import Service from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.common.by import By from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.common.keys import Keys import os script_dir = os.path.dirname(__file__) chromedriver_path = '/path/to/chromedriver' abs_chromedriver_path = os.path.join(script_dir, chromedriver_path) driver_service = Service(executable_path=abs_chromedriver_path) browser = webdriver.Chrome(service=driver_service) url = 'https://www.google.com/travel/flights' selector = "div[aria-placeholder='Where from?'] input" phrase = "Barcelona" browser.get(url) wait = WebDriverWait(browser, 20) # 处理可能出现的cookie授权弹窗 try: cookie_btn = wait.until(EC.element_to_be_clickable((By.XPATH, "//button[contains(text(), '接受') or contains(text(), 'Accept')]"))) cookie_btn.click() except: pass # 无弹窗则跳过 # 等待输入框可见并获取元素实例 origin_input = wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, selector))) # 通过JS强制让输入框获取焦点 browser.execute_script("arguments[0].focus();", origin_input) # 清除输入框原有内容 origin_input.clear() # 输入目标文本 origin_input.send_keys(phrase) # 等待下拉建议列表加载完成后再按回车确认 wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, "div[role='listbox']"))) origin_input.send_keys(Keys.ENTER)
优化说明
- 新增弹窗处理:提前处理cookie授权弹窗,避免其遮挡输入框;
- 统一元素引用:仅获取一次输入框元素实例,避免重复等待导致的状态不一致;
- 更精准的等待条件:使用
visibility_of_element_located确保元素完全可见,而非仅可点击; - 强制聚焦输入框:通过JS脚本强制输入框获取焦点,保证输入操作的有效性;
- 清除原有内容:输入前清除输入框默认值,避免干扰;
- 等待下拉建议:确认谷歌航班的目的地建议列表加载完成后再按回车,确保输入内容被正确识别。
内容的提问来源于stack exchange,提问作者Fox
相关产品推荐
相关产品推荐

