背景:
每天晚上下班第一件事情就是打开电脑上的守望先锋直播,然后边吃饭边看直播,但是点开直播这个过程实在是令人恼火又要去找某个主播在哪,又要看在不在线,还要调整清晰度,放大等,我想能不能用鼠标自动点击完成呢,然而还真有这么个语言可以实现屏幕图像识别,这就是sikuli。这是由MIT的研究人员设计了一种新颖的图形脚本语言Sikuli,可以实现屏幕图像的识别,并进行鼠标操作或者键盘操作的语言。
准备:
1、sikuli下载地址 https://launchpad.net/sikuli/+download
第一个其实是它的图形画编辑器安装包,第二个才是java所需的依赖jar包,我们这下载第二个就可以了。
2、IDEA2020 (java编译器)
3、java环境 jdk1.8自行到官网下载
4、window10系统
难点:
- 如何把sikuli的jar包放到idea的项目中去
- 如果打包写好的java脚本
- 如何获取jar包运行的根目录
导入sikuli的jar包
在新建号的项目中加入一个目录libs(名字可以自定义),然后把下好的sikulixapi-2.0.4.jar包放到该目录下,如下所示
然后在modules里面添加jar或者directories把libs文件定位到,这就可以把libs下面的所有jar导入进来。
这样做有个好处是,可以让依赖包(libs) 和项目处于同一个目录下,使用svn或者git上传的时候就可以把依赖传上去。
代码:
废话不多说,上java代码
package com.sikuli;
import org.sikuli.script.FindFailed;
import org.sikuli.script.Location;
import org.sikuli.script.Match;
import org.sikuli.script.Screen;
import java.util.ArrayList;
import java.util.List;
/**
* @Author Tmz
* @Date 2021/01/29 18:54
* @Description 打开虎牙直播
*/
public class Laoli {
/**虎牙位置*/
private static final String exePath = "C:\\Program Files (x86)\\HuyaLive\\HuyaClient\\Huya.exe";
/**主播头像*/
private static List<String> heads = new ArrayList<>();
/**图片资源位置*/
private static final String[] steps = {
"./Laoli/step1.png",
"./Laoli/step2.png",
"./Laoli/step3.png",
"./Laoli/step4.png",
"./Laoli/step5.png",
"./Laoli/step6.png",
"./Laoli/step7.png",
"./Laoli/step8.png"
};
static {
/*
* 当前jar包运行路径定位到jar的路径,这句话感觉又点奇怪,
* 事实上你如果是用cmd命令来执行,java -jar xx.jar 这种,
* 实际执行路径就是你运行cmd的路径,而不是jar包所在路径,
* 这种情况就不可能通过相对路径去访问同一目录下的资源文件。
*/
String absPath = Laoli.class.getProtectionDomain().getCodeSource().getLocation().getFile();
String[] split = absPath.split("/");
String suffix = split[split.length - 1];
// System.out.println(Arrays.asList(split));
String replace = absPath.substring(1).replace("/", "\\");
if (suffix.contains("jar")) {
replace = replace.replace(suffix, "");
}
// System.out.println(replace);
for (int i = 0; i < steps.length; i++) {
steps[i] = replace+ steps[i].substring(2).replace("/", "\\");
}
//添加老李头像
heads.add(steps[1]);
//添加老x头像
heads.add(steps[6]);
//添加麻瓜君的头像
heads.add(steps[7]);
}
public static void main(String[] args) {
Screen s = new Screen();
try {
//①.打开虎牙客户端
Runtime.getRuntime().exec(exePath);
} catch (Exception e) {
System.out.println("打开虎牙客户端失败!");
}
//②.点击我的收藏
try {
s.click(steps[0]);
} catch (FindFailed findFailed) {
System.out.println("我的收藏打开失败");
}
//③.循环主播头像[老李,老x,麻瓜君],然后点击其他操作[高清,全屏]
for (String head : heads) {
try {
Match match = s.find(head);
afterClickLeft(s,match);
break;
} catch (FindFailed | InterruptedException findFailed) {
findFailed.printStackTrace();
continue;
}
}
}
/**
* @param s
* @param HeadPortraitMatch
* @return void
* @author Tmz
* @description: 点击头像之后的操作
* @date 2021/1/31 22:23
*/
public static void afterClickLeft(Screen s,Match HeadPortraitMatch) throws InterruptedException, FindFailed {
//点击头像
HeadPortraitMatch.click();
//头像偏移
Location location1 = HeadPortraitMatch.rightAt(500);
location1.move(800, 400);
location1.click();
//③.点击.超清
Thread.sleep(300);
s.click(steps[2]);
//④.点击蓝光10M
Thread.sleep(200);
s.click(steps[3]);
System.out.println("点击蓝光失败");
Thread.sleep(200);
Match match = s.find(steps[4]);
match.click();
System.out.println("点击屏幕失败");
Thread.sleep(200);
Match match2 = s.find(steps[5]);
match2.click();
Location location = match.rightAt();
location.move(500, 100);
location.click();
}
}
由于我把资源路径改为了jar包路径,那么资源应该放在target->classes目录下,如下所示,等打包之后资源就和jar在同一目录下,不管是通过cmd还是什么运行都会访问到相对路径的资源了。
打包:
打包时关键操作,请跟随下面这些操作进行打包。
点击build之后会在项目下生成out文件夹
如果我们刚才那个选的第一个选项我们这就只会生成一个jar包demo.jar,它会把sikuli打进去,这并不是我们想要的,因为我们可能还会想写其他的脚本,到时候我们我们只需要把生成的jar包放到该目录而不需要把sikulixapi-2.0.4.jar包放过去了。
最后这是我生成的目录结构,如下。