You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python Selenium单步调试正常 直接运行代码失效问题排查

问题根因

单步调试正常、直接运行失效是典型的页面加载时序不匹配问题:

  • 单步调试时,每步操作之间的停留时间足够浏览器完成登录提交、页面跳转、侧边栏日历导航项渲染,执行查找元素逻辑时目标节点已经存在于DOM中,所以能正常拿到结果。
  • 直接全速运行时,触发回车登录后代码不会等待页面加载完成,会立刻执行查找app-navigation-entry__title元素的逻辑,此时登录后的日历页面还没跳转完成,对应元素根本没渲染出来,find_elements会直接返回空列表,看起来就像这行代码没有执行。

你的代码还存在3个会引发异常的隐性问题:

  1. 初始化Chrome驱动时参数拼写错误:excutable_path是错误写法,正确参数名是executable_path,漏了字母e。实际上undetected_chromedriver会自动匹配当前Chrome版本下载对应驱动,不需要手动指定驱动路径。
  2. 新版Chrome无头模式需要添加专属启动参数,否则会被站点的反爬机制识别拦截,导致页面加载异常。
  3. 变量命名用了Python内置类型名list,会覆盖内置的列表构造方法,容易引发难以排查的隐性bug。
修复方案

不要用硬编码的time.sleep()等待,改用Selenium的显式等待,指定等待目标元素加载完成后再执行后续逻辑,修复后的完整代码如下:

import undetected_chromedriver as uc
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC


if __name__ == '__main__':
    calendar_list = []
    # 替换成你自己的下载目录路径
    download_path = r"C:\Users\Dimitri\Documents\Programme C++\clis\extraction+sql\ressources"

    options = uc.ChromeOptions()
    pref = {"download.default_directory": download_path}
    options.add_experimental_option("prefs", pref)
    # 新版Chrome无头模式必须添加的参数
    options.add_argument("--headless=new")
    options.add_argument("--disable-gpu")
    options.add_argument("--window-size=1920,1080")
    
    driver = uc.Chrome(options=options)
    wait = WebDriverWait(driver, 15) # 最长等待15秒,每0.5秒检查一次条件是否满足
    try:
        driver.get("https://framagenda.org/login?redirect_url=/apps/calendar/dayGridMonth/now")
        # 等待用户名输入框加载完成再输入
        user = wait.until(EC.presence_of_element_located((By.ID, "user")))
        user.send_keys("user@gmail.com")
        # 等待密码输入框加载完成再输入
        pwd = wait.until(EC.presence_of_element_located((By.ID, "password")))
        pwd.send_keys("test123")
        pwd.send_keys(Keys.RETURN)
        
        # 等待登录完成、侧边栏日历条目全部加载完成
        nav_entries = wait.until(EC.presence_of_all_elements_located((By.CLASS_NAME, "app-navigation-entry__title")))
        for entry in nav_entries:
            calendar_list.append(entry.text)

        print("页面标题:", driver.title)
        print("获取到的日历列表:", calendar_list)

        for cal_name in calendar_list:
            driver.get(f"https://framagenda.org/remote.php/dav/calendars/Dimitri%20L./{cal_name.lower()}/?export")
    finally:
        # 操作完成记得关闭浏览器释放资源
        driver.quit()
补充说明

你代码里加的if __name__ == '__main__'是Python脚本的标准入口判断,作用是:只有当你直接运行当前脚本文件时,缩进块内的代码才会执行;如果这个脚本被其他Python文件作为模块导入,这段代码不会自动运行。由于undetected_chromedriver底层依赖多进程机制,这个判断是必须添加的,否则会出现反复启动浏览器、进程死锁的异常,你之前的添加操作是正确的。


内容的提问来源于stack exchange,提问作者dim lanier

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 21:24:29