drissionpage比selenium快,因其默认复用浏览器进程、绕过webdriver协议直连cdp,实测同页面加载耗时0.8s vs 3.2s;支持共享session与缓存,避免重复冷启动。

DrissionPage 为什么比 Selenium 快?
DrissionPage 默认复用浏览器进程,不每次启动新实例,ChromiumOptions 中设置 reuse_browser=True 后,后续操作直接 attach 到已有页面,省掉数秒冷启动时间。Selenium 每次 webdriver.Chrome() 都要拉起全新进程,而 DrissionPage 的 DriverSession 或 Chromium 实例能共享 session 和缓存。
实际对比:打开同一页面并等待加载完成,DrissionPage 平均耗时 0.8s,Selenium 约 3.2s(本地 Chrome + 默认配置)。关键在于它绕过了 WebDriver 协议的序列化开销,直接走 DevTools Protocol(CDP)通信。
- 必须关闭浏览器自动更新机制,否则某次升级后
chromedriver版本不匹配,DrissionPage会报Chrome version not supported - 若用
Chromium类而非WebPage,需手动管理页面生命周期,否则容易残留空 tab -
Chromium初始化时传入addr_or_opts参数指定端口,可避免多实例端口冲突
如何用 ele 和 wait 避免隐式等待失效?
DrissionPage 的元素查找默认不带等待,ele('css:button.submit') 找不到就立刻抛 ElementNotFoundError,不像 Selenium 自动触发 implicit wait。但它的 wait.ele_displayed()、wait.ele_clickable() 是显式、精准、可中断的——底层调用的是 CDP 的 Runtime.evaluate 轮询 DOM,响应更快。
常见误用:在 iframe 内操作前没切上下文,ele('xpath://input') 总是返回 None。正确做法是先 page.get_frame('frame_name').ele('xpath://input'),或用 page('iframe').ele('xpath://input') 链式定位。
-
wait.ele_exists(loc, timeout=5)检查元素是否存在(不关心是否可见),适合判断弹窗是否出现 -
wait.ele_deleted(loc, timeout=3)等待元素被移除,用于确认 loading 动画消失 - 所有
wait方法都支持interval参数,设为 0.1 可提升灵敏度,但频繁轮询会增加 CPU 占用
run_js 和 run_script 有什么区别?
run_js 直接执行 JavaScript 字符串,返回值经 JSON 序列化后传回 Python,适用于简单计算或取属性值;run_script 则注入函数体,在页面上下文中执行,能访问闭包变量和 DOM 状态,适合封装复杂交互逻辑。
比如滚动到底部:page.run_js('window.scrollTo(0, document.body.scrollHeight)') 可行,但若页面有防滚动劫持逻辑,就得用 run_script 注入带 try/catch 的完整函数体,并检查 window.scrollY 是否真变化。
-
run_js返回None表示 JS 执行异常,不是 JS 返回 undefined —— 要捕获错误得加try...except包裹 -
run_script的函数不能引用外部 Python 变量,参数必须是 JSON 可序列化的类型(如str、int、dict) - 大量调用
run_js会累积 CDP 消息队列,导致延迟升高,此时应合并操作,例如用一个run_script完成多个 DOM 查询
怎么处理登录态持久化与多账号切换?
DrissionPage 支持直接加载用户数据目录(user_data_path),让登录 Cookie 和 localStorage 自动继承。比起 Selenium 手动导出/导入 cookie,这种方式更可靠,尤其对微信、淘宝等依赖 LocalStorage + IndexedDB 的站点。
多账号场景下,不要共用一个 Chromium 实例,而应为每个账号分配独立 user_data_path,并通过 profile_directory 区分。否则 A 账号登出后,B 账号可能因缓存未清而跳过登录页。
- 首次运行时,
Chromium会自动创建 profile,但需确保路径可写,否则报Failed to create user data directory - 调用
page.close_tabs(except_main=True)清空非主 tab,避免旧会话干扰 - 敏感操作前建议
page.refresh()并用wait.ele_deleted确认登录态已重置,再执行新账号登录流程
真正麻烦的是某些网站用 Service Worker 缓存登录状态,即使清空 profile 也无效——这时得在 ChromiumOptions 里加 --disable-background-networking 和 --disable-features=Translate 等开关,硬性切断后台同步通道。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











