Clicknium 是一个 Python UI 自动化库,主要用来自动化 Windows 桌面应用和网页应用。由于 Clicknium 没中文文档,动手写了一下中文教程,简单介绍一下 Clicknium 的使用方法。
Clicknium 通过录制鼠标点击 UI 元素,自动生成 Locator ,其中存储了该 UI 元素的各种属性,使 Clicknium 可以通过 locator 重新定位到对应的 UI 元素。 定位到 UI 元素后,Clicknium 提供了各种常见的操作 UI 的方法,比如输入( set_text )、鼠标点击( Click )等,就能轻松完成 UI 自动化脚本。
Clicknium 开发套件
Clicknium Python SDK 是 Clicknium 的自动化核心, 围绕这一核心,Clicknium 还提供了一系列插件协助开发自动化脚本:
Clicknium Python SDK 可通过 pip install clicknium 安装。 在 VS Code 中搜索 Clicknium 安装拓展后,可以在拓展中管理 Clicknium 的各种插件和 SDK 的安装和升级。
需在 Windows 环境下:
在 VS Code 扩展中搜索 Clicknium 并安装:
在 Clicknium explorer 中安装 Python module 和需要的插件:
Python module 也可通过:pip install clicknium 安装。 安装较慢的同学,可以将 pypi 切换为清华源
首先看一下示例的 sample 。打开 VS Code ,Ctrl+shift+P 输入 Clicknium: Sample 然后选择一个新建一个空目录用来存放 sample project 。
这时候我们得到了下面的 sample project ,按 F5 运行,Ctrl+F5 调试。
sample project 目录结构:
/.locator locator 信息
/.locator/sample_img 是 locator 的快照
/.locator/sample.cnstore 是 locator store 里面存放这 locator 的属性
代码分析:
if cc.edge.extension.install_or_update():
print("Please open edge browser to enable clicknium extension, then run sample again.")
很好理解自动安装 edge 浏览器的插件。自动化浏览器需要安装对应的浏览器插件。
tab = cc.edge.open("https://www.bing.com/")
tab.find_element(locator.sample.bing.search_sb_form_q).set_text('clicknium')
tab.find_element(locator.sample.bing.svg).click()
sleep(3)
tab.close()
第一行:利用 clicknium 调用 edge 浏览器打开 bing 首页,返回对应浏览器 tab 。
第二行:在 tab 内调用 find_element,在参数中传入输入框 locator ,调用 set_text API 传入文本信息。
第三行:在 tab 内调用 find_element,在参数中传入搜索按钮的 locator ,调用 click 函数。
第四、五行:等待 3 秒钟,关闭对应的 tab 。
通过这部分代码,可以大致理解 clicknium 的逻辑。Clicknium 提供了诸如 find_element 等函数,接受 locator 参数获取到 UI 元素。同时提供了一些操作 UI 的通用方法,比如 set_text, click 等来模拟人工操作。
process = subprocess.Popen("notepad")
ui(locator.sample.notepad.document_15).set_text("clicknium")
接口与网页端自动化类似。
因为 sample 中没有录制的过程, 你可能不知道 locator 为什么要这么写。 在上图中,VS Code 左下方有一个 Locator tab 下。
从 0 开始用 Chrome 浏览器搜索 Clicknium 网站,自动注册一个账号。
创建一个文件夹 ClickniumSample 来存放 Python Project ,用 VS Code 打开文件夹,并创建 Python 文件 Sample.py 。
打开百度的首页,创建第一个 locator 搜索框。
进入 VS Code ,在 LOCATOR 旁边找到 Capture 按钮,启动 Clicknium Recorder 。
打开 Clicknium 官网The best python automation module | Clicknium
按住 Ctrl +鼠标点击 Sign Up 按钮:
成功后就获得了注册按钮的 locator.
locator 可以用文件夹的形式整理,也可以自己重命名。结构类似 namespace 的形式,所以 locator 的名字中不能出现空格等特殊字符。
生成 locator 后,我们可以用方法find_element定位到 Locator 对应的 UI 元素。 在输入 locator.后会有智能提示:
当鼠标放置在 locator 上时,会有 locator 快照出现,帮你辨认 locator 对应的 UI 元素,同时也可以做验证和重新录制。
定位到 UI 元素后,就支持一系列的操作。操作对象是一个按钮,所以我们选择 click 单击:
同样的方法,再录制注册页面的 5 个输入框和一个按钮:
按钮采用 Click 方法, 输入框采用 set_text 。同样的方法,完成数据填入和点击按钮,使用 F5 运行,查看效果。
from clicknium import clicknium as cc,locator
from time import sleep
def main():
cc.chrome.open("https://www.clicknium.com/")
cc.find_element(locator.clicknium.button_sign_up).click()
sleep(5)
firstName = "Kay"
lastName = "Whitlock"
email = "[email protected]"
password = "youpassword"
cc.find_element(locator.clicknium.auth.text_firstname).set_text(firstName)
cc.find_element(locator.clicknium.auth.text_lastname).set_text(lastName)
cc.find_element(locator.clicknium.auth.text_email).set_text(email)
cc.find_element(locator.clicknium.auth.password_password).set_text(password)
cc.find_element(locator.clicknium.auth.password_confirmpassword).set_text(password)
cc.find_element(locator.clicknium.button_sign_up).click()
if __name__ == "__main__":
main()
Clicknium 的文档中,对鼠标、键盘支持的操作有比较详细的描述,这里简单做一下介绍。
鼠标输入:
Clicknium 支持的鼠标操作可以在Mouse下看到,以最简单的单击( single click )为例,看一下 click 支持的参数:
def click(
self,
mouse_button: Literal["left", "middle", "right"] = MouseButton.Left,
mouse_location: MouseLocation = MouseLocation(),
by: Union[Literal["default", "mouse-emulation", "control-invocation"], MouseActionBy] = MouseActionBy.Default,
modifier_key: Literal["nonekey", "alt", "ctrl", "shift","win"] = ModifierKey.NoneKey,
timeout: int = 30
) -> None:
"""
Single click the target element.
Parameters:
mouse_button: The available values are: 'left', 'right' and 'center', default is 'left'.
mouse_location: it is set to define the position where the element to be clicked. Default position is center of element.
by: Defines the method to click the UI element.
mouse-emulation: click the target UI element by simulating mouse.
control-invocation: click the target UI element by invoking its UI method. It may not be supported if it is a Windows desktop element.
default: automatically choose method per element type. For Web element, use `control-invocation`; for Window element, use `mouse-emulation`.
modifier_key: The modifier key("alt", "ctrl", "shift", "win") to be pressed along with click, and default is none.
timeout: timeout for the operation, the unit is second, and default is set to 30 seconds.
Returns:
None
"""
mouse_button:鼠标左键,或右键。
mouselocation:绝对位置或者相对位置
by: 有两种模式 mouse-emulation 和 control-invocation 。看名字比较抽象。其实前者就是模拟鼠标的行为,移动鼠标过去点击,control-invocation 则是使用类似系统调用的方式。 简单说来,模拟鼠标 mouse-emulation 成功概率高,方法调用 control-invocation 性能好。 一般桌面端自动化,优先选择模拟鼠标,浏览器端优先方法调用,没效果再尝试模拟鼠标。
modifier_key:达到按住特殊按钮如 alt 、ctrl 、shift 点击鼠标的效果。
键盘输入
常用的键盘输入有两种:
输入文字一般用 set_text 方法:
def set_text(
self,
text: str,
by: Union[Literal["default", "set-text", "sendkey-after-click", "sendkey-after-focus"], InputTextBy]= InputTextBy.Default,
overwrite: bool = True,
timeout: int = 30
) -> None:
"""
Set text for the target element, it can be used to input text to a system.
Parameters:
text[Requried]: text string to be input.
by: the method to perform the text input operation.
set-text: call system method to set text to the target element. Some Windows application elements may not be supported.
sendkey-after-click: simulate mouse click to activate the element, then send keys by simulating keyboard.
sendkey-after-focus: set the target element to focused state, then send keys by simulating keyboard.
default: using different methods per target element type. `set-text` for web element and `sendkey-after-click` for desktop element.
overwrite: whether overwrite or append the text on the target element, default is True.
timeout: timeout for the operation. The unit of parameter is seconds. Default is set to 30 seconds
Returns:
No
参数部分:
text:需要输入的字符串。
by:set-text 为系统调用,性能最好,一般在使用在浏览器场景下。
sendkey-after-click:模拟鼠标点击这个 UI 元素,然后通过模拟键盘的方式输入。
sendkey-after-focus:将目标 UI 元素设置为 focus 然后模拟键盘输入。
overwrite: 可以选择是 append 或是直接覆盖。
sendkey-after-click 是一个很常用的选项,因为目前输入框经常需要鼠标单击后变为激活状态接受输入,在非激活状态下是无法接受输入的。 这也自动化过程中,输入操作经常失败的原因。 需要注意的是,这个方法经常会被输入法劫持,所以采用这个参数时,要讲输入关闭,切换为英文输入。
按下特殊按钮:
主要使用 send_hotkey 方法:
def send_hotkey(hotkey: str) -> None:
"""
Send hotkey to the cursor's current position.
Parameters:
hotkey[Requried]: hotkey string represents one key or combined keys. For example, to represent the letter A, input string "A". To represent the letters A, B, and C, input paremeter "ABC". For special keys, please refer to [hotkeys]( https://docs.microsoft.com/en-au/dotnet/api/system.windows.forms.sendkeys?view=windowsdesktop-6.0#remarks).
Returns:
None
"""
这个方法接受一个 string 作为 hotkey 的代码:具体按键对应的 hotkey code 可以查微软的hotkey 列表 举个例子,需要按下回车,查表可得 enter 的代码为{ENTER}
cc.send_hotkey("{ENTER}")
Locator 是 Clicknium 用来定位 UI 元素的核心。Clicknium Recorder 在录制过程中会读取 UI 元素的各种属性和结构,然后根据算法,选择出能够帮助定位出 UI 元素的属性。
回到 Sample 中的目录结构,Python 项目目录下会出现一个.locator 文件夹,就是存储 Locator 数据的。VS Code 会读取 Locator 数据并在 LOCATORS tab 下展示出来:
上图为 locator 界面,在 LOCATORS tab 下选择对应的 locator 就能进入 locator 的详情页。
右侧上部分有三个按钮,Recapture, Validation, Action:
Recapture:主要用于 locator 失效后重新录制,其还有一个选择是 recapture&compare 用来做比较,尤其是 locator 失效后,重新录制,可以看出是哪些属性发生变化导致 locator 定位失效。
Validation:测试 locator 是否能定位出对应的 UI 元素。注意,对应的 UI 元素的网页或 app 需要处于打开状态,Validation 不会主动打开陈旭。
Action:主要用于测试 Locator 的可用性, 做一些常见的 UI 操作,如点击 click ,获取文本 get_text ,设置文本 set_text 。
Locator attributes 实际上就是 locator 的内容。Clicknium Recorder 在抓取元素时,会自动获取元素的属性,然后选择利用哪些属性来定位 UI 元素。 在 locator 三个快捷操作按钮下方的红框中的内容就是 locator attributes 。在上图的例子中,attributes 的内容从上到下一共有三行。Clicknium 是通过层级结构找到对应的 UI 元素,attributes 中三行属性实际上是层级关系。第一行是 chrome.exe 应用,在定位到 chrome 应用后, 第二行是浏览器 tab ,第三行通过 web 属性定位按钮。
在绝大多数情况下,Clicknium 自动选择的属性都能成功定位到 UI 元素,但少数情况下,我们还是需要对 locator attribute 进行微调,已更好的匹配 UI 元素:首先是对层级关系的选择, 如果判断某一层属性不需要,可以通过点击属性前的蓝色方框取消勾选,该层级的属性就不会参与定位元素。 用鼠标单击层级属性后, 右侧会对该层属性进行展开。对于层级内属性,同样支持选择是否参与定位。同时为了提高泛化能力,属性值的匹配规则支持 equals ,startWith ,endWith ,regex 四种模式。
在匹配模式为 equals 时,还支持通配符。 例如 name='test?_node 其中?匹配 1 个字符,* 匹配 0 个或多个字符。
对于多个同类型的 UI 元素,大部分 locator attributes 都是相同的,仅仅一个或几个属性值不同的情况下, 创建大量 locator 是不显示的,尤其很多场景下,元素的数量还不固定,这个时候使用参数化 locator 就很合适。
在 locator 中使用参数:
<Web ancestorId="{{id}}" tag="A" />
或将部分值设置为变量:
<Web ancestorId="video-{{id}}" tag="A" />
在 Python 项目中,采用下面的方式传入变量的值:
from clicknium import clicknium as cc, locator, ui
# replace variable'id' in parametric locator during runtime
variables = {"id":"test"}
ui(locator.chrome.bing.search_sb_form_q, variables)
举个例子:
示例网页中有一个列表:List group · Bootstrap v5.1
使用 Recorder 录制列表中的第一个 item 后,得到下面的 locator:
我们修改 index 的值,使用双花括号创建一个变量{{indexValue}},然后在代码中用一个循环遍历每个 item
from clicknium import clicknium as cc, locator, ui
index = 1
driver = cc.chrome.open("https://getbootstrap.com/docs/5.1/components/list-group/")
while True:
variables = {"indexValue":index}
if driver.is_existing(locator.chrome.getbootstrap.li_anitem, variables):
text = driver.find_element(locator.chrome.getbootstrap.li_anitem, variables).get_text()
print(text)
index += 1
else:
break
get_text 方法会自动判断对应的 UI 元素中展示的文字。当我们需要获取 UI 元素的其他属性值时,可以采用get_property方法。Clicknium 支持多种自动化技术(参考Automation Concepts页面)不同自动化技术会生成不同的 locator 。 其中 Web 对应浏览器,UIA 和 IA 对应 Windows 桌面应用。针对 Web 元素, 在 Web automation 页面中, 可以找到属性列表( Web element properties )。
from clicknium import clicknium as cc, locator, ui
#获取当前页面的 URL
tag = ui(locator.chrome.bing.search_sb_form_q).get_property("URL")
#获取该元素的 title
tag = ui(locator.chrome.bing.search_sb_form_q).get_property("title")