快捷搜索:  汽车  科技

python自动化控制程序(Python自动化控制javaswing)

python自动化控制程序(Python自动化控制javaswing)https://github.com/gaozhao1989/pyjabpip install pyjab也可以访问pyjab github源码https://docs.oracle.com/javase/accessBridge/2.0.2/setup.htm解压下载的jab压缩文件,并将文件复制到相应的文件夹中(此处是重点,很多网址中没有这一步)。java7之后就已经集成了JAB,如果安装的目录中含有对应需要安装的文件,可以不用覆盖。当jab安装好了以后,随意打开一个java swing程序。然后打开JavaMonkey-64.exe(如果安装的是64位java,打开javaMonkey.exe没有效果),会出现当前窗口所有控件的属性结构图,表明jab安装成功。

java自身提供了swing程序化控制接口,即Java Access Bridge(jab)。百度上有很多相关的资料,但是总是存在一些问题导致无法控制。

一. 安装jab

jab下载地址

https://www.Oracle.com/java/technologies/javase-jab-2-0-2-downloads.html

Oracle官方jab安装教程(推荐直接阅读官方安装教程)

https://docs.oracle.com/javase/accessBridge/2.0.2/setup.htm

解压下载的jab压缩文件,并将文件复制到相应的文件夹中(此处是重点,很多网址中没有这一步)。java7之后就已经集成了JAB,如果安装的目录中含有对应需要安装的文件,可以不用覆盖。

python自动化控制程序(Python自动化控制javaswing)(1)

当jab安装好了以后,随意打开一个java swing程序。然后打开JavaMonkey-64.exe(如果安装的是64位java,打开javaMonkey.exe没有效果),会出现当前窗口所有控件的属性结构图,表明jab安装成功。

python自动化控制程序(Python自动化控制javaswing)(2)

二. 安装pyjab

pip install pyjab

也可以访问pyjab github源码

https://github.com/gaozhao1989/pyjab

于是在python中也可以像selenium操控网页一样操控java swing了。由于pyjab项目处于新生状态,可能存在部分bug。

很感谢pyjab的作者分享,这样我们就不用重复造轮子也不用去面对底层api。

三. 后记
  1. 根据pyjab官方示例,JABDriver需要输入title。但是有些java swing仅有class,title为空。

class JABDriver(Service ActorScheduler): """Controls a Java application by Java Access Bridge. Args: Service ([type]): Host system to initialize the JAB and load JAB dll file. ActorScheduler ([type]): Set message pump to interacte with windows system. """ def __init__( self title: str = "" bridge_dll: str = "" hwnd: HWND = None vmid: c_long = None accessible_context: JOBJECT64 = None timeout: int = TIMEOUT ) -> None:

于是可以使用pywin32获取到窗口的句柄,然后传入JABDriver中。但是此时会报错

FileNotFoundError: WindowsAccessBridge dll not found please set correct path for environment variable or check the passed customized WindowsAccessBridge dll.

需要将WindowsAccessBridge的绝对路径传进去,例如:

handle = win32gui.FindWindow('SunAwtDialog' None) # Create a JABDriver object. jabdriver = JABDriver(bridge_dll=r'C:\Windows\SysWOW64\WindowsAccessBridge-32.dll' hwnd=handle)

  1. 虽然pyjab支持xpath语法,但是很多语法支持程度不够。目前已知的支持的元素类型如下

""" The By implementation. """ class By(object): """ Set of supported locator strategies. """ XPATH = "xpath" NAME = "name" ROLE = "role" STATES = "states" OBJECT_DEPTH = "object_depth" CHILDREN_COUNT = "children_count" INDEX_IN_PARENT = "index_in_parent"

  1. 推荐一款java swing元素定位工具access-bridge-explorer

https://github.com/google/access-bridge-explorer

  1. 若元素采用win32接口方式点击 simulate=True

此处源码中并没有计算屏幕缩放,应在点击前(DOWN动作之前),计算屏幕缩放比例。

def click(self simulate: bool = False) -> None: """Simulates clicking to JABElement. Default will use JAB Accessible Action. Set parameter 'simulate' to True if internal action does not work. Args: simulate (bool optional): Simulate user click action by mouse event. Defaults to False. Raises: ValueError: Raise ValueError when JABElement width or height is 0. Use this to send simple mouse events or to click form fields:: form_button = driver.find_element_by_name('button') form_button.click() form_button.click(simulate=True) """ if simulate: self.win32_utils._set_window_foreground(hwnd=self.hwnd.value) self.set_element_information() x = self.bounds.get("x") y = self.bounds.get("y") width = self.bounds.get("width") height = self.bounds.get("height") if width == 0 or height == 0: raise ValueError("element width or height is 0") position_x = round(x width / 2) position_y = round(y height / 2) self.win32_utils._click_mouse(x=position_x y=position_y) else: self._do_accessible_action(action="click") def _click_mouse(self x: int y: int hold: int = 0) -> None: win32api.SetCursorPos((x y)) win32api.mouse_event(win32con.MOUSEEVENTF_LEFTDOWN x y 0 0) if hold: time.sleep(hold) win32api.mouse_event(win32con.MOUSEEVENTF_LEFTUP x y 0 0)

计算屏幕缩放比例可参考如下,从百度中复制,并未验证

from win32.lib import win32con import win32api win32gui win32print def get_real_resolution(): """获取真实的分辨率""" hDC = win32gui.GetDC(0) wide = win32print.GetDeviceCaps(hDC win32con.DESKTOPHORZRES) high = win32print.GetDeviceCaps(hDC win32con.DESKTOPVERTRES) return {"wide": wide "high": high} def get_screen_size(): """获取缩放后的分辨率""" wide = win32api.GetSystemMetrics(0) high = win32api.GetSystemMetrics(1) return {"wide": wide "high": high} def get_scaling(): '''获取屏幕的缩放比例''' real_resolution = get_real_resolution() screen_size = get_screen_size() proportion = round(real_resolution['wide'] / screen_size['wide'] 2) return proportion

猜您喜欢: