Selenium Chrome无头模式下点击按钮无法打开新窗口、window_handles无法识别新窗口的解决方案咨询
我遇到了一个头疼的问题:在Python的Selenium代码里初始化Chrome WebDriver时配置了一堆参数,打开网页后点击某个按钮——如果注释掉chrome_options.add_argument("--headless")这行,按钮点击后确实会弹出新窗口,之后我切换到driver.window_handles[-1]也能正常操作。但一旦开启无头模式,driver.window_handles就只返回1个窗口,哪怕我加了长达60秒的延迟也没用,导致后续代码因为找不到新窗口里的按钮直接崩溃。
我的代码如下:
chrome_options = webdriver.ChromeOptions() chrome_options.add_argument("--headless") chrome_options.add_argument("--disable-gpu") chrome_options.add_argument("--no-sandbox") chrome_options.add_argument('--disable-dev-shm-usage') chrome_options.add_argument("--start-maximized") chrome_options.add_experimental_option("excludeSwitches", ["enable-automation"]) chrome_options.add_experimental_option('useAutomationExtension', False) chrome_options.add_argument(f"user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36 Edg/131.0.0.0") chrome_options.add_argument('--window-size=1920,1080') driver = webdriver.Chrome(options=chrome_options) wait = WebDriverWait(driver, 30) def main(): driver.get("...") time.sleep(60) # 不管延迟多久,结果都一样 button = wait.until(ec.element_to_be_clickable((By.XPATH, "..."))) button.click() # 点击上面的按钮后,应该会打开一个新窗口 time.sleep(60) print(f"WINDOW HANDLES: {driver.window_handles}") # 无头模式下输出 WINDOW HANDLES: ['24931185E13B5F865C2AF60824C63581'] # 正常模式下输出 WINDOW HANDLES: ['2C26F32DB25AF6BA3385E57788A9A0F0', '573A622D02011B22274612B2AA81C8DC'] driver.switch_to.window(driver.window_handles[-1]) button = wait.until(ec.element_to_be_clickable((By.XPATH, "..."))) button.click() # 无头模式下会抛出异常,因为新窗口根本没打开
请问怎么在Selenium无头模式下,让按钮点击触发的新窗口正常打开,并且能成功切换到这个新窗口?
解决方案建议
作为经常处理这类问题的开发者,我给你几个实用的排查和解决方向:
禁用无头模式的弹窗拦截:Chrome无头模式默认可能会拦截新窗口弹窗,你可以添加参数允许弹窗:
chrome_options.add_argument("--disable-popup-blocking")更换为Chrome新无头模式:旧的
--headless模式和正常浏览器的行为差异较大,Chrome 96及以上版本支持更贴近正常模式的新无头模式,替换参数试试:chrome_options.add_argument("--headless=new")优化用户代理设置:你当前设置的UA包含Edge标识,可能被页面识别为不同环境,换成纯Chrome的UA:
chrome_options.add_argument("user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36")用智能等待替代固定延迟:不要依赖
time.sleep,而是用WebDriverWait等待窗口数量变化,确保新窗口加载完成后再切换:# 点击前记录原始窗口列表 original_windows = driver.window_handles button.click() # 等待窗口数量增加 wait.until(lambda d: len(d.window_handles) > len(original_windows)) # 找到新窗口并切换 new_window = next(window for window in driver.window_handles if window not in original_windows) driver.switch_to.window(new_window)模拟真实鼠标交互点击:有些页面的按钮需要真实的鼠标移动+点击触发,无头模式下直接
click()可能失效,试试用ActionChains:from selenium.webdriver.common.action_chains import ActionChains button = wait.until(ec.element_to_be_clickable((By.XPATH, "..."))) ActionChains(driver).move_to_element(button).click().perform()
备注:内容来源于stack exchange,提问作者tegularis

