求助,如果要写一个模拟点击的功能,用哪个工具最方便,功能最强大?

各位大哥,小弟我需要从数据库导出一个数据,但是目前由于数据库导出的时候,只能手工一条条导出,大约要几千条,感觉还是有点小麻烦,就像写个脚本自动在后台导出。
要求:

  • 后台运行
  • 支持暂停,因为数据加载需要时间
  • 最好支持ocr识别,因为涉及到保存,每次跳出来的窗口按钮位置不一定在固定位置
  • 以及能识别程序或窗口或通过ocr识别

1 之前用python的pyautogui包写过一个demo,但测试下来就是ocr屏幕的效果不是很好(有可能是我没调用更好的包),反正就是效果有点拉胯。在此想请教下有没有在该场景下比较好用的包?
2 或者,完成此类功能,是用 AHK/Quicker/甚至按键精灵之类的更好用?我看B站上有人分享 AHK的ocr打包好的工具效果还挺好的,如果换 AHK的话,从零学 AHK2容易不?(以前没有用过 AHK)
3 最后,有没有大佬分享下完成这种功能,用到的一些辅助小工具?比如取坐标之类的,似乎大家都是用截图软件?

1 个赞

模拟点击是没办法后台的吧

然后AHK肯定能完成,就是得稍微学一下下

如果说上手难度来说,肯定是Quicker最简单,并且支持你提到的所有需求,包括取坐标之类的小工具也有内置

按键精灵上次用的记忆太久远了,不过我估计也是能实现的,但也有上手难度,有这时间试按键精灵或许直接学AHK更好

2 个赞

使用AHK进行桌面环境自动化的话,最佳实践是直接跟软件通信。如果因为种种原因,软件没有暴露可以通信或控制的接口,再去考虑GUI界面的自动化。

GUI界面操作,更好的实践当然是使用键盘操作导航。而且合理的软件设计应当是能够使用键盘操作来导航到任意的可交互元素的。

在如上条件均不满足时,才考虑使用鼠标针对控件导航进行操作。

在如上条件均不满足且GUI界面没有使用系统控件来构建界面的情况下,才可能去考虑OCR的方式,因为就自动化来说,显然这是最差的方式。

dangerace.ysepan.com

唰唰-全编程型键鼠精灵【V3.5.0】-2024.08.13更新]

可以试试。

小众现在上个图太™困难了,就不弄了。

maa-framework可以试一下,不过可能很多地方需要自己写

点保存按钮的话没必要ocr吧,直接图色方法找“保存按钮”的图就行了
为啥不用按键精灵

怎么判断这几种方式啊,比如
-软件没有暴露可以通信或控制的接口
-键盘操作来导航到任意的可交互元素的
-鼠标针对控件导航
第一个是指API么?但一般软件没有API吧,那个数据库有API但是没有把这一块的数据纳入进去。
第二个是指类似于快捷键操作嘛?

数据库应该得有接口的吧,导出数据=获取数据+把数据以特定格式保存为文件…

通信接口可以是命令行调用运行的形式,也可以是网络接口(restful api之类的),或者是二次开发的接口(.dll库文件)…

键盘导航是指,一般软件都可以通过Tab,方向键,Alt+字母等方式可靠的将焦点导航到期望的界面元素上面。

一般懒得自己写的话,可以用 auto hot k ey的自动生成脚本功能,但现在 chrome base 的软件频繁增多,auto hot key 很多按钮是区别不出来的

图色方法找保存按钮的图,这个大佬详细说说

这个是软件自带的还是要借助什么方法?

AutoHotKey,加findtext脚本

quicker可以使用找图功能,就是上传一个截图,就可以在屏幕里找到图片并输出坐标
按键精灵估计也是有类似的功能,AHK我记得好像也有

我曾经写过一个,AU3 依靠的是屏幕像素点。算是逆向接口的工程,从已经腐朽加密的程序中导出数据。

求分享!

目前看大家似乎推荐AHK,就不知道那个精度更强,按键精灵我感觉有点麻烦,资源不太好找,quicker我不太熟悉

大家推荐AHK
一个是因为咱这是小众论坛,坛友们或多或少都有一点基础(大概)
另一个就是AHK更“万能”一点,虽然有一些门槛,但Quicker和按键精灵能做到的它基本都能做到,做不到的它也可以做到

如果你想要一劳永逸不只解决当下的问题,那花点时间了解下AHK肯定是不亏的
如果你只想快速解决当下的问题,就可以考虑其他软件了

(我是Quicker用户,Quicker也可以解决很多问题,但一年多下来的使用也逐渐让我遇到了一些得靠ahk才能实现的局限,虽然它上手难度低,但论“万能”还得是AHK)

试试 影刀 这类RPA软件

全给你也没用,给你分享一下核心内容

Func lei();类被层
	$blzs = 0
	$blsjc2 = 0
	$blsjc = 0
	While 1;像素位置判断学习病例多寡,作用在类层面
		Sleep(500)
		If $tm >= 1 Then d2xx()
		ToolTip("开始检查选择来了吗?", 500, 500)
		WinWait("选择", "")
		If Not WinActive("选择", "") Then WinActivate("选择", "")
		WinWaitActive("选择", "")
		ToolTip("选择来了", 500, 500)
		Sleep(500)
		ToolTip("是否经过了d2xx", 500, 500)
;~ MsgBox(0,$xxg,"停",8)
		If PixelGetColor(30, $xxg) = 0xECE9D8 Then
			TrayTip("该病人有病例类型", $tm, 10)
			MouseClick("left", 30, $xxg, 1, 1)
			$bls = 0
			IniWrite($lsini_lj, "类", "当前类", $tm)

			$blsjc = bl()
			$blsjc2 += $blsjc
			$tm += 1
;~ 			IniWrite($RZLJ, $m, "进度" & @HOUR & "-" & @MIN & "-" & @SEC, "已经完成" & $id & "的第一次病例。")
			ToolTip("2类别数量" & $tm, 130, $xxg)
			$xxg += 20
;~ 	MsgBox(0,$g,$tm)
		Else
;~ 			MsgBox(0,"类别结果判定","类别数等于:"&$tm)
;~ MsgBox(0,"病例数",$blsjc2)
			If $blsjc2 >= 1 Then ;如果病例获得总数大于等于1就

;~ 				If $blsjc2 >= 0 Then
;~ 					IniWrite($RZLJ, $m, "进度"&$sj, $id & "的病人有类别,但是所有类别中均无数据。未导出任何数据。其中类别数为"&$tm&"病例数为"&$blsjc2)
;~ 					IniWrite($ywcIDrzlj, "无病例", $id,"的病人有类别,但是所有类别中均无数据。未导出任何数据。其中类别数为"&$tm&"病例数为"&$blsjc2)
;~ 				EndIf

				$wjl = wjl()
;~ 				MsgBox(0,"应有文件与现有文件的比对","应有文件:"&$blsjc2&"现有文件"&$wjl)
				$wordGL1 = IniRead($lsini_lj, "树", "word文档是否有错误", "ini中无数据")
				$leils = IniRead($lsini_lj, "类", "当前类", "临时ini中无数据")
				If $wjl = $blsjc2 Then

					Select
						Case $wordGL1 = 1
							IniWrite($RZLJ, $m, "错误" & @HOUR & "-" & @MIN & "-" & @SEC, "树节错误" & $id & "的病人发生“激活Word出错。“错误,其类别在第" & $leils & "类上,")
							IniWrite($ywcIDrzlj, "程序错误", $id, "树环节发生“激活Word出错。1“,已经导出的类别数量" & $leils & "但是会继续导出")
						Case Else
							IniWrite($RZLJ, $m, "进度" & @HOUR & "-" & @MIN & "-" & @SEC, $id & "的病人已经完成导出,已完成的类别数量为" & $tm & "病例数为" & $blsjc2)
							IniWrite($ywcIDrzlj, "完成", $id, "已经导出的类别数量" & $tm & "病例数为" & $blsjc2)
					EndSelect
				Else
					Select
						Case $wordGL1 = 1
							IniWrite($RZLJ, $m, "错误" & @HOUR & "-" & @MIN & "-" & @SEC, "树节错误" & $id & "的病人发生“激活Word出错。“错误,其类别在第" & $leils & "类上,")
							IniWrite($ywcIDrzlj, "程序错误", $id, "树环节发生“激活Word出错。2“,已经导出的类别数量" & $leils & "但是会继续导出")
						Case Else
							IniWrite($RZLJ, $m, "错误" & @HOUR & "-" & @MIN & "-" & @SEC, $id & "的病人已经完成导出,但是已经导出的文件和现在存在的文件不相符,已完成的类别数量为" & $tm & "病例数为" & $blsjc2 & ",现有文件数量为:" & $blsjc2)
							IniWrite($ywcIDrzlj, "完成", $id, "已完成导出但是应有数据与现存在磁盘中数据不相符,应导出的类别数量_" & $tm & "_磁盘中实际病例数为_" & $blsjc2)
					EndSelect
				EndIf
			Else
				If $blsjc2 = 0 Then;如果类别总数等于0就
;~ 					IniWrite($RZLJ, $m, "进度"&$sj, $id & "的病人没有类别,未导出任何数据。")
;~ 					IniWrite($ywcIDrzlj, "无病例", $id, "已经导出的类别数量" & $tm)
					IniWrite($RZLJ, $m, "进度" & @HOUR & "-" & @MIN & "-" & @SEC, $id & "无病例。未导出任何数据。其中类别数为" & $tm & "病例数为" & $blsjc2)
					IniWrite($ywcIDrzlj, "无病例", $id, "无病例,未导出任何数据。其中类别数为" & $tm & "病例数为" & $blsjc2)
				Else
					IniWrite($RZLJ, $m, "错误" & @HOUR & "-" & @MIN & "-" & @SEC, "类环节错误" & $id & "的病人发生错误$tm <类别量> 为" & $tm)
					IniWrite($ywcIDrzlj, "程序错误", $id, "已经导出的类别数量" & $tm)

				EndIf
			EndIf
;~ 			MsgBox(0,"类别层","关闭类别")
			ExitLoop
		EndIf


	WEnd
EndFunc   ;==>lei