有一段时间想要对windows的桌面app进行自动化,于是找了一段时间,找到了SikuliX(斯库里),这个工具是基于像素和桌面的大小来定义的,所以脚本移植后不一定能够使用,好处就是它是基于像素的,所以相当于我们的眼睛看到的一样,下面是我使用它的一些记录,希望对正在阅读的你有帮助;
1、献上它的官网网址和参考文档:
http://sikulix-2014.readthedocs.io/en/latest/region.html#Region.exists
http://doc.sikuli.org/globals.html#importing-other-sikuli-scripts-reuse-code-and-images
2、SikuliX 文件:链接: https://pan.baidu.com/s/1AlPpQRv7Ra9rUfycrGsF3A 提取码: hbid
3、启动命令:
1)cmd在对应的目录下执行命令: runsikulix.cmd;
runsikulix -r script.sikuli\script.skl\script.jar
2)直接双击sikulix.jar
4、admin权限启动sikulix:以管理员权限双击runsikulix.cmd 或者以管理员权限启动cmd,再启动sikulix.jar,否则会遇到各种权限问题;
5、sikuli的优点
- sikuli可在Mac OS X、Windows 和 Linux 平台运行,需要Java 6 的运行环境支持
- sikuli提供sikuli-script.jar包供java,python程序调用
- 图形化编程,简单易用
sikuli的缺点
- 依赖屏幕截图,不同的操作系统上,不同的浏览器中,甚至是不同的显示分辨率下,需要独立维护一套图形源文件,对于其跨平台的能力造成障碍。
- 执行容错性差,如果出现程序逻辑之外的意外界面遮挡或焦点切换(如,弹出窗口等),则会对程序执行造成影响。
- sikuli IDE处于初级开发阶段,稳定性有待提高,很多机器截图功能失效
- sikuli IDE仅支持初级的代码编辑功能,不适合规模较大的代码开发和调试。
综上所述,类似自动发帖、自动抢购,QQ自动发消息等小型程序直接使用sikuli IDE是不错的选择,类似GUI自动化测试等工作,还是选择java、python程序调用sikuli-script.jar快捷。
6、sikuli导入import的使用:
导入mymodule.sikuli模块:
1、测试环境中需要将mymodule.sikuli存在的目录写入sys.path,以便运行时可以查找;
2、我们可以导入sikuli模块到其他模块,导入的模块必须在第一行写入:from sikuli import *
3、被导入模块需要执行import操作:from wehotel2 import * 或者import wehotel2
两种不同的导入调用函数的时候对应为:function() 和 wehotel2.function()
导入python模块function.py:
(functions.py的首行需写入from sikuli import *)
import function
reload(function)
from function import *
7、使用规则:
1)可以使用函数,但是不函数不能够放在类中,也不能够放在其他模块文件里。
2)查询时间默认是3s内,超过才出错。
3)sys 和 time 已经导入了,不需要另外import
8、screen的使用,我们可以使用region来缩小搜索的范围,也可以减少相似的object,使我们查询定位的时候不会因为查找出过多的object出错。
9、导入新路径:
#the path of script
myScriptPath = r"C:\Python27\Lib\site-packages;D:\sikuli1.1.1\sikulixapi.jar"
if not myScriptPath in sys.path: sys.path.append(myScriptPath)
10、设置查找失败时的设置:
Region.setThrowException = False #即便查找失败也不会raise一个setThrowException
Region.setFindFailedResponse:ABORT(报错)、SKIP(跳过)、PROMPT(提示,可设置处理的handler函数,setFindFailedHandler设置)、RETRY (重试)
getFindFailedResponse——设置出错后的返回
getThrowException——获取返回的exception是true还是false
11、常用函数:
waitvanish:等待ps消失,如waitvanish(ps,10)
rightclick:鼠标右键点击,打开右键目录,rightclick(ps)
hover:转动鼠标滑轮至该图片上
dragdrop(ps1,ps2):dragdrop(ps,Location(x,y-10)),实现一个拖放操作,从ps1拖放到ps2
type(ps,text):可以对图片ps进行输入text
paste(ps,text):可以对图片ps进行粘贴text,她可以将剪切板中的内容粘贴过来。
onappear(ps,hnd):图片显现出来后进行hnd操作,如:onAppear(ps,function1())
onvanish(ps,hnd):图片消失后进行操作,如:onVanish(ps,function2())
onchange(m,hnd):该区域像素改变m后进行操作,默认是50点像素,如:onChange(1,function3())
observe:与region进行使用,在observe监控的时段里,如果出错不报错,会返回一个false出来。可用stopObserver()停止监控;——待考究
wheel(ps,Button.WHEEL_DOWN,5):控制鼠标滑轮,可上可下,通过控制鼠标停留在ps上,向下滑5步,也可以向上Button.WHEEL_UP
区域系列:
region:形成区域,所有操作都是在里面进行操作。
moveTo(Locaiton(x,y)):移动region值另外一个地点(x,y)
r.setW(200):改变矩阵的宽为200
r.setY(200):改变矩阵的高
setRect(x,y,w,h):对一个region设置新值,位置和大小
highlight(n):将区域标红n秒,期间是不处理事务的。
getBundlePath():获取存放图片的路径绝对路径
setBundlePath(path):设置图片存放的路径
12、最后列一个我使用的例子:
#为了让这个脚本可以被sikuli调用,需要添加下面这个导入语句
from sikuli import *
#是否记录脚本的每个动作到日记里
Settings.ActionLogs = True
#如果想要导入其他目录下的包,可以借下面两句进行调用
#写入包的目录,r=raw
myScriptPath = r"C:\Users\user\Desktop\sikuli\conf"
#判断搜索路径中如果没有这个地址则添加
if not myScriptPath in sys.path: sys.path.append(myScriptPath)
#导入基本配置脚本
from common_template import *
#以下三个参数可以设定的日记格式为:[test (18-5-15 10:45:37)] xxx
#是否开启用户输出日记功能,通过Debug.user("xxx")输出想要的信息
Settings.UserLogs = True
#日记前的用户名
Settings.UserLogPrefix = "test"
#日记前的是否添加日记记录时的时间
Settings.UserLogTime = True
#两个动作之间的反应时间,默认是0.5
Settings.MoveMouseDelay = 0.01
#设定日记等级,0=none,1=error,2=info,3=debug,4=log
Debug.on(1)
#设定日记文件的地址
Debug.setLogFile(r"C:\Users\user\Desktop\workplaces\work\xxx\xxx.txt")
#结果设定
def Result(ps,func):
if exists(ps,10):
print func
else:
print "Fail"
#将每个需要完成的功能写成独立的模块,此部分可以自行决定
def Login():
#打开app,只需添加启动文件exe的路径就可以了,r=raw
openApp(r"C:\Users\user\Desktop\workplaces\work\xxx\xxx.exe")
#在10s内,查找到这张图片,否则会发起寻找不到错误的exception
wait("1519782024463.png",10)
#单击这张图片中的红点,设定相似度99%,默认是70%
click(Pattern("1519635655534.png").exact())
#单击这张图片中的红点,设定相似度99%,默认是70%
click(Pattern("1526350750704.png").exact())
#输入内容"111111",按下键盘按键Tab
type("111111"+"\t")
#输入内容"123456
type("123456")
click(Pattern("1519635773499.png").exact())
#设定了不同点击点的代码
exists(Pattern("1521012282803.png").exact().targetOffset(-133,-2),10)
click(Pattern("1519702036468.png").targetOffset(-129,2))
type("ducheng"+"\r")
#设定相似度的代码
click(Pattern("1521605514360.png").similar(0.80))
wait(Pattern("1521685919125.png").similar(0.80),3)
#在10s内,等待这张图片消失,否则发起错误exception
waitVanish("login.png",10)
#双击这张图,相似度80%
doubleClick(Pattern("1519702473901-1.png").similar(0.80))
#调用Result函数
Result(Pattern("1521602991182.png").similar(0.80),"Login is OK.")
# 输出日记内容到日记文件中,如:[test (18-5-15 10:45:37)] Login is OK.
Debug.user("Login is OK.")
#python文件运行的标准格式
if __name__ == "__main__":
#需要运行的函数
Login()