💥 3.2 功能介绍
3.2 对比 3.1 有相当大的变化。既对底层逻辑进行了梳理,修复了许多问题,提高了稳定性,也对用户 api 进行了整合。
期待大佬们体验并提出意见建议。
沟通方式:
-
QQ 群:897838127
✅️️ 特性改变
📌 WebPage
不再自动切换模式
旧版本中,调用非当前模式独有的方法,会先自动切换模式。比如在 d 模式调用post()
方法,会自动切换到 s 模式。
3.2 中,只有显式调用change_mode()
时才会切换模式。因此,可以在 s 模式时控制浏览器,不会产生冲突。使用更灵活。
📌 WebPage
的标签页对象也可以切换模式
WebPage
的get_tab()
方法现在返回WebPageTab
对象,也能切换模式。创建时默认处于 d 模式。
📌 更改找不到元素时返回值
旧版本中,查找不到元素会返回None
,3.2 版中会返回一个NoneElement
对象。
该对象用if
判断表现为False
,调用其功能会抛出ElementNotFoundError
异常。这样可以用if
判断是否找到元素,也可以用try
去捕获异常。
查找多个元素找不到时,依然返回空的list
,这点和旧版本一致。
示例,当我们查找一个不存在的元素时:
❌ 当前版本用None
判断的方式将不可用:
⭕ 正确做法:
📌 部分方法调整
-
run_js()
方法参数顺序作了调整 -
darg()
和darg_to()
方法删除了shake
参数 -
元素对象去除
wait_ele()
方法,改用wait.xxxx()
方法等待自身属性改变 -
ChromiumPage
的to_tab()
、close_tabs()
、close_other_tabs()
方法可接收标签页对象 -
ActionChains
导入路径改为from DrissionPage.common import ActionChains
-
Keys
导入路径改为from DrissionPage.common import Keys
📌 下载默认使用浏览器
避免不了解 DownloadKit 的用户以为点击后程序没有反应。
现在点击后默认用浏览器下载到程序当前路径,可用download_set.save_path()
设置保存位置。
✅️️ api 整合
随着功能的增加,同类 api 也越来越多,比如ChromiumPage
以set_
开头的方法就有 9 个,元素点击的方式有 5 种。如何这些同类的 api 全堆在一起,会显得十分凌乱。
因此,3.2 版对大量 api 做了整合,避免提示界面越来越臃肿,也增强了开发灵活性。
旧版的 api 目前还将保留,但将在以后的版本中舍弃。
旧版:
新版:
📌 浏览器页面对象
旧版 | 新版 | 说明 |
---|---|---|
set_timeouts() | set.timeouts() | 超时设置 |
set_session_storage() | set.session_storage() | session storage 设置 |
set_local_storage() | set.local_storage() | local storage 设置 |
set_user_agent() | set.user_agent() | user agent 设置 |
set_cookies() | set.cookies() | cookies 设置 |
set_headers() | set.headers() | headers 设置 |
set_page_load_strategy.xxxx() | set.load_strategy.xxxx() | 页面加载策略设置 |
set_window.xxxx() | set.window.xxxx() | 浏览器大小位置设置 |
set_main_tab() | set.main_tab() | 主 tab 设置 |
wait_loading() | wait.load_start() | 等待页面加载开始 |
wait_ele().xxxx() | wait.ele_xxxx() | 等待元素变成某种状态 |
scroll_to_see() | scroll.to_see() | 把元素滚动到视口 |
hide_browser() | set.window.hide() | 隐藏浏览器 |
show_browser() | set.window.show() | 显示浏览器 |
to_front() | set.tab_to_front() | 设置某个标签页到激活状态 |
📌 元素对象
旧版 | 新版 | 说明 |
---|---|---|
wait_ele().xxxx() | wait.xxxx() | 等待元素变成某种状态 |
r_click() | click.right() | 右键点击元素 |
m_click() | clikc.middle() | 中键点击元素 |
r_click_at() | click.right_at() | 带偏移量中键点击元数据 |
click_at() | click.left_at() | 带偏移量左键点击元素 |
set_attr() | set.attr() | 设置 attribute 属性 |
set_prop() | set.prop() | 设置 property 属性 |
set_innerHTML() | set.innerHTML() | 设置 innerHTML 内容 |
midpoint | locations.midpoint | 获取元素中点在页面位置 |
client_location | locations.viewport_location | 获取元素左上角在视口位置 |
client_midpoint | locations.viewport_midpoint | 获取元素中点在视口位置 |
is_selected | states.is_selected | 获取元素是否被选中 |
is_displayed | states.is_displayed | 获取元素是否显示 |
is_enabled | states.is_enabled | 获取元素是否可操作 |
is_alive | states.is_alive | 获取元素是否仍然在 DOM 内 |
is_in_viewport | states.is_in_viewport | 获取元素是否在视口内 |
pseudo_before | pseudo.before | 获取 before 伪元素内容 |
pseudo_after | pseudo.after | 获取 after 伪元素内容 |
obj_id | ids.obj_id | 获取元素 object id |
node_id | ids.node_id | 获取元素 node id |
backend_id | ids.backend_id | 获取元素 backend id |
doc_id | ids.doc_id | 获取元素 doc id |
✅️️ 新增功能
📌 拦截上传控件填写路径
之前的版本中,要上传文件须要开发者先在 DOM 内找到文件上传控件,有些经过伪装后实时加载的<input>
元素并不好找,有时也会由 js 控制。
新版本中,再也无须费心查找上传控件,只要设置好要上传的路径,然后点击触发文本选择框,程序会自动拦截选择框,并把路径输入到控件,非常便利。
示例:
# 设置要上传的文件路径
page.set.upload_files('demo.txt')
# 点击触发文件选择框按钮
btn_ele.click()
# 等待路径填入
page.wait.upload_paths_inputted()
点击按钮后,文本选择框被拦截不会弹出,但可以看到文件路径已经传入其中。
由于此动作是异步输入,须显式等待输入完成才进行下一步操作。
📌 优先读取项目路径 ini 文件
旧版本中默认 ini 文件存放在 DrissionPage 安装目录下,修改要通过代码进行,给调试带来不便。新版会优先在用户项目文件夹下查找'dp_configs.ini'
文件并使用,使开发时可方便地手动更改配置。项目打包也可以直接打包而不会造成找不到文件问题。
easy_set
方法中增加configs_to_here()
方法,调用该方法可直接把默认 ini 文件复制到当前路径。
📌 查找元素增加或语法
查找元素增加@|
语法,用于或关系匹配多个属性:
或语法@|
不能跟与语法@@
共同生效。
📌 找不到元素时可抛出异常
找不到元素时,除了返回NoneElement
对象,也可设置直接抛出异常。
该设置是全局设置,设置后整个项目都会生效。
示例:
from DrissionPage import SessionPage
from DrissionPage.easy_set import raise_when_ele_not_found
raise_when_ele_not_found(True)
p = SessionPage()
p.get('https://www.baidu.com')
e = p('xxxxxx')
上面的代码会抛出ElementNotFound
异常。
📌 新增一批异常
新增一批异常,调用位置:
-
AlertExistsError
:调用页面功能若存在未处理的弹出框则抛出 -
ContextLossError
:页面被刷新后仍调用其中的元素时抛出 -
ElementLossError
:元素因页面或自身被刷新而失效时抛出 -
CallMethodError
:调用 cdp 时产生的异常 -
TabClosedError
:标签页关闭后仍调用其功能时抛出 -
ElementNotFoundError
:找不到元素抛出 -
JavaScriptError
:JavaScript 运行错误 -
NoRectError
:对没有大小和位置信息的元素获取这些信息时抛出
📌 新增的方法和属性
ChromiumPage
:
名称 | 说明 |
---|---|
run_cdp_loaded() | 执行 cdp 命令,执行前等待页面加载完成 |
run_js_loaded() | 执行 js 语句,执行前等待页面加载完成 |
wait.load_complete() | 等待页面加载完毕 |
wait.upload_paths_inputted() | 等待上传文件路径输入到文件选择框 |
rect.browser_location | 获取浏览器左上角在屏幕上坐标 |
rect.page_location | 获取页面左上角在屏幕上坐标 |
rect.viewport_location | 获取视口在屏幕上坐标 |
rect.browser_size | 获取浏览器大小 |
rect.page_size | 获取页面大小 |
rect.viewport_size | 获取视口大小,不含滚动条 |
rect.viewport_size_with_scrollbar | 获取视口大小,含滚动条 |
remove_ele() | 从页面上移除一个元素 |
get_frame() | 获取一个ChromiumFrame 对象 |
SessionPage
新增一系列设置方法:
名称 | 说明 |
---|---|
set.header() | 设置一个 header 值 |
set.proxies() | 设置代理 |
set.auth() | 设置登录信息 |
set.hooks() | 设置回调方法 |
set.params() | 设置连接参数 |
set.cert() | 设置证书 |
set.stream() | 设置是否使用流式响应内容 |
set.trust_env() | 设置是否信任环境 |
set.max_redirects() | 设置最大重定向次数 |
set.max_redirects() | 添加适配器 |
ChromiumElement
:
名称 | 说明 |
---|---|
locations.screen_location | 获取元素左上角在屏幕上的坐标 |
locations.screen_midpoint | 获取元素中间点在屏幕上的坐标 |
locations.screen_click_point | 获取元素点击点在屏幕上的坐标 |
locations.click_point | 获取元素点击点在页面上的坐标 |
locations.viewport_click_point | 获取元素点击点在视口上的坐标 |
states.is_covered | 获取元素是否被覆盖 |
click.at() | 带偏移量点击元素,可指定按键 |
wait.covered() | 等待元素被覆盖 |
wait.covered() | 等待元素不被覆盖 |
📌 命令行工具
新增支持命令行工具。
实验功能
作者仍未熟练掌握命令行配置,此功能随时会调整。
-
--set-browser-path
(-p
):设置配置文件中的浏览器路径 -
--set-user-path
(-u
):设置配置文件中的用户数据路径 -
--configs-to-here
(-c
):复制默认配置文件到当前路径 -
--launch-browser
(-l
):启动浏览器,传入端口号,0表示用配置文件中的值
✅️️ 优化和问题修复
-
对程序底层和业务逻辑进行了重新梳理,优化程序逻辑,大幅增强稳定性
-
新旧版本完全隔离,新版以后开发可放飞自我,无须担心影响以前用
MixPage
开发的程序 -
现在会返回开发者能看懂的异常信息
-
修复页面加载和退出触发弹窗引起的问题
-
修复
<iframe>
加载时可能出现的 500 错误 -
修复异域
<iframe>
点击问题 -
没有位置和大小信息的元素在获取这些信息时,现在会抛出异常
-
修复内存没有正确释放的问题
-
修复点击被固定栏遮挡问题
-
接管新出现的
<iframe>
会自动等待内容加载 -
修复
<iframe>
在同域和异域间互相跳转时会卡住的问题 -
修复
<iframe>
内元素截图出现偏移问题