javascript自动点击iTunes中的下载按钮

时间:2015-10-20 08:53:34

标签: macos javascript-automation jxa

我需要使用JXA以编程方式从iTunes下载应用程序。我做了以下事情:

var its = SystemEvents.processes.byName('iTunes');
delay(3);
its.windows[0].buttons.byName('Get').click();

没有选择任何元素。我已经尝试点击按钮[0 ... 7],但这些都不是“获取”按钮。按钮。我假设我需要的按钮位于文档中,然后JXA文档明确指出按钮元素是Window的子元素,而不是Document的子元素。关于如何点击相关按钮的任何想法?

1 个答案:

答案 0 :(得分:0)

“叶子”UI元素(如按钮)位于可能复杂的UI元素层次结构的底部,对于iTu​​nes来说尤其如此。

为了给你一个意义,这里是免费应用程序的App Store页面上public class TestDoubleThread extends Thread { String jobNmae; static int count = 0; TestDoubleThread(String jobName) { this.jobNmae = jobName; } public static void main(String[] args) throws Exception { TestDoubleThread t1 = new TestDoubleThread("A"); TestDoubleThread t2 = new TestDoubleThread("B"); t1.start(); t2.start(); Thread.sleep(3 * 1000L); System.out.println("count=" + TestDoubleThread.count); } public void run() { // addCount2(); addCount3("A"); } public synchronized static int addCount1() { for (int i = 0; i < 10000; i++) { count++; } return count; } static void addCount2() { synchronized (TestDoubleThread.class) { for (int i = 0; i < 10000; i++) { count++; } } } void addCount3(String key) { synchronized (myMap.get(key)) { for (int i = 0; i < 10000; i++) { count++; } } } public static java.util.Map<String, TestDoubleThread> myMap = new java.util.HashMap<String, TestDoubleThread>(); static { myMap.put("A", new TestDoubleThread("A")); myMap.put("B", new TestDoubleThread("B")); } } 按钮的示例对象说明符(假设你已经确保此页面处于活动状态):

Get

问题是这个对象说明符在页面之间有所不同,所以理想情况下你只需要将过滤器应用于所有 UI元素(通过窗口的Application("System Events") .applicationProcesses.byName("iTunes") .windows.byName("iTunes") .splitterGroups.at(0) .scrollAreas.at(0) .uiElements.at(0) .groups.at(3) .buttons.at(0) 检索感兴趣的按钮:

entireContents

这是一个问题:在我最近合理的机器上,这需要大约20秒(!)。

我会想象一个// Get an array of all UI elements in iTunes window. uiElems = Application("System Events").applicationProcesses['iTunes'] .windows[0].entireContents() // Find all buttons whose description contains 'Get'. btns = uiElems.filter(function(el) { try { return el.role() == 'AXButton' && el.description().match(/\bGet\b/) } catch (e) {} }) // Click on the 1st button found. btns[0].click() 样式的过滤器会更快,但我无法让它在这个实例中工作,因为必须捕获异常 - 如上所述 - 但.whose不会似乎支持嵌入式异常处理程序。

如果您愿意在层次结构中对较低级别进行假设,可以在其子树中找到按钮,那么您可以大大加快速度:

.whose

这在不到1秒的时间内完成。在我的机器上。

不幸的是,UI自动化(GUI脚本)是一项棘手的业务。

对于交互式探索,Xcode附带的辅助功能检查器开发人员工具,但使用它并非易事,尤其是在将结果转换为代码时。