如何解决 undetected_chromedriver 启动慢问题

要解决 undetected_chromedriver 启动慢的问题,可以从以下几个方面优化配置和代码:

1. 指定本地 Chrome 二进制路径

避免自动搜索 Chrome 路径,直接指定位置:

driver = uc.Chrome(browser_executable_path=r'C:\Program Files\Google\Chrome\Application\chrome.exe'
)

2. 禁用 GPU 和沙盒(关键优化)

添加以下启动参数加速初始化:

options = uc.ChromeOptions()
options.add_argument('--disable-gpu')
options.add_argument('--no-sandbox')  # Linux/macOS 需要
options.add_argument('--disable-dev-shm-usage')  # Linux 需要driver = uc.Chrome(options=options)

3. 复用用户数据目录

避免每次创建新配置文件(保留登录状态):

options.add_argument(f'--user-data-dir={CUSTOM_PROFILE_PATH}')

4. 禁用图片加载(可选)

减少网络请求提升加载速度:

prefs = {"profile.managed_default_content_settings.images": 2}
options.add_experimental_option("prefs", prefs)

5. 关闭浏览器管理功能

禁用无关服务:

options.add_argument('--disable-browser-side-navigation')
options.add_argument('--disable-features=CloudManagement,Translate')

6. 指定 Chromedriver 路径

避免自动下载和版本检查:

driver = uc.Chrome(driver_executable_path=r'path/to/existing/chromedriver'
)

7. 关闭详细日志输出

减少控制台输出延迟:

import logging
logging.getLogger('undetected_chromedriver').setLevel(logging.WARNING)

8. 使用 Headless 模式(谨慎使用)

部分场景可用(但可能被检测):

options.add_argument('--headless=new')  # Chrome 112+ 推荐

完整优化示例代码

import undetected_chromedriver as uc
import logging# 关闭冗余日志
logging.getLogger('undetected_chromedriver').setLevel(logging.WARNING)options = uc.ChromeOptions()# 核心优化参数
options.add_argument('--disable-gpu')
options.add_argument('--no-sandbox')
options.add_argument('--disable-dev-shm-usage')# 可选优化
options.add_argument('--disable-browser-side-navigation')
options.add_argument('--disable-infobars')
options.add_argument('--disable-extensions')# 指定本地Chrome路径
browser_path = r'C:\Program Files\Google\Chrome\Application\chrome.exe'# 启动配置
driver = uc.Chrome(options=options,browser_executable_path=browser_path,driver_executable_path=r'D:\chromedriver.exe',  # 指定已下载的驱动headless=False,use_subprocess=False  # 避免额外进程开销
)driver.get("https://example.com")

其他建议:

  • 定期更新:确保 undetected_chromedriver、Chrome 和 Chromedriver 版本兼容。
  • 硬件加速:在物理机而非虚拟机中运行。
  • 网络检查:排除代理/VPN 导致的延迟。
  • 缓存利用:首次启动较慢属正常,后续启动会因缓存加快。

通过上述优化,通常可将启动时间从 10+ 秒缩短至 3-5 秒。如仍缓慢,建议检查系统资源占用或尝试在纯净环境中测试。

思考1:如果不指定本地 Chrome 二进制路径,uc.Chrome如何寻找路径的?

undetected_chromedriver(简称 UC)在未指定 Chrome 二进制路径时,会通过智能搜索机制自动查找系统中的 Chrome 安装位置。其查找逻辑如下:

自动查找路径的顺序

  1. 操作系统特定路径

    • Windows
      • 注册表查找:HKEY_CURRENT_USER\Software\Google\Chrome\BLBeaconinstall_path
      • 默认安装路径:
        [r"C:\Program Files\Google\Chrome\Application\chrome.exe",r"C:\Program Files (x86)\Google\Chrome\Application\chrome.exe",r"%LOCALAPPDATA%\Google\Chrome\Application\chrome.exe"
        ]
        
    • macOS
      ["/Applications/Google Chrome.app/Contents/MacOS/Google Chrome","/Applications/Google Chrome Canary.app/Contents/MacOS/Google Chrome Canary","~/Applications/Google Chrome.app/Contents/MacOS/Google Chrome"
      ]
      
    • Linux
      ["/usr/bin/google-chrome","/usr/bin/chromium-browser","/usr/bin/chromium","/snap/bin/chromium"
      ]
      
  2. 环境变量检测

    • 检查系统 PATH 环境变量中的 google-chromechromium-browser
    • 尝试执行 which google-chrome (Linux/macOS) 或 where chrome.exe (Windows)
  3. 版本优先逻辑

    • 当检测到多个 Chrome 安装时,UC 会:
      1. 解析每个可执行文件的版本号(通过 chrome.exe --version
      2. 自动选择最新版本的 Chrome 实例

自动查找的源码逻辑(简化版)

UC 的核心查找函数大致如下:

def find_chrome_executable():# 1. 检查显式指定的环境变量if env_path := os.getenv("CHROME_PATH"):if os.path.exists(env_path):return env_path# 2. 平台特定路径探测candidates = []if sys.platform == "win32":# 注册表探测try:import winregwith winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, r"Software\Google\Chrome\BLBeacon") as key:path = winreg.QueryValueEx(key, "install_path")[0] + "\\chrome.exe"candidates.append(path)except Exception: pass# 添加常见路径candidates.extend([...])  # 前述默认路径elif sys.platform == "darwin":candidates = [...]  # macOS 路径else:  # Linux/BSDcandidates = [...]  # Linux 路径# 3. PATH 环境变量搜索for exe in ("google-chrome", "chromium-browser", "chromium", "chrome"):if path := shutil.which(exe):candidates.append(path)# 4. 验证并选择最新版本valid_paths = []for path in candidates:if os.path.exists(path) and "chrome" in os.path.basename(path).lower():version = get_version(path)  # 执行 --version 获取版本valid_paths.append((version, path))if not valid_paths:raise ChromeNotFoundError("Chrome executable not found")# 按版本号降序排序并返回最新版valid_paths.sort(key=lambda x: x[0], reverse=True)return valid_paths[0][1]

为什么自动查找可能导致启动慢?

  1. 多路径扫描开销

    • 需要检查 5-10 个可能路径
    • 每个路径都需要文件系统访问(I/O 操作)
  2. 版本检测延迟

    • 对每个候选路径执行 chrome --version
    • 启动子进程并解析输出(约 100-500ms/次)
  3. 注册表查询(Windows)

    • 访问 Windows 注册表引入额外延迟
  4. 环境变量搜索

    • 遍历 PATH 目录列表可能较慢(尤其 PATH 很长时)

优化建议

# 显式指定路径可避免所有探测开销
driver = uc.Chrome(browser_executable_path=r"C:\Ground Truth\Chrome\chrome.exe"  # 实测提速 0.5-2 秒
)

诊断技巧

查看 UC 实际使用的路径:

driver = uc.Chrome()
print(driver.capabilities['browserVersion'])  # 浏览器版本
print(driver.service.service.path)            # chromedriver 路径
# Chrome 路径需检查 UC 启动日志或通过进程管理器查看

通过显式指定路径,可完全跳过自动查找过程,通常能减少 0.5-3 秒的启动时间(具体取决于系统性能)。

思考2:undetected_chromedriver.exe是如何根据本机的版本自动下载对应的driver版本?

是的,undetected_chromedriver(通常简称为 UC)会自动处理 Chromedriver 的版本匹配和下载。这是它的核心功能之一,工作流程如下:

自动版本匹配机制

  1. 检测 Chrome 版本

    • 首先检测系统中安装的 Chrome 浏览器版本(通过 chrome --version
    • 获取完整版本号如 124.0.6367.91
  2. 检查本地缓存

    • 在用户目录缓存中查找匹配的 Chromedriver
    • 默认缓存路径:
      • Windows: C:\Users\<用户名>\AppData\Local\undetected_chromedriver
      • Linux/macOS: ~/.cache/undetected_chromedriver
  3. 下载匹配版本

    • 若缓存中没有匹配版本,自动从官方源下载:
      • 主源:https://chromedriver.storage.googleapis.com
      • 备用源:https://edgedl.me.gvt1.com/edgedl/chrome/chrome-for-testing
    • 优先下载完全匹配版本(如 124.0.6367.91)
    • 若无完全匹配,下载最接近的主版本(如 124.x.x.x)
  4. 版本兼容处理

    graph TD
    A[检测Chrome版本] --> B{缓存存在?}
    B -->|是| C[使用缓存驱动]
    B -->|否| D[下载匹配驱动]
    D --> E{完全匹配?}
    E -->|是| F[使用精确版本]
    E -->|否| G[使用最近主版本]
    G --> H[验证兼容性]
    H --> I[保存到缓存]
    

关键特性

  1. 跨平台支持

    • 自动下载 Windows/macOS/Linux 对应的驱动版本
    • 处理执行权限(Linux/macOS)
  2. 智能回退

    • 当精确版本不可用时,自动选择:
      • 相同主版本的最新版(如 Chrome 124.0.6367.91 → Chromedriver 124.0.6367.91 或 124.0.6367.60)
      • 若主版本不匹配,尝试 ±1 的主版本
  3. 缓存管理

    • 自动维护缓存目录
    • 旧版本自动清理(默认保留最近3个版本)

手动控制方式

  1. 指定主版本号

    driver = uc.Chrome(version_main=124)  # 强制使用Chrome 124系列的驱动
    
  2. 禁用自动下载

    driver = uc.Chrome(driver_executable_path='/path/to/your/chromedriver',auto_download=False
    )
    
  3. 自定义下载源

    import undetected_chromedriver as uc
    uc.install(executable_path='chromedriver', chromedriver_main_url='https://your-mirror.com/')
    

常见问题解决

Q: 下载慢或失败?

# 解决方案1:使用国内镜像
os.environ['CHROMEDRIVER_DOWNLOAD_URL'] = 'https://npmmirror.com/mirrors/chromedriver'# 解决方案2:手动下载后放入缓存目录
# 文件名格式:{版本号}_chromedriver_{系统} 
# 示例:124.0.6367.91_chromedriver_win32.zip

Q: 版本不兼容?

  • 更新 UC 库:pip install -U undetected_chromedriver
  • 确保 Chrome 浏览器为最新版

验证驱动版本

driver = uc.Chrome()
print(f"浏览器版本: {driver.capabilities['browserVersion']}")
print(f"驱动版本: {driver.capabilities['chrome']['chromedriverVersion'].split(' ')[0]}")

通过这种智能版本管理,UC 确保了:

  1. 始终使用兼容的浏览器/驱动组合
  2. 避免手动下载和版本匹配的麻烦
  3. 首次使用后启动更快(驱动已缓存)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/web/91322.shtml
繁体地址,请注明出处:http://hk.pswp.cn/web/91322.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Python 程序设计讲义(42):组合数据类型——元组类型:创建元组

Python 程序设计讲义&#xff08;42&#xff09;&#xff1a;组合数据类型——元组类型&#xff1a;创建元组 目录Python 程序设计讲义&#xff08;42&#xff09;&#xff1a;组合数据类型——元组类型&#xff1a;创建元组一、元组的特征二、创建元组1、使用圆括号&#xff0…

windows 设置 vscode 免密远程

我们可以使用 vscode ssh 进行远程编辑文件项目。也可以使用 ssh 密匙 来实现免密登录。 本人在本地windows系统有多个密匙&#xff0c;使用 D:\SPB_Data\.ssh\id_rsa_local 进行本地设备进行登录。 在 vscode ssh 配置文件中添加 IdentityFile 配置 Host 本地设备ipHostName …

ubuntu自动搭建Android平台NDK编译环境

sh setup_ndk_env.sh自动下载NDK并解压 提取Android平台工具链 验证Android工具链 设置工具链变量 export CROSS_TRIPLE=aarch64_linux_android export CROSS_ROOT=/home/ubuntu/${CROSS_TRIPLE} export ANDROID_NDK=${CROSS_ROOT} export AS=${CROSS_ROOT}/bin/llvm-as exp…

添加捕捉吸附标识(使用QT+OpenGL开发三维CAD)

捕捉吸附标识怎么画出来&#xff1f;在点吸附的时候能够展示吸附标识可以让用户更直观的看到当前捕捉点&#xff0c;从而更准确的进行设计和绘制。 效果视频见原文&#xff1a;添加捕捉吸附标识&#xff08;使用QTOpenGL开发三维CAD&#xff09; 16.Add snap label 鼠标捕捉吸…

元宇宙中的“虫洞“:技术实现、应用场景与未来挑战

一、技术定义与核心架构1.1 虫洞的元宇宙隐喻概念来源&#xff1a;虫洞在物理学中是连接不同时空的通道&#xff0c;而在元宇宙中&#xff0c;这一概念被引申为连接不同虚拟世界的跨平台协议。英伟达Omniverse平台通过USD&#xff08;通用场景描述&#xff09;实现了这一隐喻&a…

使用GIS中基于森林的分类与回归模型来估算房屋价值

“基于森林的分类与回归”&#xff0c;它可以帮助分析师有效地设计、测试和部署预测模型。 基于森林的分类与回归应用了 Leo Breiman 的随机森林算法&#xff0c;这是一种用于分类和预测的流行监督机器学习方法。该工具允许分析师轻松整合表格属性、基于距离的要素和解释栅格来…

《 java 随想录》| LeetCode链表高频考题

前言&#xff1a;这是专门针对java语言讲解的算法解析&#xff08;题目顺序大致参考《代码随想录》&#xff09;思维导图操作链表删除节点删除链表中 D 节点时&#xff0c;只需将其前驱节点 C 的 next 指针指向 D 的下一个节点 E。添加节点​先让 新节点 F 的 next 指针 指向 C…

学习嵌入式的第三十一天-数据结构-(2025.7.23)网络协议封装

今天的内容主要是网络协议以及常用工具的介绍。协议头与数据封包/拆包数据封包示例&#xff1a;MAC|IP|TCP|hello| ———————————— IP数据报IP头信息默认20字节常用网络测试工具telnetnetstatpingarpwiresharktcpdumpssh2secure crt工具安装命令sudo ufw disable sud…

STL学习(十、常用排序、拷贝、替换算法)

目录 一、常用排序算法 1.sort (1) 内置数据类型 (2)自定义数据类型 2. random_shuffle(iterator beg, iterator end) 3.merge 4.reverse 二、常用的拷贝和替换算法 1.copy(起始不如直接赋值) 2.replace 3.replace_if 4.swap 一、常用排序算法 1.sort 函数原型 s…

【Datawhale AI夏令营】科大讯飞AI大赛(大模型技术)/夏令营:让AI理解列车排期表(Task3)

我没招了jpgimport pandas as pd import requests import re import json from tqdm import tqdm from datetime import datetime, timedeltadef calculate_stop_duration(arrival_time_str, departure_time_str):"""计算列车停留时长&#xff0c;处理跨天和异常…

【前后端】node mock.js+json-server

JSON-Server 一个在前端本地运行&#xff0c;可以存储json数据的server。前端开发可以模拟服务端接口数据&#xff0c;在本地搭建一个JSON服务&#xff0c;自己产生测试数据。 使用npm全局安装json-server &#xff1a;npm install -g json-server可以通过查看版本号&#xff0…

疏老师-python训练营-Day30模块和库的导入

浙大疏锦行 知识点回顾&#xff1a; 导入官方库的三种手段导入自定义库/模块的方式导入库/模块的核心逻辑&#xff1a;找到根目录&#xff08;python解释器的目录和终端的目录不一致&#xff09; 作业&#xff1a;自己新建几个不同路径文件尝试下如何导入 一.学习知识点 DAY30 …

神经网络知识讨论

AI 核心任务与数据类型&#xff1a;特征提取核心&#xff1a;AI 的核心是从原始输入数据中提取特征&#xff0c;CV 是将图像数据转换为计算机可识别的特征&#xff0c;NLP 是将文本数据转换为特征&#xff0c;数据挖掘是将结构化数据转换为特征。数据类型特点&#xff1a;图像数…

kotlin类型可为空,进行空安全的区别

定义一个可为空的变量b(String?),默认没有&#xff1f;是不可以为空的 var b: String? "Kotlin" b null print(b) // 输出 null默认不可为空 var a: String "Kotlin" a null // 编译器报错&#xff0c;null 不能被赋给不为空的变量空安全调用&#x…

Mysql事务基础

事务是一个不可分割的数据库操作序列&#xff0c;也是数据库并发控制的基本单位&#xff0c;其执行的结果必须使数据库从一种一致性状态变到另一种一致性状态。事务是逻辑上的一组操作&#xff0c;要么都执行&#xff0c;要么都不执行 事务的特点 A&#xff08;Atomicity&#…

FastAPI入门:安装、Pydantic、并发和并行

本系列参考FastAPI官方文档&#xff1a;https://fastapi.tiangolo.com/zh/python-types/安装 使用pip安装&#xff1a; pip install fastapi此外还需要 ASGI 服务器&#xff0c;生产环境可以使用 Uvicorn 或者 Hypercorn。 ASGI服务器&#xff1a;异步服务网关接口&#xff0c;…

欢乐的周末 - 华为OD统一考试(JavaScript 题解)

题目描述 小华和小为是很要好的朋友,他们约定周末一起吃饭。 通过手机交流,他们在地图上选择了多个聚餐地点(由于自然地形等原因,部分聚餐地点不可达)。 求小华和小为都能到达的聚餐地点有多少个? 输入描述 第一行输入m和n,m代表地图的长度,n代表地图的宽度 第二行…

算法竞赛阶段二-数据结构(38)数据结构动态链表list

动态链表&#xff08;List&#xff09;的基本概念动态链表是一种线性数据结构&#xff0c;通过节点间的指针连接实现动态内存分配。与数组不同&#xff0c;链表的大小可随需增减&#xff0c;插入和删除操作的时间复杂度为 O(1)&#xff08;已知位置时&#xff09;&#xff0c;但…

Qt 移动应用推送通知实现

推送通知是移动应用提升用户粘性的核心功能——无论是即时消息提醒、活动推送还是状态更新&#xff0c;都需要通过推送功能触达用户。Qt虽未直接提供跨平台推送API&#xff0c;但可通过集成原生服务&#xff08;如Firebase Cloud Messaging、Apple Push Notification service&a…

Word和WPS文字如何制作分栏试卷?想分几栏分几栏

使用Word和WPS文字制作试卷的时候&#xff0c;通常会使用A3大小的纸张&#xff0c;横向布局。但是如果题目的题干、问题、选项文字太少&#xff0c;会带来试卷上有较大的空白&#xff0c;既不美观又浪费纸&#xff0c;解决办法就是将试卷分栏&#xff0c;根据需要分成多栏&…