• 基于自动化工具autox.js的抢票(猫眼)


    1.看到朋友圈抢周杰伦、林俊杰演唱会票贼难信息,特研究了一段时间,用autox.js写了自动化抢票脚本,购票页面自动点击下单(仅限安卓手机)。

    2.脚本运行图

    3.前期准备工作

     (1)autox.js社区官网:AutoX.js

     (2)b站上学习资料:10分钟学会AutoX.js hello world_哔哩哔哩_bilibili

                                          AutoX.js控件操作_哔哩哔哩_bilibili

    4.源码

    1. // 检查无障碍服务是否已经启用,如果没有启用则跳转到无障碍服务启用界面,并等待无障碍服务启动;当无障碍服务启动后脚本会继续运行。
    2. auto.waitFor();
    3. //打开猫眼app
    4. app.launchApp("猫眼");
    5. openConsole();
    6. console.setTitle("猫眼 go!","#ff11ee00",30);
    7. main();
    8. //获取输入的场次信息
    9. function getPlayEtc(){
    10. var playEtc = rawInput("请输入场次关键字(按照默认格式)", "周六");
    11. if (playEtc == null || playEtc.trim()=='') {
    12. alert("请输入场次信息!");
    13. return getPlayEtc();
    14. }
    15. console.log("手动输入的场次信息:"+playEtc);
    16. return playEtc;
    17. }
    18. //获取输入票价信息
    19. function getTicketPrice(){
    20. var ticketPrice = rawInput("请输入票价关键字(按照默认格式)", "788");
    21. if (ticketPrice == null || ticketPrice.trim()=='') {
    22. alert("请输入票价信息!");
    23. return getTicketPrice();
    24. }
    25. console.log("手动输入的票价信息:"+ticketPrice);
    26. return ticketPrice;
    27. }
    28. //获取输入的抢票时间
    29. function getSellTime(){
    30. var sellTime = rawInput("请输入抢票时间(按照默认格式)", "10-07 12:18");
    31. if (sellTime == null || sellTime.trim()=='') {
    32. alert("请输入抢票时间!");
    33. return getSellTime();
    34. }
    35. return sellTime;
    36. }
    37. function main() {
    38. console.log("开始猫眼抢票!");
    39. var preBook= text("已 预 约").findOne(2000)
    40. var preBook2 = className("android.view.View").text("已填写").findOne(2000)
    41. var isPreBook = preBook2!=null||preBook!=null;
    42. var playEtc;
    43. var ticketPrice;
    44. console.log("界面是否已预约:"+isPreBook);
    45. if(!isPreBook){
    46. console.log("无预约信息,请输入抢票信息!");
    47. playEtc = getPlayEtc();
    48. ticketPrice = getTicketPrice();
    49. }
    50. var month;
    51. var day;
    52. var hour;
    53. var minute;
    54. var inputTime = getSellTime();
    55. //在这里使用输入的时间进行后续操作
    56. console.log("输入的抢票时间:" + inputTime);
    57. var times = inputTime.split(" ");
    58. var time1 = times[0]
    59. var time2 = times[1]
    60. var monthDay= time1.split("-");
    61. month = monthDay[0] - 1;
    62. day = monthDay[1];
    63. var hourMinute= time2.split(":");
    64. hour = hourMinute[0];
    65. minute= hourMinute[1];
    66. // 设置开抢时间
    67. var year = new Date().getFullYear();
    68. var second = 0;
    69. var msecond = 0;
    70. var startTimestamp = new Date(year, month, day, hour, minute, second, msecond).getTime();
    71. // 减去 45ms 的网络延迟
    72. startTimestamp = startTimestamp - 45;
    73. var damaiTimestamp;
    74. var startTime = convertToTime(startTimestamp);
    75. console.log("开抢时间:", startTime);
    76. console.log("等待开抢...");
    77. // 循环等待
    78. while (true) {
    79. damaiTimestamp = getDamaiTimestamp();
    80. if (damaiTimestamp >= startTimestamp) {
    81. break;
    82. }
    83. }
    84. var realStartTime = getDamaiTimestamp();
    85. console.log("冲啊!!!");
    86. while(true){
    87. var but1 = className("android.view.View").text("立即预订").exists();
    88. var but2 = className("android.view.View").text("立即购票").exists();
    89. var but3= className("android.view.View").text("特惠购票").exists();
    90. //var but4= className("android.view.View").text("缺货登记").exists();
    91. var result = but1||but2||but3;
    92. if(result){
    93. var s;
    94. if(but1){
    95. var s =className("android.view.View").text("立即预订").findOne().click();
    96. }else if(but2){
    97. var s =className("android.view.View").text("立即购票").findOne().click();
    98. }else if(but3){
    99. var s =className("android.view.View").text("特惠购票").findOne().click();
    100. }
    101. console.log("点击了立即购票相关按钮:"+s)
    102. break;
    103. }
    104. }
    105. if(!isPreBook){
    106. // 选择场次
    107. //textContains(playEtc).findOne().parent().click();
    108. className("android.view.View").textContains(" "+playEtc+" ").findOne().parent().click();
    109. console.log("选择场次");
    110. ticketPrice = "¥"+ticketPrice
    111. textContains(ticketPrice).findOne().parent().click();
    112. console.log("选择票档");
    113. }
    114. //className("android.view.View").text("确认").waitFor();
    115. className("android.view.View").text("确认").findOne().click();
    116. console.log("点击确认");
    117. // while(className("android.view.View").text("确认").exists()){
    118. // console.log("确认按钮还在,继续点击");
    119. // }
    120. //等待立即支付按钮出现
    121. className("android.widget.Button").waitFor();
    122. var c = className("android.widget.Button").findOne().click();
    123. console.log("点击立即支付 "+c);
    124. var t = getDamaiTimestamp() - realStartTime
    125. console.log("花费时间:"+t)
    126. console.log("休息2秒,如果立即支付按钮还在再点击一次")
    127. //休息2
    128. sleep(2000)
    129. if(className("android.widget.Button").exists()){
    130. var c = className("android.widget.Button").findOne().click();
    131. console.log("继续点击立即支付 "+c);
    132. }
    133. //立即支付按钮一直在一直支付
    134. // while(className("android.widget.Button").exists()){
    135. // var c = className("android.widget.Button").findOne().click();
    136. // sleep(100)
    137. // console.log("继续点击立即支付 "+c);
    138. // }
    139. console.log("结束时间:"+convertToTime(getDamaiTimestamp()))
    140. }
    141. /**
    142. *
    143. * @returns 大麦服务器时间戳
    144. */
    145. function getDamaiTimestamp() {
    146. return JSON.parse(http.get("https://mtop.damai.cn/gw/mtop.common.getTimestamp/", {
    147. headers: {
    148. 'Host': 'mtop.damai.cn',
    149. 'Content-Type': 'application/json;charset=utf-8',
    150. 'Accept': '*/*',
    151. 'User-Agent': 'floattime/1.1.1 (iPhone; iOS 15.6; Scale/3.00)',
    152. 'Accept-Language': 'zh-Hans-CN;q=1, en-CN;q=0.9',
    153. 'Accept-Encoding': 'gzip, deflate, br',
    154. 'Connection': 'keep-alive'
    155. }
    156. }).body.string()).data.t;
    157. }
    158. /**
    159. *
    160. * @param {时间戳} timestamp
    161. * @returns ISO 8601 格式的北京时间
    162. */
    163. function convertToTime(timestamp) {
    164. var date = new Date(Number(timestamp));
    165. var year = date.getUTCFullYear();
    166. var month = (date.getUTCMonth() + 1).toString().padStart(2, "0");
    167. var day = date.getUTCDate().toString().padStart(2, "0");
    168. var hours = (date.getUTCHours() + 8).toString().padStart(2, "0");
    169. var minutes = date.getUTCMinutes().toString().padStart(2, "0");
    170. var seconds = date.getUTCSeconds().toString().padStart(2, "0");
    171. var milliseconds = date.getUTCMilliseconds().toString().padStart(3, "0");
    172. var iso8601 = `${year}-${month}-${day} ${hours}:${minutes}:${seconds}.${milliseconds}`;
    173. return iso8601;
    174. }
    175. //点击控件所在坐标
    176. function btn_position_click(x) {
    177. if (x) {
    178. var b = x.bounds();
    179. print(b.centerX())
    180. print(b.centerY())
    181. var c = click(b.centerX(), b.centerY())
    182. console.log("点击是否成功:"+c);
    183. }
    184. }

  • 相关阅读:
    数字图标的使用(阁瑞钛伦特软件-九耶实训)
    spring事务
    记一次iOS审核被拒条例4.1和2.3.7的通关经历
    我是如何使用Spring Retry减少1000 行代码
    阿里巴巴按关键字搜索商品 API 返回值说明
    【比特熊故事汇2.0】|即使每天都是新的探险,他也会快乐Say Hi
    Centos7安装Gogs完整教程
    刷题经验分享(一)
    【JavaEE基础与高级 第61章】Java中的注解和元注解的介紹使用、注解解析
    FIFO深度计算学习记录(汇总)
  • 原文地址:https://blog.csdn.net/Java_wucao/article/details/134012918