123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703 |
- const common = require("./common.js");
- const { swipeRandom, waitTime, openApp, random, xs_控件匹配是否存在, xs_控件是否存在, xs_控件点击, noResponse, findNodeXY } = require("./common.js");
- var douyinUtils = {};
- douyinUtils.appName = "抖音";
- douyinUtils.packageName = 'com.ss.android.ugc.aweme';
- /**关闭屏幕上“以后再说”对话框*/
- douyinUtils.closeFlashWindow = function () {
- try {
- if (xs_控件是否存在("text", "好的")) {
- log("检测到---抖音个人信息保护指引");
- xs_控件点击("text", "好的");//抖音个人信息保护指引
- }
- if (xs_控件是否存在("text", "我知道了")) {
- log("检测到---青少年模式");
- xs_控件点击("text", "我知道了");//青少年模式
- }
- if (xs_控件是否存在("text", "以后再说")) {
- log("检测到---抖音更新界面");
- xs_控件点击("text", "以后再说");//抖音更新界面
- }
- if (xs_控件匹配是否存在("text", "发现通讯录好友")) {
- log("检测到---抖音发现通讯录界面");
- if (xs_控件匹配是否存在("text", "取消")) {
- xs_控件点击("text", "取消");//抖音发现通讯录界面
- }
- if (xs_控件匹配是否存在("text", "暂时不要")) {
- xs_控件点击("text", "暂时不要");//抖音发现通讯录界面
- }
- }
- if (xs_控件是否存在("text", "知道了")) {
- log("检测到---青少年模式");
- xs_控件点击("text", "知道了");//青少年模式
- }
- //TODO
- if (xs_控件是否存在("text", "刷新")) {
- log("检测到---网络异常");
- xs_控件点击("text", "刷新");//网络异常
- }
- if (xs_控件是否存在("text", "挂断")) {
- log("有视频电话打进来");
- xs_控件点击("text", "挂断");//不接视频电话
- }
- if (xs_控件是否存在("text", "取消") && xs_控件是否存在("text", "等待对方接听")) {
- log("拨打出视频电话");
- xs_控件点击("text", "取消");//打视频电话
- }
- if (xs_控件是否存在("text", "好友推荐")) {
- log("检测到---好友推荐");
- back();
- }
- if (xs_控件是否存在("text", "网络错误")) {
- log("检测到---网络错误");
- xs_控件点击("text", "刷新");
- }
- if (xs_控件是否存在("text", "直播已结束")) {
- log("检测到---直播已结束");
- // eslint-disable-next-line no-undef
- swipe(822, 1293, 804, 205, random(500, 1000));
- sleep(2000);
- }
- if (xs_控件是否存在("text", "稍后")) {
- log("稍后", "t");
- click("稍后");
- }
- if (xs_控件是否存在("text", "下次再说")) {
- log("下次再说", "t");
- click("下次再说");
- }
- if (xs_控件是否存在("text", "稍后提醒我")) {
- log("稍后提醒我", "t");
- click("稍后提醒我");
- }
- if (findNodeXY(text("暂不绑定"), true)) {
- log("暂不绑定", "t");
- }
- if (click("立即开始")) {
- log("立即開始", "t");
- }
- if (findNodeXY(text("同意授权"), true)) {
- log("同意授权", "t");
- }
- if (findNodeXY(text("同意"), true)) {
- log("同意", "t");
- }
- //TODO
- if (findNodeXY(id("a9p"), true)) {
- log("拒绝", "来电");
- }
- if (findNodeXY(text("忽略"), true)) {
- log("检测到---链接", "t");
- }
- noResponse();
- }catch (e) {
- console.log(e);
- }
- }
- /**
- * 检查及处理一些意外情况,界面干扰情况,比如弹出的“以后再说”,“不感兴趣”,该方案是单独使用一个独立的线程来执行,不会主线程造成阻塞 ??理解肯定有错
- 这个干了两件事,第一个关闭哪些弹出框,第二 检测任务线程是否卡主,如果连续times 次,检测到卡主,就重启任务线程。.
- * @param {*} taskThread 线程 ,任务线程。
- * @param {*} times 次数,连续检测到任务线程,卡主的次数。每一次是10秒,
- */
- douyinUtils.checkOthers = function (taskThread, times) {
- var tmpIndex = 0;
- var oldActivty = 1;
- if (taskThread) {
- var tTh = taskThread.call(this);
- }
- threads.start(function () {
- var i = 0;
- // eslint-disable-next-line no-constant-condition
- while (true) {
- douyinUtils.closeFlashWindow();
- var curA = common.index;
- if (taskThread) {
- console.log("%d---%d", oldActivty, curA);
- if (oldActivty == curA) {
- console.log("" + (times - tmpIndex) * 10 + "秒后退出,重新开始");
- tmpIndex++;
- } else {
- tmpIndex = 0;
- oldActivty = curA;
- }
- if (tmpIndex > times) {
- var txt = "退出任务重新开始";
- console.log(txt);
- console.log(txt);
- console.log(txt);
- console.log(txt);
- tTh.interrupt();
- back();
- back();
- sleep(5000);
- tTh = taskThread.call(this);
- common.index = 0;
- tmpIndex = 0;
- }
- }
- if (i % 6 == 0) {
- log("activity-->" + curA);
- }
- sleep(10000);
- i++;
- }
- });
- }
- /**
- * 跳转到评论
- */
- douyinUtils.toComment = function () {
- waitTime(3,"点击评论")
- // eslint-disable-next-line no-constant-condition
- while(true){
- var plwg = descStartsWith("评论").findOnce();
- if (plwg != null) {
- console.log("点击评论");
- plwg.click();
- sleep(3000);
- }
- console.log("检测评论页");
- var t = textMatches(".*条评论.*|.*暂无评论.*").find();
- if(t){
- console.log("加载评论完成");
- break;
- }
- if(text("留下你的精彩评论吧").findOnce()){
- back();
- sleep(3000);
- }
- sleep(1000);
- }
- };
- /**
- * 点击斗音界面“我” 按钮
- */
- douyinUtils.toMy = function () {
- text("我").findOne().parent().parent().parent().click();
- }
- /**
- * 点击粉丝按钮
- */
- douyinUtils.toMyFs = function () {
- text("粉丝").findOne().parent().click();
- }
- /**
- * 上滑视屏,冷却时间一秒
- */
- douyinUtils.nextVideo = function () {
- log("上滑")
- // eslint-disable-next-line no-undef
- swipe(device.width * 0.6 + random(-20, 10), device.height * 0.55 + random(-20, 10),
- device.width * 0.62 + random(-20, 10), device.height * 0.35 + random(-20, 10), 1);
- sleep(1000);
- log("冷却")
- }
- /**
- * 下滑视屏,冷却时间一秒
- */
- douyinUtils.lastVideo = function () {
- log("下滑")
- // eslint-disable-next-line no-undef
- swipe(device.width * 0.6 + random(-20, 10), device.height * 0.35 + random(-20, 10),
- device.width * 0.62 + random(-20, 10), device.height * 0.55 + random(-20, 10), 1);
- log("冷却")
- sleep(1000)
- }
- /**
- * 评论翻页
- * @param {*} step 一次翻多少页,默认只翻一页
- */
- douyinUtils.commentNextPage = function (step) {
- var total = step || 1;
- var index = 0;
- while (index < total) {
- waitTime(1, "下一页")
- swipeRandom(device.width * 0.5, device.height * 0.85, device.width * 0.7, device.height * 0.4, 500);
- waitTime(1, "冷却");
- index++;
- }
- }
- /**
- * 跟据用户分享的直播间链接,进入直博间 或者某是,(后面发现非直播间也能进,就是用户分享的,名字没改)
- * @param {*} link 直播间链接
- */
- douyinUtils.toLiveRoom = function (link) {
- setClip(link);
- douyinUtils.closeDy();
- douyinUtils.openDy();
- waitTime(8, "等待抖音冷却,等待看一看出现,如果没出现可能链接有问题");
- textEndsWith("打开看看").findOne().click();
- waitTime(1, "进入指定视频");
- }
- douyinUtils.toRoom = function (link) {
- setClip(link);
- douyinUtils.closeDy();
- waitTime(3);
- douyinUtils.openDy();
- waitTime(8, "等待抖音冷却,等待看一看出现,如果没出现可能链接有问题");
- textEndsWith("看看").findOne().click();
- waitTime(1, "进入指定视频");
- }
- /**
- * 打开抖音
- */
- douyinUtils.openDy = function () {
- openApp(douyinUtils.appName);
- waitTime(10, "加载抖音中");
- }
- /**
- * 等待主页加载完成,等待抖音的主页出现。这些方法都不好使,
- */
- douyinUtils.waitMain = function () {
- global.waitForActivity("com.ss.android.ugc.aweme.main.MainActivity")
- }
- /**
- * 等待视频加载完成
- */
- douyinUtils.waitVideoDetail = function () {
- global.waitForActivity("com.ss.android.ugc.aweme.detail.ui.DetailActivity")
- }
- /**
- * 等待用户个人信息加载完成
- */
- douyinUtils.waitUserProfile = function () {
- global.waitForActivity("com.ss.android.ugc.aweme.profile.ui.UserProfileActivity")
- }
- /**
- * 等待用户自己的粉丝列表加载完成 ?? 是的,但是不太好使
- */
- douyinUtils.waitFollowRelation = function () {
- global.waitForActivity("com.ss.android.ugc.aweme.following.ui.FollowRelationTabActivity")
- }
- /**
- * 等待分享?? 对的,不太好使
- */
- douyinUtils.waitShare = function () {
- global.waitForActivity("com.ss.android.ugc.aweme.refactor.douyin.share.improve.CommonShareDialog")
- }
- /**
- * 等待直播 ?? 对的,不太好使
- */
- douyinUtils.waitLive = function () {
- global.waitForActivity("com.ss.android.ugc.aweme.live.LivePlayActivity")
- }
- /**
- * 返回个人信息
- */
- douyinUtils.backToUserProfile = function () {
- while (global.currentActivity() != "com.ss.android.ugc.aweme.profile.ui.UserProfileActivity") {
- back();
- console.log("返回个人信息");
- sleep(2000);
- }
- }
- /**
- * 返回用户首页
- */
- douyinUtils.backToHome = function () {
- while (global.currentActivity() != "com.ss.android.ugc.aweme.main.MainActivity" && global.currentActivity() != "android.app.Dialog") {
- back();
- console.log("返回用户首页");
- sleep(2000);
- }
- click("首页");
- sleep(2000);
- click("推荐");
- }
- /**
- * 返回用户作品
- */
- douyinUtils.backToDetail = function () {
- while (global.currentActivity() != "com.ss.android.ugc.aweme.detail.ui.DetailActivity" && descStartsWith("评论").findOnce() != null) {
- sleep(1000)
- log("返回用户作品")
- }
- }
- /**
- * 返回评论
- */
- douyinUtils.backToPl = function () {
- while (global.currentActivity() != "com.ss.android.ugc.aweme.detail.ui.DetailActivity") {
- back();
- sleep(1000)
- log( "返回评论")
- }
- }
- /**
- * 是否在评论页中?? ,是的,不好使。偶尔出错
- * @returns
- */
- douyinUtils.isInPly = function () {
- sleep(2000)
- var t = id("title").findOnce();
- if (t) {
- return true;
- }
- return false;
- }
- /**
- * 检查是否可以评论,是否有评论按钮,检测是否有 ‘写评论’,如果有,就是没有人评论过,点进去 要出问题。
- * @returns
- */
- douyinUtils.checkXPl = function () {
- click(device.width * 0.4, device.height * 0.5);
- var i = 2;
- while (i > 0) {
- var t = text("写评论").findOnce();
- if (t != null) {
- return true;
- }
- sleep(1000);
- i--;
- }
- return false;
- }
- /**
- * 关闭抖音??不太像啊 是关闭抖音,用了n种方法,都不是特别好使。
- */
- douyinUtils.closeDy = function () {
- // closeApp(douyinUtils.appName);
- // close1();
- // common.forceStopApp(douyinUtils.packageName);
- common.closeApp(douyinUtils.appName);
- waitTime(3);
- // close1();
- }
- /**
- * 点击坐标清理内存。 分辨率不同,可能不好使
- */
- // eslint-disable-next-line no-unused-vars
- function closex() {
- press(device.width * 0.75, device.height - device.getVirtualBarHeigh() * 0.5, 10);
- waitTime(2, "清理");
- click(device.width * 0.5, device.height - device.getVirtualBarHeigh() * 2);
- }
- /**
- * 清理后台??,强行结束 抖音,但是结束后,有可能,再也启动不起来了。
- */
- function close1() {
- // currentPackage();
- app.openAppSetting(douyinUtils.packageName);
- text(app.getAppName(douyinUtils.packageName)).waitFor();
- let is_sure = textMatches(/(.*强.*|.*停.*|.*结.*|.*行.*)/).findOne();
- if (is_sure.enabled()) {
- textMatches(/(.*强.*|.*停.*|.*结.*|.*行.*)/).findOne().click();
- textMatches(/(.*确.*|.*定.*)/).findOne().click();
- log(app.getAppName(douyinUtils.packageName) + "应用已被关闭");
- sleep(2000);
- back();
- } else {
- log(app.getAppName(douyinUtils.packageName) + "应用不能被正常关闭或不在后台运行");
- back();
- }
- }
- /**
- * 随机进入直播间
- */
- douyinUtils.toLive = function () {
- click(device.width * 0.4, device.height * 0.5);
- waitTime(3, "点击直播");
- desc("直播").findOne().click();
- waitTime(3, "直播加载中")
- }
- /**
- * 点赞
- */
- douyinUtils.Dz = function () {
- press(device.width * 0.4, device.height * 0.4, 10);
- sleep(50)
- press(device.width * 0.4, device.height * 0.4, 10);
- }
- /**
- * 识别性别
- * @returns 0,是男,1是女,2是未知
- */
- douyinUtils.getSex = function () {
- waitTime(0, "识别性别");
- var p = images.captureScreen();
- waitTime(1, '识别性别');
- var sexwg = className("android.widget.TextView").textMatches("\\d+岁").findOnce();
- if (sexwg == null) {
- return 2;
- }
- var bound = sexwg.bounds();
- // eslint-disable-next-line no-undef
- var point = findColor(p, "#18DCF3", {
- region: [bound.left, bound.top, 100, 50],
- threshold: 8
- });
- log("坐标", point)
- if (point != null) {
- return 0;
- }
- // eslint-disable-next-line no-undef
- var point2 = findColor(p, "#FD5473", {
- region: [bound.left, bound.top, 100, 50],
- threshold: 8
- });
- if (point2 != null) {
- return 1;
- }
- return 2;
- }
- /**
- * 取得用户的年龄和地区??
- * @returns
- */
- douyinUtils.getUserAgeAndArea = function () {
- var wg = id("im2").findOnce()
- var rs = { age: '未知', area: '未知' }
- if (!wg) {
- return rs;
- }
- var children = wg.find(className('android.widget.TextView'));
- var ta;
- if (children.length > 1) {
- rs.area = children[1].text();
- ta = children[0].text();
- if (ta.indexOf('岁') != -1) {
- rs.age = ta.replace("岁", '');
- }
- if (ta.replace(/\d+岁/, '').length > 1) {
- rs.area = ta;
- }
- console.log(1, rs);
- return rs;
- }
- if (children.length > 0) {
- ta = children[0].text();
- if (!ta.indexOf('岁') == -1) {
- rs.age = ta.replace("", '');
- }
- if (ta.replace(/\d+岁/, '').length > 1) {
- rs.area = ta;
- }
- console.log(2, rs);
- return rs;
- }
- return rs;
- }
- /**
- * 把字符串格试的日期转换成标准时间
- * @param {*} timeStr 字符串格试的日期
- * @returns 反回成标准时间
- */
- douyinUtils.toStandardTime = function (timeStr) {
- var units = ["刚刚", "分钟", '小时', "昨天", '天'];
- var unitVales = [0, 0.0166, 1, 1, 24];
- let index = 0;
- for (; index < units.length; index++) {
- const element = units[index];
- if (timeStr.indexOf(element) != -1) {
- break;
- }
- }
- console.log(index, "index");
- var time;
- if (index == units.length) {
- console.log("固定日期", timeStr)
- console.log(timeStr.match(/(\d+-\d+-\d+)|(\d+-\d+)/g).join(''))
- timeStr = timeStr.match(/(\d+-\d+-\d+)|(\d+-\d+)/g).join('');
- if (timeStr.length < 6) {
- timeStr = '2021-' + timeStr;
- }
- time = StringToDate(timeStr)
- console.log(time)
- var cha = (new Date().getTime() - time.getTime()) / 1000 / 60 / 60;
- return cha;
- }
- var num = parseInt(timeStr.replace(/[^0-9]/ig, "")) || 1;
- if (index == 3) {
- num = 18
- }
- return unitVales[index] * num;
- }
- /**
- * 字符串转日期
- * @param {*} str
- * @returns
- */
- function StringToDate(str) {
- var strDate = str.split(" ");
- var strDatepart = strDate[0].split("-");
- var dtDate = new Date(strDatepart[0], strDatepart[1] - 1, strDatepart[2]);
- return dtDate;
- }
- /**
- * 抖音搜索
- * @param {*} text 内容 输入的文字
- */
- function inputHs(text) {
- className("android.widget.EditText").findOne().click();
- waitTime(1, "进入输入框页,准备输入文字");
- className("android.widget.EditText").findOne().setText(text);
- log("停留在这里,说明id发生了变化,手动点点击输入框试试");
- var times = 0;
- // eslint-disable-next-line no-constant-condition
- while (true) {
- //发送id
- var t = id("b4l").findOnce();
- if (t != null) {
- t.click();
- break;
- }
- t = desc("发送").findOnce()
- if (t != null) {
- t.click();
- break;
- }
- if (times > 1) {
- log("一直无法点到发送,点击坐标试试");
- var bqwg = desc("表情").findOnce();
- if (bqwg != null) {
- let rect = bqwg.bounds();
- click(rect.right + 10, rect.centerY());
- break;
- }
- }
- var m = className("android.widget.EditText").findOnce();
- if (m != null) {
- click(m.bounds().centerX(), m.bounds().centerY())
- }
- times++;
- sleep(1000);
- }
- }
- douyinUtils.sentMsg=function(msg){
- inputHs(msg);
- }
- /**
- * 随机选择一条进行发送
- * @param {话术数组} msgs
- */
- douyinUtils.sendHs = function (msgs) {
- var tmp = msgs[random(0, msgs.length - 1)];
- var contents = tmp.split(/-+/);
- for (let index = 0; index < contents.length; index++) {
- const element = contents[index];
- inputHs(element);
- }
- }
- /**
- * 输入搜索文字
- * @param {*} txt 要搜索的内容
- */
- douyinUtils.inputToSearch = function (txt) {
- waitTime(6, "准备输入文字");
- className("android.widget.EditText").findOne().setText(txt);
- waitTime(6, "输入完成");
- //click("搜索")
- //eslint-disable-next-line no-constant-condition
- while (true) {
- console.log(text('搜索').find().length);
- var t = text("搜索").findOnce();
- // console.log("查找搜索",t);
- if(t){
- let rect = t.bounds();
- log(rect.centerX(), rect.centerY());
- click(rect.centerX(), rect.centerY());
- }
- sleep(1000)
- if (id("android:id/text1").text("视频").exists()) {
- sleep(3000)
- break;
- }
- }
- }
- /**
- * 点击作品
- */
- douyinUtils.clickZp = function () {
- var t = id("android:id/text1").textStartsWith("作品").findOnce();
- if (t) {
- var txt = t.text();
- click(txt);
- waitTime(1);
- }
- //部分作品看不到
- var i = random(0,5);
- while (i < 5) {
- douyinUtils.commentNextPage();
- i++;
- }
- // eslint-disable-next-line no-undef
- var vwg = descMatches("视频\\d+").findOne().parent();
- //console.log(vwg);
- var sp1 = vwg.findOne(className("android.view.View"));
- if (sp1 != null) {
- sp1.click();
- }
- }
- douyinUtils.isEndOfComment=function(){
- var rs =false;
- rs =rs||text("暂时没有更多了").findOnce()
- rs=rs||textMatches(".*来抢沙发.*").findOnce()
- rs=rs||textMatches(".*部分评论.*").findOnce();
- rs=rs||textMatches(".*上限.*").findOnce();
- return rs;
- }
- /**
- * 跟据抖音UID跳转到用户页
- * @param {*} uid
- */
- douyinUtils.openUserProfileByUid = function (uid) {
- var tmp = "snssdk1128://user/profile/" + uid + "?refer=web&gd_label=click_wap_profile_follow&type=need_follow&needlaunchlog=1"
- app.startActivity({
- data: tmp
- });
- }
- /**
- * 读取用户信息
- * @returns 反回用户信息
- */
- douyinUtils.readUserInfo = function () {
- douyinUtils.toMy();
- var userInfo={};
- try {
- waitTime(3);
- var liked = id('bmk').findOne().text();
- var subed = id('co9').findOne().text();
- var friends = id('co3').findOne().text();
- console.log(common.strToNumber(liked));
- userInfo.huozanNumber = common.strToNumber(liked);
- userInfo.concernNumber = common.strToNumber(subed);
- userInfo.friendNumber = common.strToNumber(friends);
- click('编辑资料');
- waitTime(3)
- var items = id('k6c').find();
- var infos = [];
- for (let index = 0; index < items.length; index++) {
- const item = items[index];
- var info = item.text();
- console.log(info);
- infos.push(info);
- }
- if (infos.length == 0) {
- waitTime(10, "读取失败");
- return null;
- }
- userInfo.name = infos[0];
- userInfo.account = infos[1];
- userInfo.synopsis = infos[2]; //概要
- userInfo.gender = infos[3]
- userInfo.age = infos[4]
- userInfo.address = infos[5]
- userInfo.school = infos[6]
- } catch (error) {
- console.log(error);
- }
- return userInfo;
- }
- module.exports = douyinUtils;
|