注册 登录
发贴工具
查看: 2|回复: 0
打印 上一主题 下一主题

[24小时收录超级好的网站] 京东每日签到领京豆脚本

[复制链接]

2597

主题

2645

帖子

1万

积分

积分
15758
跳转到指定楼层
楼主

京东每日签到领京豆脚本
京东每日签到领京豆脚本 群发软件发帖工具

  1. /*
  2. * ============================================================
  3. * AIWROK 京东每日签到领京豆脚本 - 无障碍AUTO模式
  4. * ============================================================
  5. * 功能: 自动打开京东APP,进入签到页面完成每日签到领京豆
  6. * 流程: 启动京东 → 进入"我的" → 点击签到入口 → 完成签到 →
  7. *       领取奖励 → 关闭弹窗 → 统计结果
  8. *
  9. * 技术特点:
  10. *   1. 纯无障碍节点解析,不依赖固定坐标
  11. *   2. 三级安全点击策略(节点直点→父节点→坐标兜底)
  12. *   3. 多路径签到入口查找(签到卡片→领京豆→签到按钮)
  13. *   4. 自动关闭广告弹窗和奖励弹窗
  14. *   5. 签到状态检测(已签到/未签到/签到成功)
  15. *   6. 支持定时循环执行(每日自动签到)
  16. *   7. 连续错误自动恢复与APP重启
  17. *
  18. * 兼容性: Rhino ES5 引擎 / AIWROK 安卓自动化平台
  19. * ============================================================
  20. */

  21. print.log("===== 京东每日签到领京豆(无障碍AUTO模式)=====");
  22. print.time();

  23. // ============================================================
  24. // 一、配置参数
  25. // ============================================================
  26. var config = {
  27.     APP包名: "com.jingdong.app.mall",    // 京东商城包名
  28.     页面加载等待秒: 5,                     // 页面切换等待秒数
  29.     操作间隔毫秒: 1000,                   // 操作间隔毫秒
  30.     最大重试次数: 3,                      // 单步操作最大重试次数
  31.     最大连续错误: 5,                      // 连续错误上限
  32.     调试模式: 'test',                     // 调试模式:'debug'=只输出页面节点摘要不签到, 'test'=执行完整签到流程, 'false'=正常模式
  33.     循环签到: false,                      // 是否循环签到(定时模式)
  34.     循环间隔分钟: 30,                     // 循环间隔分钟数
  35.     // 签到入口关键词:京东签到入口在"我的"页面"领88豆"按钮
  36.     // 实际可点击节点desc="领88豆京豆最高",text="领88豆"(不可点击,需父节点遍历)
  37.     // 数字每天变化,用textIncludes匹配"豆"或desc匹配"领"+"豆"
  38.     首页签到入口: ["领京豆", "签到", "签到领豆", "领金币", "双签", "每日签到"],
  39.     我的页签到入口: ["每日签到", "领京豆", "签到", "签到领豆", "做任务领京豆", "签到中心", "领金币", "领88豆"]
  40. };

  41. // ============================================================
  42. // 二、初始化
  43. // ============================================================
  44. print.log("\n【初始化】设置无障碍详细模式...");
  45. auto.setDetailedModel();

  46. var 屏幕宽 = screen.getScreenWidth();
  47. var 屏幕高 = screen.getScreenHeight();
  48. print.log("屏幕尺寸:" + 屏幕宽 + " x " + 屏幕高);

  49. // ============================================================
  50. // 三、通用工具函数
  51. // ============================================================

  52. /**
  53. * 查找文字节点(同时搜索text和desc属性)
  54. * @param {Array} 关键词列表 - 关键词数组,依次尝试精确匹配和包含匹配
  55. * @return {Object} 找到的节点对象或null
  56. */
  57. function 查找文字节点(关键词列表) {
  58.     try {
  59.         var 节点集合 = auto.nodeSearch(2000);
  60.         if (节点集合 == '' || 节点集合 == null) {
  61.             return null;
  62.         }

  63.         for (var i = 0; i < 关键词列表.length; i++) {
  64.             var 关键词 = 关键词列表[i];

  65.             // 精确文本匹配
  66.             var 文本过滤 = 节点集合.text(关键词);
  67.             if (文本过滤 != '' && 文本过滤 != null && 文本过滤.count() > 0) {
  68.                 var 节点 = 文本过滤.getNode(0);
  69.                 if (节点 != '' && 节点 != null) {
  70.                     return 节点;
  71.                 }
  72.             }

  73.             // 包含文本匹配
  74.             var 包含过滤 = 节点集合.textIncludes(关键词);
  75.             if (包含过滤 != '' && 包含过滤 != null && 包含过滤.count() > 0) {
  76.                 var 节点2 = 包含过滤.getNode(0);
  77.                 if (节点2 != '' && 节点2 != null) {
  78.                     return 节点2;
  79.                 }
  80.             }
  81.         }

  82.         // desc属性兜底搜索(京东签到按钮的可点击节点desc含"领88豆京豆最高"但text为空)
  83.         for (var j = 0; j < 关键词列表.length; j++) {
  84.             var 关键词2 = 关键词列表[j];
  85.             var 节点 = 查找描述节点([关键词2]);
  86.             if (节点) {
  87.                 return 节点;
  88.             }
  89.         }
  90.     } catch (e) {
  91.         print.log("  ⚠ 查找文字节点出错:" + e.message);
  92.     }
  93.     return null;
  94. }

  95. /**
  96. * 查找描述节点(通过desc属性搜索)
  97. * 遍历所有可点击节点,检查desc是否包含关键词
  98. * @param {Array} 关键词列表 - 关键词数组
  99. * @return {Object} 找到的节点对象或null
  100. */
  101. function 查找描述节点(关键词列表) {
  102.     try {
  103.         var 节点集合 = auto.nodeSearch(2000);
  104.         if (节点集合 == '' || 节点集合 == null) {
  105.             return null;
  106.         }

  107.         // 遍历所有节点检查desc
  108.         var 总数 = 节点集合.count();
  109.         for (var i = 0; i < 总数; i++) {
  110.             var 节点 = 节点集合.getNode(i);
  111.             if (节点 == '' || 节点 == null) {
  112.                 continue;
  113.             }
  114.             try {
  115.                 var desc = "" + 节点.getDesc();
  116.                 if (!desc || desc == "null" || desc.length == 0) {
  117.                     continue;
  118.                 }
  119.                 for (var j = 0; j < 关键词列表.length; j++) {
  120.                     var 关键词 = 关键词列表[j];
  121.                     if (desc.indexOf(关键词) >= 0) {
  122.                         return 节点;
  123.                     }
  124.                 }
  125.             } catch (e) {
  126.             }
  127.         }
  128.     } catch (e) {
  129.         print.log("  ⚠ 查找描述节点出错:" + e.message);
  130.     }
  131.     return null;
  132. }

  133. /**
  134. * 查找desc中同时包含多个关键词的节点
  135. * 例如: 查找描述节点含多词(["领", "豆"]) 会匹配 desc="领88豆京豆最高"
  136. * @param {Array} 关键词列表 - 需要同时包含的关键词数组
  137. * @return {Object} 找到的节点对象或null
  138. */
  139. function 查找描述节点含多词(关键词列表) {
  140.     try {
  141.         var 节点集合 = auto.nodeSearch(2000);
  142.         if (节点集合 == '' || 节点集合 == null) {
  143.             return null;
  144.         }

  145.         var 总数 = 节点集合.count();
  146.         for (var i = 0; i < 总数; i++) {
  147.             var 节点 = 节点集合.getNode(i);
  148.             if (节点 == '' || 节点 == null) {
  149.                 continue;
  150.             }
  151.             try {
  152.                 var desc = "" + 节点.getDesc();
  153.                 if (!desc || desc == "null" || desc.length == 0) {
  154.                     continue;
  155.                 }
  156.                 // 检查是否同时包含所有关键词
  157.                 var 全部匹配 = true;
  158.                 for (var j = 0; j < 关键词列表.length; j++) {
  159.                     if (desc.indexOf(关键词列表[j]) < 0) {
  160.                         全部匹配 = false;
  161.                         break;
  162.                     }
  163.                 }
  164.                 if (全部匹配) {
  165.                     print.log("  [desc组合匹配] desc=[" + desc + "]");
  166.                     return 节点;
  167.                 }
  168.             } catch (e) {
  169.             }
  170.         }
  171.     } catch (e) {
  172.         print.log("  ⚠ 查找描述节点含多词出错:" + e.message);
  173.     }
  174.     return null;
  175. }

  176. /**
  177. * 检查文字是否存在
  178. * @param {Array} 关键词列表 - 关键词数组
  179. * @return {boolean} 存在返回true
  180. */
  181. function 检查文字存在(关键词列表) {
  182.     var 规则 = 关键词列表.join("||");
  183.     return auto.findText(规则);
  184. }

  185. /**
  186. * 安全点击节点 - 三级降级策略
  187. * 策略: 1)节点可点击→直接点击 2)父/祖父节点可点击→点击父级 3)兜底→坐标点击
  188. * @param {Object} 节点 - 要点击的节点对象
  189. * @return {boolean} 点击成功返回true
  190. */
  191. function 安全点击节点(节点) {
  192.     if (!节点 || 节点 == '' || 节点 == null) {
  193.         return false;
  194.     }

  195.     // 第一级:节点本身可点击
  196.     try {
  197.         if (节点.isClickable && 节点.isClickable()) {
  198.             节点.click();
  199.             return true;
  200.         }
  201.     } catch (e) {
  202.     }

  203.     // 第二级:向上查找可点击的父节点或祖父节点
  204.     try {
  205.         var 父节点 = 节点.getParent();
  206.         if (父节点 != '' && 父节点 != null) {
  207.             if (父节点.isClickable && 父节点.isClickable()) {
  208.                 父节点.click();
  209.                 return true;
  210.             }

  211.             var 祖父节点 = 父节点.getParent();
  212.             if (祖父节点 != '' && 祖父节点 != null) {
  213.                 if (祖父节点.isClickable && 祖父节点.isClickable()) {
  214.                     祖父节点.click();
  215.                     return true;
  216.                 }
  217.             }
  218.         }
  219.     } catch (e2) {
  220.     }

  221.     // 第三级:兜底方案,使用坐标点击
  222.     try {
  223.         var 中心 = 节点.getCenter();
  224.         var x = 中心.x();
  225.         var y = 中心.y();
  226.         auto.clickPoint(x, y);
  227.         return true;
  228.     } catch (e3) {
  229.         print.log("  ⚠ 安全点击全部失败:" + e3.message);
  230.         return false;
  231.     }
  232. }

  233. /**
  234. * 关闭弹窗 - 自动识别并关闭各种弹窗、广告、奖励提示
  235. * @return {boolean} 成功关闭返回true
  236. */
  237. function 关闭弹窗() {
  238.     var 弹窗关键词 = [
  239.         "我知道了", "知道了", "关闭", "暂不开启", "以后再说",
  240.         "取消", "暂不更新", "下次再说", "拒绝", "不允许", "跳过",
  241.         "稍后", "确定", "不了谢谢", "残忍拒绝", "收下", "好的"
  242.     ];

  243.     var 检测结果 = auto.findText(弹窗关键词.join("||"));
  244.     if (!检测结果) {
  245.         return false;
  246.     }

  247.     for (var i = 0; i < 弹窗关键词.length; i++) {
  248.         var 关键词 = 弹窗关键词[i];
  249.         var 节点 = 查找文字节点([关键词]);
  250.         if (节点) {
  251.             try {
  252.                 if (安全点击节点(节点)) {
  253.                     print.log("  ✓ 关闭弹窗:点击【" + 关键词 + "】");
  254.                     sleep.millisecond(毫秒 = config.操作间隔毫秒);
  255.                     return true;
  256.                 }
  257.             } catch (e) {
  258.             }
  259.         }
  260.     }

  261.     // 尝试点击右上角关闭按钮(X图标)
  262.     try {
  263.         var 节点集合 = auto.nodeSearch(1000);
  264.         if (节点集合 != '' && 节点集合 != null) {
  265.             var 可点击 = 节点集合.clickable(true);
  266.             if (可点击 != '' && 可点击 != null) {
  267.                 for (var j = 0; j < 可点击.count(); j++) {
  268.                     var n = 可点击.getNode(j);
  269.                     if (n) {
  270.                         var desc = "" + n.getDesc();
  271.                         if (desc.indexOf("关闭") >= 0 || desc.indexOf("close") >= 0 ||
  272.                             desc.indexOf("Close") >= 0) {
  273.                             n.click();
  274.                             print.log("  ✓ 点击关闭按钮(描述匹配)");
  275.                             sleep.millisecond(毫秒 = config.操作间隔毫秒);
  276.                             return true;
  277.                         }
  278.                     }
  279.                 }
  280.             }
  281.         }
  282.     } catch (e) {
  283.     }

  284.     return false;
  285. }

  286. /**
  287. * 调试输出 - 输出当前页面节点摘要
  288. */
  289. function 输出页面摘要() {
  290.     if (!config.调试模式) {
  291.         return;
  292.     }
  293.     try {
  294.         var 节点集合 = auto.nodeSearch(1000);
  295.         if (节点集合 == '' || 节点集合 == null) {
  296.             print.log("  [调试] 无节点");
  297.             return;
  298.         }
  299.         var 总数 = 节点集合.count();
  300.         print.log("  [调试] 页面节点总数:" + 总数);

  301.         var 文本视图 = 节点集合.className("android.widget.TextView");
  302.         if (文本视图 != '' && 文本视图 != null) {
  303.             var 文本数 = Math.min(15, 文本视图.count());
  304.             print.log("  [调试] 前" + 文本数 + "个文本节点:");
  305.             for (var i = 0; i < 文本数; i++) {
  306.                 var 节点 = 文本视图.getNode(i);
  307.                 if (节点) {
  308.                     var 文本 = "";
  309.                     try { 文本 = "" + 节点.getText(); } catch (e) {}
  310.                     var 描述 = "";
  311.                     try { 描述 = "" + 节点.getDesc(); } catch (e) {}
  312.                     print.log("    " + (i + 1) + ". text=" + 文本 + " desc=" + 描述);
  313.                 }
  314.             }
  315.         }
  316.     } catch (e) {
  317.         print.log("  [调试] 输出页面摘要出错:" + e.message);
  318.     }
  319. }

  320. /**
  321. * 等待页面加载并检测特征文字
  322. * @param {Array} 特征文字列表 - 页面特征文字
  323. * @param {number} 超时秒 - 超时秒数
  324. * @return {boolean} 检测到特征返回true
  325. */
  326. function 等待页面(特征文字列表, 超时秒) {
  327.     var 超时毫秒 = 超时秒 * 1000;
  328.     var 开始时间 = Date.now();

  329.     while (Date.now() - 开始时间 < 超时毫秒) {
  330.         if (检查文字存在(特征文字列表)) {
  331.             return true;
  332.         }
  333.         sleep.millisecond(毫秒 = 500);
  334.     }

  335.     if (config.调试模式) {
  336.         print.log("  [调试] 等待页面超时,未检测到:" + 特征文字列表.join(", "));
  337.         输出页面摘要();
  338.     }
  339.     return false;
  340. }

  341. // ============================================================
  342. // 四、核心功能函数
  343. // ============================================================

  344. /**
  345. * 启动京东APP
  346. * @return {boolean} 启动成功返回true
  347. */
  348. function 启动京东() {
  349.     print.log("\n【启动】正在启动京东...");

  350.     for (var i = 0; i < config.最大重试次数; i++) {
  351.         try {
  352.             app.openApp(config.APP包名);
  353.             sleep.second(秒 = config.页面加载等待秒);

  354.             关闭弹窗();

  355.             // 验证京东是否正常启动(首页特征文字)
  356.             if (检查文字存在(["首页", "分类", "发现", "购物车", "我的"])) {
  357.                 print.log("✓ 京东启动成功");
  358.                 return true;
  359.             }

  360.             // 兜底验证:检查是否有搜索框
  361.             if (auto.findText("搜索")) {
  362.                 print.log("✓ 京东启动成功(搜索框检测)");
  363.                 return true;
  364.             }
  365.         } catch (e) {
  366.             print.log("⚠ 启动失败(第" + (i + 1) + "次):" + e.message);
  367.             sleep.second(秒 = 3);
  368.         }
  369.     }

  370.     print.log("✗ 京东启动失败");
  371.     return false;
  372. }

  373. /**
  374. * 进入「我的」页面
  375. * @return {boolean} 成功进入返回true
  376. */
  377. function 进入我的页面() {
  378.     print.log("\n【导航】进入「我的」页面...");

  379.     // 方法1:通过文字查找「我的」标签
  380.     var 我的节点 = 查找文字节点(["我的"]);
  381.     if (我的节点) {
  382.         if (安全点击节点(我的节点)) {
  383.             print.log("  ✓ 已点击【我的】");
  384.             sleep.second(秒 = 2);
  385.             关闭弹窗();

  386.             // 验证是否进入我的页面
  387.             if (等待页面(["我的订单", "我的钱包", "账号管理", "京豆", "会员"], 3)) {
  388.                 print.log("✓ 已进入「我的」页面");
  389.                 return true;
  390.             }
  391.         }
  392.     }

  393.     // 方法2:底部导航栏坐标兜底("我的"通常在底部最右侧)
  394.     print.log("  ⚠ 文字查找失败,尝试坐标点击");
  395.     auto.clickPercent(0.9, 0.97);
  396.     sleep.second(秒 = 2);
  397.     关闭弹窗();

  398.     if (等待页面(["我的订单", "我的钱包", "京豆", "会员"], 3)) {
  399.         print.log("✓ 已进入「我的」页面(坐标点击)");
  400.         return true;
  401.     }

  402.     print.log("✗ 无法进入「我的」页面");
  403.     输出页面摘要();
  404.     return false;
  405. }

  406. /**
  407. * 输出页面完整节点摘要(调试用)
  408. * 无论调试模式是否开启都强制输出,用于排查节点问题
  409. */
  410. function 输出完整页面摘要(标签) {
  411.     try {
  412.         var 节点集合 = auto.nodeSearch(2000);
  413.         if (节点集合 == '' || 节点集合 == null) {
  414.             print.log("  【页面摘要-" + 标签 + "】无节点");
  415.             return;
  416.         }
  417.         var 总数 = 节点集合.count();
  418.         print.log("  【页面摘要-" + 标签 + "】节点总数:" + 总数);

  419.         // 输出所有文本节点
  420.         var 文本视图 = 节点集合.className("android.widget.TextView");
  421.         if (文本视图 != '' && 文本视图 != null) {
  422.             var 文本数 = 文本视图.count();
  423.             print.log("  【页面摘要-" + 标签 + "】文本节点数:" + 文本数);
  424.             var 输出数 = Math.min(30, 文本数);
  425.             for (var i = 0; i < 输出数; i++) {
  426.                 var 节点 = 文本视图.getNode(i);
  427.                 if (节点) {
  428.                     var 文本 = "";
  429.                     try { 文本 = "" + 节点.getText(); } catch (e) {}
  430.                     var 描述 = "";
  431.                     try { 描述 = "" + 节点.getDesc(); } catch (e) {}
  432.                     var 可点击 = "";
  433.                     try { 可点击 = 节点.isClickable() ? "可点击" : "不可点击"; } catch (e) {}
  434.                     print.log("    " + (i + 1) + ". text=[" + 文本 + "] desc=[" + 描述 + "] " + 可点击);
  435.                 }
  436.             }
  437.         }

  438.         // 输出所有可点击节点
  439.         var 可点击节点 = 节点集合.clickable(true);
  440.         if (可点击节点 != '' && 可点击节点 != null) {
  441.             var 可点击数 = 可点击节点.count();
  442.             print.log("  【页面摘要-" + 标签 + "】可点击节点数:" + 可点击数);
  443.             var 输出数2 = Math.min(20, 可点击数);
  444.             for (var j = 0; j < 输出数2; j++) {
  445.                 var cn = 可点击节点.getNode(j);
  446.                 if (cn) {
  447.                     var c文本 = "";
  448.                     try { c文本 = "" + cn.getText(); } catch (e) {}
  449.                     var c描述 = "";
  450.                     try { c描述 = "" + cn.getDesc(); } catch (e) {}
  451.                     var cID = "";
  452.                     try { cID = "" + cn.getID(); } catch (e) {}
  453.                     print.log("    点击" + (j + 1) + ". text=[" + c文本 + "] desc=[" + c描述 + "] id=[" + cID + "]");
  454.                 }
  455.             }
  456.         }
  457.     } catch (e) {
  458.         print.log("  【页面摘要】输出出错:" + e.message);
  459.     }
  460. }

  461. /**
  462. * 在首页查找签到入口
  463. * 京东签到入口通常在首页顶部"领京豆"图标
  464. * @return {boolean} 成功进入签到页面返回true
  465. */
  466. function 首页查找签到() {
  467.     print.log("\n【签到】在首页查找签到入口...");
  468.     关闭弹窗();
  469.     sleep.millisecond(毫秒 = 500);

  470.     // 调试模式下输出首页节点摘要
  471.     if (config.调试模式 == 'debug') {
  472.         print.log("\n  >>> 首页节点摘要 <<<");
  473.         输出完整页面摘要("首页");
  474.     }

  475.     for (var i = 0; i < config.首页签到入口.length; i++) {
  476.         var 关键词 = config.首页签到入口[i];
  477.         var 节点 = 查找文字节点([关键词]);
  478.         if (节点) {
  479.             print.log("  ✓ 首页找到签到入口:【" + 关键词 + "】");
  480.             if (安全点击节点(节点)) {
  481.                 sleep.second(秒 = config.页面加载等待秒);
  482.                 关闭弹窗();

  483.                 // 验证是否进入签到页面
  484.                 if (检查文字存在(["签到", "立即签到", "签到成功", "已签到", "连签", "京豆", "领取"])) {
  485.                     print.log("✓ 已进入签到页面(首页入口)");
  486.                     return true;
  487.                 }

  488.                 sleep.second(秒 = 2);
  489.                 if (检查文字存在(["签到", "立即签到", "已签到", "连签"])) {
  490.                     print.log("✓ 已进入签到页面(延迟检测)");
  491.                     return true;
  492.                 }

  493.                 // 可能点击后进入了其他页面,返回首页重试
  494.                 print.log("  ⚠ 点击后未进入签到页面,返回重试");
  495.                 auto.back();
  496.                 sleep.second(秒 = 2);
  497.             }
  498.         }
  499.     }

  500.     // 首页顶部可能有签到图标但没有文字,尝试下滑一点找
  501.     print.log("  首页顶部未找到,下滑查找...");
  502.     auto.swipPercent_v2(0.5, 0.3, 0.5, 0.6, 300, 100);
  503.     sleep.second(秒 = 1);

  504.     for (var j = 0; j < config.首页签到入口.length; j++) {
  505.         var 关键词2 = config.首页签到入口[j];
  506.         var 节点2 = 查找文字节点([关键词2]);
  507.         if (节点2) {
  508.             print.log("  ✓ 下滑后找到签到入口:【" + 关键词2 + "】");
  509.             if (安全点击节点(节点2)) {
  510.                 sleep.second(秒 = config.页面加载等待秒);
  511.                 关闭弹窗();
  512.                 if (检查文字存在(["签到", "立即签到", "已签到", "连签", "京豆"])) {
  513.                     print.log("✓ 已进入签到页面(下滑后)");
  514.                     return true;
  515.                 }
  516.             }
  517.         }
  518.     }

  519.     return false;
  520. }

  521. /**
  522. * 在「我的」页面查找签到入口
  523. * @return {boolean} 成功进入签到页面返回true
  524. */
  525. function 我的页面查找签到() {
  526.     print.log("\n【签到】在「我的」页面查找签到入口...");

  527.     if (config.调试模式 == 'debug') {
  528.         print.log("\n  >>> 我的页面节点摘要 <<<");
  529.         输出完整页面摘要("我的页面");
  530.     }

  531.     for (var 尝试次数 = 0; 尝试次数 < config.最大重试次数; 尝试次数++) {
  532.         print.log("  第" + (尝试次数 + 1) + "次在「我的」页面查找...");

  533.         关闭弹窗();
  534.         sleep.millisecond(毫秒 = 500);

  535.         // 方法1:遍历关键词列表查找(text + desc)
  536.         for (var i = 0; i < config.我的页签到入口.length; i++) {
  537.             var 关键词 = config.我的页签到入口[i];
  538.             var 节点 = 查找文字节点([关键词]);
  539.             if (节点) {
  540.                 print.log("  ✓ 「我的」页面找到签到入口:【" + 关键词 + "】");
  541.                 if (安全点击节点(节点)) {
  542.                     sleep.second(秒 = config.页面加载等待秒);
  543.                     关闭弹窗();

  544.                     if (检查文字存在(["签到", "立即签到", "签到成功", "已签到", "连签", "京豆"])) {
  545.                         print.log("✓ 已进入签到页面(我的页入口)");
  546.                         return true;
  547.                     }

  548.                     sleep.second(秒 = 2);
  549.                     if (检查文字存在(["签到", "立即签到", "已签到", "连签"])) {
  550.                         print.log("✓ 已进入签到页面(延迟检测)");
  551.                         return true;
  552.                     }
  553.                 }
  554.             }
  555.         }

  556.         // 方法2:desc组合搜索"领"+"豆"(解决"领88豆"数字每天变化的问题)
  557.         // 京东签到按钮desc格式如"领88豆京豆最高",数字会变但"领"和"豆"不变
  558.         if (尝试次数 == 0) {
  559.             print.log("  关键词未匹配,尝试desc组合搜索「领」+「豆」...");
  560.             var 豆节点 = 查找描述节点含多词(["领", "豆"]);
  561.             if (豆节点) {
  562.                 print.log("  ✓ desc组合搜索找到签到按钮");
  563.                 if (安全点击节点(豆节点)) {
  564.                     sleep.second(秒 = config.页面加载等待秒);
  565.                     关闭弹窗();

  566.                     if (检查文字存在(["签到", "立即签到", "签到成功", "已签到", "连签", "京豆"])) {
  567.                         print.log("✓ 已进入签到页面(desc组合搜索)");
  568.                         return true;
  569.                     }
  570.                 }
  571.             }
  572.         }

  573.         // 下滑查找
  574.         if (尝试次数 < config.最大重试次数 - 1) {
  575.             print.log("  未找到签到入口,下滑查找...");
  576.             auto.swipPercent_v2(0.5, 0.7, 0.5, 0.3, 400, 100);
  577.             sleep.second(秒 = 1);
  578.         }
  579.     }

  580.     return false;
  581. }

  582. /**
  583. * 查找并点击签到入口(主入口函数)
  584. * 查找顺序: 首页 → 我的页面 → 搜索兜底
  585. * @return {boolean} 成功进入签到页面返回true
  586. */
  587. function 进入签到页面() {
  588.     print.log("\n【签到】开始查找签到入口...");
  589.     auto.refresh();

  590.     // 路径1:在首页直接查找签到入口(京东签到入口主要在首页顶部"领京豆")
  591.     print.log("\n  >> 路径1:首页查找");
  592.     if (首页查找签到()) {
  593.         return true;
  594.     }

  595.     // 路径2:进入「我的」页面查找
  596.     print.log("\n  >> 路径2:进入「我的」页面查找");
  597.     if (进入我的页面()) {
  598.         if (我的页面查找签到()) {
  599.             return true;
  600.         }
  601.         // 没找到,返回首页
  602.         auto.back();
  603.         sleep.second(秒 = 2);
  604.     }

  605.     // 路径3:通过搜索进入签到页面
  606.     print.log("\n  >> 路径3:搜索进入签到");
  607.     回到首页();

  608.     var 搜索节点 = 查找文字节点(["搜索", "搜索商品"]);
  609.     if (搜索节点) {
  610.         安全点击节点(搜索节点);
  611.         sleep.second(秒 = 2);

  612.         try {
  613.             input.sendString("京东签到领京豆");
  614.         } catch (e) {
  615.             print.log("  ⚠ 输入失败:" + e.message);
  616.         }
  617.         sleep.second(秒 = 2);

  618.         // 点击搜索按钮
  619.         auto.clickPercent(0.95, 0.05);
  620.         sleep.second(秒 = 3);

  621.         if (检查文字存在(["签到", "领京豆", "签到中心"])) {
  622.             var 签到入口 = 查找文字节点(["签到", "领京豆", "签到中心"]);
  623.             if (签到入口) {
  624.                 安全点击节点(签到入口);
  625.                 sleep.second(秒 = config.页面加载等待秒);
  626.                 if (检查文字存在(["签到", "立即签到", "已签到"])) {
  627.                     print.log("✓ 通过搜索进入签到页面");
  628.                     return true;
  629.                 }
  630.             }
  631.         }
  632.     }

  633.     print.log("✗ 所有路径均无法找到签到入口");
  634.     print.log("\n  >>> 最终页面节点摘要 <<<");
  635.     输出完整页面摘要("最终页面");
  636.     return false;
  637. }

  638. /**
  639. * 执行签到操作
  640. * 在签到页面中查找"签到"按钮并点击
  641. * @return {number} 0=签到成功, 1=今日已签到, 2=签到失败
  642. */
  643. function 执行签到() {
  644.     print.log("\n【签到】执行签到操作...");
  645.     关闭弹窗();
  646.     sleep.millisecond(毫秒 = 500);

  647.     // 检查是否已经签到过
  648.     if (检查文字存在(["已签到", "明天再来", "今日已签到", "已连续签到"])) {
  649.         // 需要区分「已签到」按钮和「已签到」状态文字
  650.         // 如果页面有「已签到」但没有「立即签到」/「签到」按钮,说明今天已签过
  651.         if (!检查文字存在(["立即签到", "签到"]) && 检查文字存在(["已签到", "今日已签到"])) {
  652.             print.log("  ℹ 今日已签到,无需重复操作");
  653.             return 1;
  654.         }
  655.     }

  656.     // 查找并点击"签到"按钮
  657.     var 签到按钮关键词 = ["立即签到", "签到", "点击签到", "签到领取"];
  658.     var 签到按钮 = 查找文字节点(签到按钮关键词);

  659.     if (签到按钮) {
  660.         print.log("  ✓ 找到签到按钮");
  661.         if (安全点击节点(签到按钮)) {
  662.             print.log("  ✓ 已点击签到按钮");
  663.             sleep.second(秒 = 2);

  664.             // 关闭签到后弹出的奖励弹窗
  665.             关闭弹窗();
  666.             sleep.millisecond(毫秒 = 500);

  667.             // 验证签到是否成功
  668.             if (检查文字存在(["签到成功", "签到+", "获得", "领取成功", "已签到"])) {
  669.                 print.log("  &#127881; 签到成功!");
  670.                 return 0;
  671.             }

  672.             // 再等待一下检测
  673.             sleep.second(秒 = 2);
  674.             关闭弹窗();

  675.             if (检查文字存在(["签到成功", "已签到", "明天见", "连签"])) {
  676.                 print.log("  &#127881; 签到成功!(延迟检测)");
  677.                 return 0;
  678.             }

  679.             // 即使没有明确成功提示,如果没有"立即签到"按钮了也算成功
  680.             if (!检查文字存在(["立即签到"])) {
  681.                 print.log("  &#127881; 签到成功(按钮消失验证)");
  682.                 return 0;
  683.             }
  684.         }
  685.     } else {
  686.         print.log("  ⚠ 未找到签到按钮");
  687.         输出页面摘要();
  688.     }

  689.     // 二次尝试:下滑查找签到按钮
  690.     print.log("  下滑查找签到按钮...");
  691.     auto.swipPercent_v2(0.5, 0.6, 0.5, 0.3, 300, 100);
  692.     sleep.second(秒 = 1);
  693.     关闭弹窗();

  694.     var 签到按钮2 = 查找文字节点(签到按钮关键词);
  695.     if (签到按钮2) {
  696.         print.log("  ✓ 下滑后找到签到按钮");
  697.         if (安全点击节点(签到按钮2)) {
  698.             sleep.second(秒 = 2);
  699.             关闭弹窗();
  700.             if (检查文字存在(["签到成功", "已签到", "连签"])) {
  701.                 print.log("  &#127881; 签到成功!(二次尝试)");
  702.                 return 0;
  703.             }
  704.         }
  705.     }

  706.     print.log("  ✗ 签到失败");
  707.     return 2;
  708. }

  709. /**
  710. * 领取签到奖励
  711. * 签到后可能有额外奖励需要手动领取
  712. * @return {boolean} 领取成功返回true
  713. */
  714. function 领取奖励() {
  715.     print.log("\n【奖励】检查并领取额外奖励...");
  716.     sleep.second(秒 = 1);

  717.     var 领取关键词 = ["领取", "立即领取", "收下", "领豆", "去领取", "点击领取"];
  718.     var 领取节点 = 查找文字节点(领取关键词);

  719.     if (领取节点) {
  720.         print.log("  ✓ 找到奖励领取入口");
  721.         if (安全点击节点(领取节点)) {
  722.             sleep.second(秒 = 2);
  723.             关闭弹窗();
  724.             print.log("  &#127873; 已领取奖励");
  725.             return true;
  726.         }
  727.     }

  728.     print.log("  ℹ 暂无额外奖励可领取");
  729.     return false;
  730. }

  731. /**
  732. * 回到京东首页
  733. * @return {boolean} 成功返回首页返回true
  734. */
  735. function 回到首页() {
  736.     print.log("\n【返回】回到京东首页...");

  737.     for (var i = 0; i < 3; i++) {
  738.         auto.back();
  739.         sleep.second(秒 = 1);

  740.         if (检查文字存在(["首页", "分类", "购物车"])) {
  741.             print.log("✓ 已回到首页");
  742.             return true;
  743.         }
  744.     }

  745.     // 兜底:回到桌面重新打开
  746.     print.log("  返回失败,重新打开京东...");
  747.     auto.home();
  748.     sleep.second(秒 = 2);
  749.     if (启动京东()) {
  750.         return true;
  751.     }
  752.     return false;
  753. }

  754. /**
  755. * 重启京东APP
  756. * @return {boolean} 重启成功返回true
  757. */
  758. function 重启京东() {
  759.     print.log("✗ 需要重启京东...");
  760.     try {
  761.         app.resetApp(config.APP包名);
  762.         sleep.second(秒 = 8);
  763.         关闭弹窗();
  764.         print.log("✓ 京东重启成功");
  765.         return true;
  766.     } catch (e) {
  767.         print.log("✗ 重启失败:" + e.message);
  768.         return false;
  769.     }
  770. }

  771. // ============================================================
  772. // 五、主流程
  773. // ============================================================
  774. print.log("\n【主流程】开始京东每日签到领京豆...\n");

  775. var 签到成功次数 = 0;
  776. var 签到跳过次数 = 0;
  777. var 签到失败次数 = 0;

  778. for (var 当前轮次 = 1; ; 当前轮次++) {
  779.     print.log("\n========== 第 " + 当前轮次 + " 轮签到 ==========");

  780.     var 连续错误 = 0;

  781.     // ===== 步骤1:启动京东 =====
  782.     print.log("\n【步骤1】启动京东APP...");
  783.     if (!启动京东()) {
  784.         print.log("✗ 启动失败,等待10秒后重试");
  785.         sleep.second(秒 = 10);
  786.         签到失败次数++;
  787.         continue;
  788.     }
  789.     sleep.second(秒 = 2);

  790.     // ===== 调试模式:只输出页面摘要不签到 =====
  791.     if (config.调试模式 == 'debug') {
  792.         print.log("\n【调试模式】当前为debug模式,只输出页面节点摘要,不执行签到");
  793.         print.log("  >>> 京东首页节点摘要 <<<");
  794.         输出完整页面摘要("京东首页");

  795.         // 同时进入"我的"页面输出摘要
  796.         print.log("\n  >>> 进入「我的」页面输出摘要 <<<");
  797.         if (进入我的页面()) {
  798.             输出完整页面摘要("我的页面");
  799.         }

  800.         print.log("\n【调试模式】请查看上方节点摘要,确认签到入口文字后:");
  801.         print.log("  1. 将关键词加入 config.首页签到入口 或 config.我的页签到入口");
  802.         print.log("  2. 将 config.调试模式 改为 'test' 验证完整签到流程");
  803.         print.log("  3. 验证通过后改为 'false' 进入正常模式");
  804.         print.log("\n  完成时间:");
  805.         print.time();
  806.         break;
  807.     }

  808.     // ===== 步骤2:进入签到页面(首页→我的→搜索三路径) =====
  809.     print.log("\n【步骤2】进入签到页面...");
  810.     if (!进入签到页面()) {
  811.         print.log("⚠ 进入签到页面失败");
  812.         连续错误++;

  813.         if (连续错误 >= config.最大连续错误) {
  814.             print.log("✗ 连续失败,重启京东...");
  815.             重启京东();
  816.             连续错误 = 0;
  817.             continue;
  818.         }
  819.         continue;
  820.     }

  821.     // ===== 步骤3:执行签到 =====
  822.     print.log("\n【步骤3】执行签到...");
  823.     var 签到结果 = 执行签到();

  824.     if (签到结果 == 0) {
  825.         // 签到成功
  826.         签到成功次数++;
  827.         print.log("✓ 签到成功!累计成功:" + 签到成功次数 + " 次");

  828.         // 步骤4:领取额外奖励
  829.         print.log("\n【步骤4】领取额外奖励...");
  830.         领取奖励();

  831.     } else if (签到结果 == 1) {
  832.         // 今日已签到
  833.         签到跳过次数++;
  834.         print.log("ℹ 今日已签到过,跳过");

  835.     } else {
  836.         // 签到失败
  837.         签到失败次数++;
  838.         print.log("✗ 签到失败");
  839.         输出页面摘要();
  840.     }

  841.     // ===== 步骤5:回到首页 =====
  842.     print.log("\n【步骤5】回到首页...");
  843.     回到首页();

  844.     // ===== 统计输出 =====
  845.     print.log("\n【签到统计】");
  846.     print.log("==========================================");
  847.     print.log("  签到成功:" + 签到成功次数 + " 次");
  848.     print.log("  已签跳过:" + 签到跳过次数 + " 次");
  849.     print.log("  签到失败:" + 签到失败次数 + " 次");
  850.     print.log("==========================================");

  851.     // 判断是否需要循环
  852.     if (!config.循环签到) {
  853.         print.log("\n✓ 单次签到模式,任务完成!");
  854.         print.log("  完成时间:");
  855.         print.time();
  856.         break;
  857.     }

  858.     // 循环模式:等待下一次签到
  859.     var 等待秒 = config.循环间隔分钟 * 60;
  860.     print.log("\n等待 " + config.循环间隔分钟 + " 分钟后进行下一次签到...");
  861.     print.log("  下次签到时间:约 " + new Date(Date.now() + 等待秒 * 1000).toLocaleString());

  862.     for (var 倒计时 = 等待秒; 倒计时 > 0; 倒计时 -= 60) {
  863.         var 显示分钟 = Math.floor(倒计时 / 60);
  864.         print.log("  剩余等待时间:约 " + 显示分钟 + " 分钟");
  865.         sleep.second(秒 = Math.min(60, 倒计时));
  866.     }
  867. }

  868. print.log("\n===== 京东每日签到领京豆完成 =====");
复制代码



unto无碍模式auto淘宝千牛自动发货系统nextnocontent
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

相关导读了
    采集亚马逊正版群发工具有没有?
    Apr.20旅行X心语今天来说说YYPOST新功能的一个灵活用法,采集亚马逊商品信息,并且获得排名的软件,亚马逊现在越来越多客户做,淘宝的水是越来越清了,以前做电商的客户,现在都转战到外国,最赚钱的要数一些客户往亚马逊里堆了吧,拿我这个YYPOST的客户,最多的是采集,分析排名,刷价格,刷数量,改价,刷访问量等等技术

    企业发展B2B网站有什么东东软件可以发呢
    标题企业发展网B2B软件,现在虽然B2B网站收录不错,可愁的是心急的人们,他们太想一口吃撑胖子了,发帖宣传虽然不能像佛系那样淡定,但也不能像跑火车那般急躁对待,自己内容不收录,完全是自己操作内容问题,可以参考一下别人的内容是怎么弄的,然后自己要试着转变,而且收录这个内容,常常会变化的,不是一种规则就吃到老

    搜房天下房聊软件哪一个好呢
    本帖最后由 发帖软件 于 2019-5-22 16:15 编辑 2搜房天下群发房聊信息软件,开始本来打算做58同城的,但发一个就要一次点触验证码,这就让人没有感觉到存在的价值了吧,都是卖二手房和新房的搜房天下倒是可以发即时聊天信息,也没有发现他这个网站有啥子限制,登陆一个搜房天下账号,然后采集回来分类列表的网址,然后就一

    大家坛有没有好用的群发工具下载呢
    当你的笑容给我礼貌的招呼,大家坛全自动发帖软件,宣传推广是一场持久战,总是有一些人把软件用了一天,或是几个小时,就觉得自己付出太多了,那加进来的粉丝,或是流量,应该是和宣传多少成正比的,其实没有这么便宜的事,就像很多阅读量超过一百万的视频,或是电影,真正会在屏幕打赏的人不会超过三千,真正大额打赏给主

    群发正版软件中国塑料网
    中国塑料网群发软件YYPOST脚本下载地址,这个网站会有一个很奇怪的问题就是你在首页登陆无半个验证码,但在登陆网址登陆就会有一个验证码,所以我们灵活一些,在首页登陆就不用输入验证码了哈。网站秒收录比较高,但发的都是五金和建筑行业,先前有很多人都是发土建工程的大公司操作的,现在这个网站专为那个行业诞生的吧。

    OpenStreetMap网站正版2019年发帖工具下载
    本帖最后由 发帖软件 于 2019-5-21 11:13 编辑 OpenStreetMap网站全自动群发,OpenStreetMapOpenStreetMap(简称OSM,中文是公开地图)是一个网上地图协作计划,目标是创造一个内容自由且能让所有人编辑的世界地图。有的人编辑地图然后等收录,有的人发日志等收录,我们这里也是利用地图日志做为宣传的目标,简单的脚本理

    搜房天下全自动收短信全自动识别验证码注册账号软件
    房天下自动注册机,这个脚本是前几天发房聊的脚本廷伸品种,这个脚本能做到自动注册账号,自动保存账号,自动发房聊的效果,不过今天我们主要说一说怎么注册账号写脚本吧,这个搜房天天下的账号,可以发提问,可以发房聊,发论坛,发博客,还有发个人中心页都是有秒收的效果的,这样就省去了去买号,去乱花钱的效果了吧,而

    企业邮箱安卓端有什么APP软件可以发的呢
    请输入标题企业邮箱安卓发发送邮箱脚本,这个脚本是利用企业邮箱进行群发的,全程是一种模拟手工操作的过程,所以封号是很少的,而且企业邮箱群发到普通QQ邮箱不容易进垃圾箱中的,所以这个脚本也是这样的原理,不过最好是利用一些多开器,登陆多点的QQ邮箱账号会比较流畅一些,然后用软件一个一个的切换APP进行群发邮件会

    头条留评论软件有没有好用的呢?
    今天整一个今日头条留言软件,对于留言YYPOST是优势是比较大的存在,因为他往往专注一些下拉定位的优点,像今日头条这样,还是需要一些特殊下拉定位的,因为他新闻有长有短,有图有视频的,所以综合起来定位是比较难的,如果用POST也不是很轻松可以破解他的加密参数。这个脚本也是有一个不好的地方就是换号会比较麻烦,您电

    单网页生成神器
    最近新技术,网页生成机占领了整个网络的半壁江山,效果很疯狂,虽然不知道能持续多久,作为开发软件的领头者,一直在找收录的方法,一直在努力创新着,一直被人模仿,却从没有被超越过,这个网页生成机,已经出来有一段时间了,一直没有拿出来分享,醉过醉过,它是利用的一些小小收录漏洞整的,您最好用一些老站域名,进行

关闭
快速回复 返回列表 返回顶部
本站自动发贴软件,是现在最流行的做脚本软件,这种发贴工具,不但发贴收录快,而且抢占好的先机,完全自由编辑,实现针对性群发模拟操作,软件可以顶贴,也可以发贴,可以兼容支持Discuz、PHPWind、Dvbbs三大主流论坛,有手机验证码收件,邮件收发的功能,支持验证码识别,注册问题识别,多线程任务,自动上传头像,自动激活注册邮件,兼容防注册插件,本站软件原创正版,更新效率最快的原创软件。 『网络推广软件』『自动发帖软件』『 自动发帖