lolisaikou / LazyStudy

GNU General Public License v2.0
531 stars 232 forks source link

基于xxqg_helper 3.1.3 UI 修改的42分版强国助手2020.10 #85

Closed zhuxuedefeng closed 3 years ago

zhuxuedefeng commented 4 years ago

20201215 网盘链接https://wws.lanzous.com/b01npbw7a  密码:263a v2.19 20201212 推荐更新。 更新日志: 修正题库已知错题。 修改词形题与注音题答题逻辑,对应修改题库内格式。* 修正双人对战连续答题逻辑。 跟随强国APP升级电台收听逻辑。 修改题目输出日志与题库实际搜索一致。 加入运行日志输出功能,默认/脚本/AiQiangGuo日志.txt。

20201028 https://wws.lanzous.com/b01npbw7a 密码:263a 使用Ivan-cn处理挑战答题的逻辑:随机点击,如果正确,写入题库。 挑战答题支持自定义次数和题数,所以可以用来挂机刷题库。 增加争上游答题次数自定义,双人对战次数=争上游次数-1,因不容易判断答题错误,故该部分未加入随机点击正确写入题库功能。

20201017 https://wws.lanzous.com/iD9ouhihdxi 该版本加入挑战答题分享复活功能,完善部分争上游 对战答题逻辑。

20201016 https://wws.lanzous.com/iZVeahgrufa

0,源代码基于https://github.com/ivanwhaf/xxqg-helper V3.1.3 UI版本进行修改而来。 1,修改学习按钮点击方式,由基于文本"学习"(强国改版后为“工作”)改为基于控件"home_bottom_tab_button_work"点击。 2,积分执行加入循环判断,引入顺序执行(因测试部分手机积分获取时返回Null,获取不到积分)。 3,部分手机本地频道控件位置为13,故引入基于是否存在"切换地区"的判断。文章视频使用随机数(随机1 2 3文章点击推荐 要闻 综合,视频点击第一频道 学习视频 联播频道)。 3,执行逻辑为:文章 12篇30秒(含前2篇文章分享点赞评论),视频 6个60秒,本地频道,挑战答题 1轮*5题,每日答题(至领取奖励已达今日上限),之后循环检查 文章个数时长积分、视频个数积分,本地,挑战,每日答题 积分,不足则循环执行。以上足够之后,检查分享评论积分,不足则学习2篇文章执行分享点赞评论;检查视频时长,不足则收听广播补时长(注意广播不会自动退出,但不影响接下来执行);检查双人对战积分,<1执行一次双人对战;检查争上游答题积分,<2执行两次争上游答题。 4,双人对战和争上游答题为基于延时执行,不算很准确,重在参与(参与分1+2)。提取的题目(已去除题目号1. 2.)在题库中搜索不到答案。争上游两轮结束判断偶尔出错导致执行报错,故放在最后执行。这两项可以提前手动答题,均为单选题也可执行中辅助点击。 5,计划加入:挑战答题不足1轮5题 失败时的分享复活。 6,存在问题:文章 视频重复点击;文章有概率点击到广播,然后不能自动执行,需手动返回学习主页(执行逻辑将文章优先执行后已降低此问题概率)。

@lolisaikou 将已点击文章标题写入数据库避免重复点击,解决思路很棒。挑战答题的结束判断部分,提取不到题目弹出提示而不是报错。 在线题库更新,@ivanwhaf xxqg-helper原链接已挂掉。

zhuxuedefeng commented 4 years ago

延时4秒太长了,我修改了一下为1秒搜题,主要是用个全局oldquestion和question对比,两者不同以及在question不为空值时(为空值时,答案为徐特立,题库第一行?)返回question值,但在搜aquestion时先判断是否已存在"继续挑战"(防止最后一题出错)。剩下的就是题库了的问题了。

测试了下您的题目对比处理法,比我的延时处理更准确。但对普通题目 掐头去尾,我测试反而搜不到题目了。把掐头去尾注释掉,只去除题号搜索反而准确。

zhuxuedefeng commented 4 years ago

https://wws.lanzous.com/b01npbw7a 密码:263a 新版本答题逻辑优化,新增基于题目变化的逻辑判断@Ivan-cn 争上游两轮完成后退出,back4或5个判断逻辑(谜之故障,有时候4步返回退回主页,有时候需要5步返回退回主页),处理方式:先4步返回,再判断是否在我的页面,如是,再返回一次 文章脚本,基于播报的在我手机测试正常,但部分同事手机执行始终翻页不点击。故增加用户选择,基于输入1/2选择执行两个函数 本地,山东省界面变化,原点击第三控件,现新增一个控件,导致第三控件变为跳转或跳转下载第三方app大众日报,故改为点击第一个控件。其他省份请自行测试。本地频道入口原基于新思想判断,但如果主页在综合,会导致判断错误。修改为基于综合(貌似不如进本地先点击推荐,再基于新思想判断点击本地频道,再考虑下。)

zhuxuedefeng commented 4 years ago

测试发现,如果强国APP不在主页,拉起强国app后回到主页的逻辑判断之所以未执行是因为延时问题,加个加载app的延时(3s左右即可)。疏忽了。。。

KB64ba commented 4 years ago

测试发现,如果强国APP不在主页,拉起强国app后回到主页的逻辑判断之所以未执行是因为延时问题,加个加载app的延时(3s左右即可)。疏忽了。。。

while(!(desc("学习").exists() || desc("工作").exists() || id("home_bottom_tab_button_work").exists())){ f++; console.log("正在等待加载出主页"); delay(1); if(f>5){ back(); var f=0; break;}}

可以试试这个

Ivan-cn commented 4 years ago

https://wws.lanzous.com/b01npbw7a 密码:263a 新版本答题逻辑优化,新增基于题目变化的逻辑判断@Ivan-cn 争上游两轮完成后退出,back4或5个判断逻辑(谜之故障,有时候4步返回退回主页,有时候需要5步返回退回主页),处理方式:先4步返回,再判断是否在我的页面,如是,再返回一次 文章脚本,基于播报的在我手机测试正常,但部分同事手机执行始终翻页不点击。故增加用户选择,基于输入1/2选择执行两个函数 本地,山东省界面变化,原点击第三控件,现新增一个控件,导致第三控件变为跳转或跳转下载第三方app大众日报,故改为点击第一个控件。其他省份请自行测试。本地频道入口原基于新思想判断,但如果主页在综合,会导致判断错误。修改为基于综合(貌似不如进本地先点击推荐,再基于新思想判断点击本地频道,再考虑下。)

我是这样回退到主页: //回退返回主页 while (!id("home_bottom_tab_button_work").exists()) { back(); delay(0.5); } break;

另外,掐头去尾是@lolisaikou的,我看了新题库好像并不好用,后来找到了在线的题库,但估计是收费的(qq发信息去取授权也没回复),挑战答题和争上游都可用,我在线搜的题,也是只去除题号搜索,但在字形题就加上第一个选项一起搜索,非常准确,剩下的就是题库的问题了。刚想分享,发现已经在服务器上做了验证。。。真快,就搜不出答案了。。。

zhuxuedefeng commented 4 years ago

基于AiQiangguo衍生一个去题库版,答题随机/查提示。因部分华为机型在判断题库存在函数,path文件路径命令报错。不确定如果去除题库存在判断但保留题库搜索命令下是否能正常搜题。先衍生个去题库单js版。也就用来挂文章 视频 每日答题 本地。争上游 对战去就是送人头,挑战随机对5个概率应该可以买彩票中个小奖。

zhuxuedefeng commented 4 years ago

https://wws.lanzous.com/b01npbw7a 密码:263a 新版本答题逻辑优化,新增基于题目变化的逻辑判断@Ivan-cn 争上游两轮完成后退出,back4或5个判断逻辑(谜之故障,有时候4步返回退回主页,有时候需要5步返回退回主页),处理方式:先4步返回,再判断是否在我的页面,如是,再返回一次 文章脚本,基于播报的在我手机测试正常,但部分同事手机执行始终翻页不点击。故增加用户选择,基于输入1/2选择执行两个函数 本地,山东省界面变化,原点击第三控件,现新增一个控件,导致第三控件变为跳转或跳转下载第三方app大众日报,故改为点击第一个控件。其他省份请自行测试。本地频道入口原基于新思想判断,但如果主页在综合,会导致判断错误。修改为基于综合(貌似不如进本地先点击推荐,再基于新思想判断点击本地频道,再考虑下。)

我是这样回退到主页: //回退返回主页 while (!id("home_bottom_tab_button_work").exists()) { back(); delay(0.5); } break;

另外,掐头去尾是@lolisaikou的,我看了新题库好像并不好用,后来找到了在线的题库,但估计是收费的(qq发信息去取授权也没回复),挑战答题和争上游都可用,我在线搜的题,也是只去除题号搜索,但在字形题就加上第一个选项一起搜索,非常准确,剩下的就是题库的问题了。刚想分享,发现已经在服务器上做了验证。。。真快,就搜不出答案了。。。

没有用你的掐头去尾搜索法,但借用了你的新旧题目对比法,套到我那答题逻辑里,也挺好用。 等待可用的在线题库,因为同事华为mate10不能基于题库做,昨晚刚给他弄了个去题库衍生版。

Ivan-cn commented 4 years ago

//找题目,防出错
while (aquestion == oldaquestion || question == "") { delay(0.3); if (className("android.view.View").text("继续挑战").exists() || textContains("继续挑战").exists()) {
console.info("答题结束!"); return; } else if (className("RadioButton").exists()) { //找题目 aquestion = className("ListView").findOnce().parent().child(0).text(); question = aquestion.substring(3); } }

这个位置我又改了这样,要不然最后一题易出错。

另,之前我用网上题库,部分代码是这样,但现在那狗P服务器加了验证,没办法了。 if (aquestion != oldaquestion) { console.log(aquestion.substring(0, 2) + "题目:" + question); var zixing = "选择词语的正确词形        。"; // 判断是否为字形题 if (question==zixing) { question = question + options[0].substring(3); //在题目后面添加第一选项
} else { question = question.replace(/\s/g, ""); //去除题目空格 } console.log("net"+question); var answer = getZXAnswer(question);//在线搜题 //console.log(answer); question = question.replace(/\s/g, ""); //再去除字形题的题目空格,为本地题库准备 console.log("local"+question);
if (/^[a-zA-Z]{1}$/.test(answer)) {//如果为ABCD形式 var indexAnsTiku = indexFromChar(answer.toUpperCase()); answer = options[indexAnsTiku]; //toastLog("answer from char=" + answer); } let hasClicked = false; let listArray = className("ListView").findOnce().children();//题目选项列表 //更新本地题库 if (answer.length!=0) {//在线找到答案 console.log("已在线搜索到答案");
//对比本地题库,如果没有就加入tiku表 var tiku_answer = getAnswer(question, 'tiku'); if (tiku_answer.length == 0) {//tiku表中没有则到tikuNet表中搜索答案 tiku_answer = getAnswer(question, 'tikuNet'); if (tiku_answer.length == 0) {
//加入本地题库 tiku 表 var sql = "INSERT INTO tiku VALUES ('" + question + "','" + answer + "','')"; insertOrUpdate(sql); console.log("更新本地题库答案..."); //delay(1); } } } //本地搜题 if (answer.length == 0) {//在线没有找到答案,本地数据库查找 console.log("在线没有找到答案,尝试本地数据库查找"); answer = getAnswer(question, 'tiku'); if (answer.length == 0) {//tiku表中没有则到tikuNet表中搜索答案 answer = getAnswer(question, 'tikuNet'); } } console.info("答案:" + answer); //如果没找到答案

你的更新题库和博主的一样,前面少一个字,且很多答题为空值

Ivan-cn commented 4 years ago

while (!className("RadioButton").exists());//@KB64ba建议使用while判断 if (className("RadioButton").exists() || aquestion.length == 0) { //delay(0.3); //这里延时有可能界面已变化,在最后一题会出错 var aquestion = className("ListView").findOnce().parent().child(0).text(); var question = aquestion.substring(3); //争上游和对战题目前带1.2.3.需去除 //找题目,防出错
while (aquestion == oldaquestion || question == "") { delay(0.5); if (className("android.view.View").text("继续挑战").exists() || textContains("继续挑战").exists()) {
console.info("答题结束!"); return; } else if (className("RadioButton").exists()) { //找题目 aquestion = className("ListView").findOnce().parent().child(0).text(); question = aquestion.substring(3); } }

Ivan-cn commented 4 years ago

改写了争上游循环的主要代码,用try来防止最后一题的出错信息。 就差好的题库了。

function zsyQuestionLoop() {
while (className("RadioButton").exists()) {//@Ivan-cn修改 try { //找题目,防出错
var aquestion = className("ListView").findOnce().parent().child(0).text(); var question = aquestion.substring(3); //争上游和对战题目前带1.2.3.需去除 while (aquestion == oldaquestion || question == "") { delay(0.5); //找题目 aquestion = className("ListView").findOnce().parent().child(0).text(); question = aquestion.substring(3);
}
var chutiIndex = question.lastIndexOf("出题单位");//@chongyadong添加 if (chutiIndex != -1) { question = question.substring(0, chutiIndex - 2); } // var options = [];//选项列表 if (className("RadioButton").exists()) { className("ListView").findOne().children().forEach(child => { var answer_q = child.child(0).child(1).text(); options.push(answer_q); }); } else { console.error("答案获取失败!"); return; } // if (aquestion != oldaquestion) { console.log(aquestion.substring(0, 2) + "题目:" + question); var zixing = "选择词语的正确词形        。"; // 判断是否为字形题 if (question==zixing) { question = question + options[0].substring(3); //在题目后面添加第一选项
} else { question = question.replace(/\s/g, ""); //去除题目空格 }

            question = question.replace(/\s/g, "");  //再去除字形题的题目空格,为本地题库准备

            if (/^[a-zA-Z]{1}$/.test(answer)) {//如果为ABCD形式
                var indexAnsTiku = indexFromChar(answer.toUpperCase());
                answer = options[indexAnsTiku];
                //toastLog("answer from char=" + answer);
            }
            let hasClicked = false;
            let listArray = className("ListView").findOnce().children();//题目选项列表

            //本地搜题
            answer = getAnswer(question, 'tiku');
                if (answer.length == 0) {//tiku表中没有则到tikuNet表中搜索答案
                   answer = getAnswer(question, 'tikuNet');
                }

            console.info("答案:" + answer);
            //如果没找到答案
            if (answer.length == 0) {
                let i = random(0, listArray.length - 1);
                console.error("没有找到答案,随机点击");
                listArray[i].child(0).click();//随意点击一个答案
                hasClicked = true;
                console.log("------------------------");
            } else {//如果找到了答案 该部分问题: 选项带A.B.C.D.,题库返回答案不带,char返回答案带
                var answer_a = answer.substring(0, 2);//定义answer_a,获取答案前两个字符对比A.B.C.D.应该不会出现E选项
                if (answer_a == "A." || answer_a == "B." || answer_a == "C." || answer_a == "D.") {
                    listArray.forEach(item => {
                        var listDescStrb = item.child(0).child(1).text();
                        if (listDescStrb == answer) {
                            item.child(0).click();//点击答案
                            hasClicked = true;
                            console.log("------------------------");
                        }
                    });
                } else {
                    listArray.forEach(item => {
                        var listDescStra = item.child(0).child(1).text();
                        var listDescStrb = listDescStra.substring(3);//选项去除A.B.C.D.再与answer对比
                        if (listDescStrb == answer) {
                            item.child(0).click();//点击答案
                            hasClicked = true;
                            console.log("------------------------");
                        }
                     });
                }
            }
            if (!hasClicked) {//如果没有点击成功
                console.error("未能成功点击,随机点击");
                let i = random(0, listArray.length - 1);
                listArray[i].child(0).click();//随意点击一个答案
                console.log("------------------------");
            }
        } 
    } catch (e) {
        if (!className("RadioButton").exists() || className("android.view.View").text("继续挑战").exists() || textContains("继续挑战").exists() || !textContains("距离答题结束").exists()) {  
            console.info("答题结束!");
            delay(0.5);
            return;                              
        }
    }
//旧题目
oldaquestion = aquestion;
delay(0.5);
}
if (aquestion.length == 0) {
    console.error("提取题目失败!");
    let listArray = className("ListView").findOnce().children();//题目选项列表
    let i = random(0, listArray.length - 1);
    console.log("随机点击");
    listArray[i].child(0).click();//随意点击一个答案
    return;
}      

}

Ivan-cn commented 4 years ago

已测试成功,除广播电台外,分为10个项目随机顺序进行学习,基本实现ai学习,主要代码如下: //各个学习模块,除广播电台先开始听,其他各个学习模块随机顺序执行 function xx1(){ if (myScores['订阅'] != 2) { sub();//订阅 } }

function xx2(){ if (myScores['挑战答题'] != 6) { challengeQuestion();//挑战答题 } }

function xx3(){ if (myScores['每日答题'] != 5) { dailyQuestion();//每日答题 } }

function xx4(){ if (myScores['本地频道'] != 1) { localChannel();//本地频道 } }

function xx5(){ if (vCount != 0) { videoStudy_news();//看视频 } }

function xx6(){ //增加双人对战和争上游答题 if (myScores["双人对战"] < 1) { SRQuestion();//双人对战 }
}

function xx7(){ if (myScores["争上游答题"] < 2) { zsyQuestion();//争上游答题 } } function xx8(){ if (myScores['专项答题'] == 0) {//无分值即尝试答题 specialQuestion();//专项答题 } }

function xx9(){ if (myScores['每周答题'] == 0) {//无分值即尝试答题 weeklyQuestion();//每周答题 } }

function xx10(){ while (aCount != 0) { var x = 0; articleStudy(x);//学习文章,包含点赞、分享和评论 console.info("等待十秒,然后确认文章是否已满分。"); delay(10); getScores(1); x++; if (x > 2) {//尝试三次 console.info("尝试3次未满分,暂时跳过。"); break; } } }

function main() { if (!judge_tiku_existence()) {//题库不存在则退出 return; } auto.waitFor();//等待获取无障碍辅助权限 start_app();//启动app var path = files.path("list.db"); var start = new Date().getTime();//程序开始时间

getScores();//获取积分
//听电台广播
if (rTime != 0) {
    listenToRadio();//听电台广播
}
var r_start = new Date().getTime();//广播开始时间
//学习文章,包含点赞、分享和评论

var funArr = [xx1,xx2,xx3,xx4,xx5,xx6,xx7,xx8,xx9,xx10],func;//随机学习各模块
while(funArr.length != 0){
    func = funArr.splice(random(0,funArr.length-1),1)[0];
    func();
}//随机学习各模块

var end = new Date().getTime();//广播结束时间
var radio_time = (parseInt((end - r_start) / 1000));//广播已经收听的时间
radio_timing(parseInt((end - r_start) / 1000), rTime - radio_time);//广播剩余需收听时间
if (rTime != 0) {
    stopRadio();
}
end = new Date().getTime();
console.info("您今日学习获得"+xxScores+"分");
console.log("运行结束,共耗时" + (parseInt(end - start)) / 1000 + "秒");
files.copy(path, "/sdcard/Download/list.db");
console.warn("自动备份已学文章列表到/sdcard/Download!!!");

} //main()

zhuxuedefeng commented 4 years ago

改写了争上游循环的主要代码,用try来防止最后一题的出错信息。 就差好的题库了。

function zsyQuestionLoop() { while (className("RadioButton").exists()) {//@Ivan-cn修改 try { //找题目,防出错 var aquestion = className("ListView").findOnce().parent().child(0).text(); var question = aquestion.substring(3); //争上游和对战题目前带1.2.3.需去除 while (aquestion == oldaquestion || question == "") { delay(0.5); //找题目 aquestion = className("ListView").findOnce().parent().child(0).text(); question = aquestion.substring(3); } var chutiIndex = question.lastIndexOf("出题单位");//@chongyadong添加 if (chutiIndex != -1) { question = question.substring(0, chutiIndex - 2); } // var options = [];//选项列表 if (className("RadioButton").exists()) { className("ListView").findOne().children().forEach(child => { var answer_q = child.child(0).child(1).text(); options.push(answer_q); }); } else { console.error("答案获取失败!"); return; } // if (aquestion != oldaquestion) { console.log(aquestion.substring(0, 2) + "题目:" + question); var zixing = "选择词语的正确词形        。"; // 判断是否为字形题 if (question==zixing) { question = question + options[0].substring(3); //在题目后面添加第一选项 } else { question = question.replace(/\s/g, ""); //去除题目空格 }

            question = question.replace(/\s/g, "");  //再去除字形题的题目空格,为本地题库准备

            if (/^[a-zA-Z]{1}$/.test(answer)) {//如果为ABCD形式
                var indexAnsTiku = indexFromChar(answer.toUpperCase());
                answer = options[indexAnsTiku];
                //toastLog("answer from char=" + answer);
            }
            let hasClicked = false;
            let listArray = className("ListView").findOnce().children();//题目选项列表

            //本地搜题
          answer = getAnswer(question, 'tiku');
                if (answer.length == 0) {//tiku表中没有则到tikuNet表中搜索答案
                   answer = getAnswer(question, 'tikuNet');
              }

          console.info("答案:" + answer);
            //如果没找到答案
            if (answer.length == 0) {
                let i = random(0, listArray.length - 1);
                console.error("没有找到答案,随机点击");
                listArray[i].child(0).click();//随意点击一个答案
                hasClicked = true;
                console.log("------------------------");
            } else {//如果找到了答案 该部分问题: 选项带A.B.C.D.,题库返回答案不带,char返回答案带
                var answer_a = answer.substring(0, 2);//定义answer_a,获取答案前两个字符对比A.B.C.D.应该不会出现E选项
                if (answer_a == "A." || answer_a == "B." || answer_a == "C." || answer_a == "D.") {
                    listArray.forEach(item => {
                        var listDescStrb = item.child(0).child(1).text();
                        if (listDescStrb == answer) {
                            item.child(0).click();//点击答案
                            hasClicked = true;
                            console.log("------------------------");
                        }
                    });
                } else {
                    listArray.forEach(item => {
                        var listDescStra = item.child(0).child(1).text();
                        var listDescStrb = listDescStra.substring(3);//选项去除A.B.C.D.再与answer对比
                        if (listDescStrb == answer) {
                            item.child(0).click();//点击答案
                            hasClicked = true;
                            console.log("------------------------");
                        }
                     });
                }
            }
            if (!hasClicked) {//如果没有点击成功
                console.error("未能成功点击,随机点击");
                let i = random(0, listArray.length - 1);
                listArray[i].child(0).click();//随意点击一个答案
                console.log("------------------------");
            }
        } 
    } catch (e) {
        if (!className("RadioButton").exists() || className("android.view.View").text("继续挑战").exists() || textContains("继续挑战").exists() || !textContains("距离答题结束").exists()) {    
            console.info("答题结束!");
            delay(0.5);
            return;                              
        }
    }
//旧题目
oldaquestion = aquestion;
delay(0.5);
}
if (aquestion.length == 0) {
    console.error("提取题目失败!");
    let listArray = className("ListView").findOnce().children();//题目选项列表
    let i = random(0, listArray.length - 1);
    console.log("随机点击");
    listArray[i].child(0).click();//随意点击一个答案
    return;
}      

}

争上游出错情况是:本轮失败,且最后一题恰好错误,则有概率跑飞,可能还和延时有关。所以我认为关键还是捕捉分析成功/失败标志。 10 25,刚度娘了下javascript try catch语句,是个处理错误的好方法。 挑战答题,随机点击的 正确(非错误标志)则把题目和点击答案更新进题库;错误则把所有选项输出到日志(或参考网友建议建立错题库,把题目+所有选项更新进去,回头手工处理) 争上游 对战答题,基于颜色识别红色,或者基于振动马达状态/振动传感器识别答题是否错误。 另外,你的返回主页代码,对清掉强国app后台,初始打开强国app加载的不友好(加载过程到出现学习id延时长达7s~手机配置 网速很大程度影响,但只要没有学习id就会触发back)。不过用在里面执行完某模块返回主页,整体逻辑性好多了。

Ivan-cn commented 3 years ago

今天重写了start_app函数,其中start_app的代码如下:

function start_app() { //重写start_app函数,使其适合多个场景 //启动强国主页,回退到主页并点击正下方的"学习"按钮 let err = false; while (!err) { //等待强国主页加载 try { //AppDynamicText(); if (app.getAppName(currentPackage()) != "学习强国" ){//如果强国未启动 console.log("启动学习强国"); if (!launchApp("学习强国")){//启动学习强国app console.error("找不到学习强国App!"); return; } } else { //delay(3); console.log("等待加载出主页"); if (currentActivity()!="com.alibaba.android.user.login.SignUpWithPwdActivity") {//如果强国界面不为密码登录页 if ( currentActivity()=="android.widget.FrameLayout") {//强国主界面 if (id("home_bottom_tab_button_work").exists()) {//如果发现"学习"按钮 id("home_bottom_tab_button_work").findOne().click();//点击主页正下方的"学习"按钮 err = true; }
} else { back(); delay(1); } } else { console.error("未登录学习强国账号,请登录后重试!"); return; }

        }
        delay(2);
    } catch (e) {//如果出错?
        //console.log(e);
        console.error("出现错误,请检查!");
    }
}

}

然后把所有需要回退的位置用start_app()应该就可以了,或在每个需要执行的函数前先运行一次。

Ivan-cn commented 3 years ago

最新的zsy循环函数:

function zsyQuestionLoop() {
if (className("ListView").exists()) {
while (!textContains("继续挑战").exists()) { //等待强国主页加载 try { var aquestion = className("ListView").findOnce().parent().child(0).text(); var question = aquestion.substring(3); //争上游和对战题目前带1.2.3.需去除 if ( aquestion != oldaquestion && question!="") { console.log("题目:" + question); // var chutiIndex = question.lastIndexOf("出题单位"); if (chutiIndex != -1) { question = question.substring(0, chutiIndex - 2); }

                var options = [];//选项列表
                if (className("ListView").exists()) {
                    className("ListView").findOne().children().forEach(child => {
                        var answer_q = child.child(0).child(1).text();
                        options.push(answer_q);
                    });
                } else {
                    console.error("答案获取失败!");
                    return;
                }

                // 判断是否为字形题和本地搜题
                if (question==zixing) {
                    question = question + options[0].substring(3); //在题目后面添加第一选项               
                } 

                question = question.replace(/\s/g, "");  //再去除字形题的题目空格,为本地题库准备

                if (/^[a-zA-Z]{1}$/.test(answer)) {//如果为ABCD形式
                    var indexAnsTiku = indexFromChar(answer.toUpperCase());
                    answer = options[indexAnsTiku];
                    //toastLog("answer from char=" + answer);
                }

                let hasClicked = false;
                let listArray = className("ListView").findOnce().children();//题目选项列表

                //本地搜题

                    answer = getAnswer(question, 'tiku');
                    if (answer.length == 0) {//tiku表中没有则到tikuNet表中搜索答案
                        answer = getAnswer(question, 'tikuNet');
                    }

                //本地搜题

                console.info("答案:" + answer);
                //如果没找到答案
                if (answer.length == 0) {
                    let i = random(0, listArray.length - 1);
                    console.error("没有找到答案,随机点击");
                    listArray[i].child(0).click();//随意点击一个答案
                    hasClicked = true;
                    console.log("------------------------");
                } else {//如果找到了答案 该部分问题: 选项带A.B.C.D.,题库返回答案不带,char返回答案带
                    var answer_a = answer.substring(0, 2);//定义answer_a,获取答案前两个字符对比A.B.C.D.应该不会出现E选项
                    if (answer_a == "A." || answer_a == "B." || answer_a == "C." || answer_a == "D.") {
                        listArray.forEach(item => {
                        var listDescStrb = item.child(0).child(1).text();
                            if (listDescStrb == answer) {
                                item.child(0).click();//点击答案
                                hasClicked = true;
                                console.log("------------------------");
                            }
                        });
                    } else {
                        listArray.forEach(item => {
                            var listDescStra = item.child(0).child(1).text();
                            var listDescStrb = listDescStra.substring(3);//选项去除A.B.C.D.再与answer对比
                            if (listDescStrb == answer) {
                                item.child(0).click();//点击答案
                                hasClicked = true;
                                console.log("------------------------");
                            }
                        });
                    }
                }
                if (!hasClicked){//如果没有点击成功
                    console.error("未能成功点击,随机点击一个");
                    delay(randomNum(0.5, 1));
                    let i = random(0, listArray.length - 1);
                    listArray[i].child(0).click();//随意点击一个答案
                    console.log("------------------------");
                }
                var oldaquestion = aquestion; //对比新旧题目
                delay(0.5);
                //完成一道题目作答
            }  
            //delay(0.5);
        }catch (e) {
            //console.log(e); //输出错误信息,调试用
            console.error("答题结束,出现错误,请检查!");
            return;
            /*
            if (className("android.view.View").text("继续挑战").exists() || textContains("继续挑战").exists() || !textContains("距离答题结束").exists()) {    
                console.info("答题结束!");
                delay(0.5);
                return;
            }    
            */              
        }                           
    }       
} else {
    console.error("提取题目失败!");
    let listArray = className("ListView").findOnce().children();//题目选项列表
    let i = random(0, listArray.length - 1);
    console.log("随机点击一个");
    listArray[i].child(0).click();//随意点击一个答案
    return;
}   

}

Ivan-cn commented 3 years ago

挑战答题单独js,随机答对即加入本地题库,可选循环函数进一键js即可:

importClass(android.database.sqlite.SQLiteDatabase); var lCount = 1;//挑战答题轮数 var qCount = 20;//挑战答题每轮答题数,强刷题库,正常为5道题

var zixing = "选择词语的正确词形        。"; //已定义为全局变量

/**

/**

/**

/**

function indexFromChar(str) { return str.charCodeAt(0) - "A".charCodeAt(0); }

/**

function drawfloaty(x, y) { //floaty.closeAll(); var window = floaty.window(

);
window.setPosition(x, y - 45);
return window;

}

/**

  • @description: 挑战答题
  • @param: null
  • @return: null */ function challengeQuestion() { text("我的").click(); while (!textContains("我要答题").exists()); delay(1); click("我要答题"); while (!text("每日答题").exists()); delay(1); className("android.view.View").text("每日答题").findOne().parent().parent().child(10).click(); console.log("开始挑战答题") delay(4); // let conNum = 0;//连续答对的次数 let lNum = 0;//轮数 while (true) { delay(2); if (!className("RadioButton").exists()) { toastLog("没有找到题目!请检查是否进入答题界面!"); console.error("没有找到题目!请检查是否进入答题界面!"); console.log("停止"); break; } challengeQuestionLoop(conNum); delay(0.5); if (text("v5IOXn6lQWYTJeqX2eHuNcrPesmSud2JdogYyGnRNxujMT8RS7y43zxY4coWepspQkvw" + "RDTJtCTsZ5JW+8sGvTRDzFnDeO+BcOEpP0Rte6f+HwcGxeN2dglWfgH8P0C7HkCMJOAAAAAElFTkSuQmCC").exists())//遇到❌号,则答错了,不再通过结束本局字样判断 { if (conNum >= qCount) { lNum++; } if (lNum >= lCount) { console.log("挑战答题结束!返回主界面!"); //回退返回主页 while (!id("home_bottom_tab_button_work").exists()) { back(); delay(0.5); } break; } else { console.log("出现错误,等5秒开始下一轮...") delay(3);//等待5秒才能开始下一轮 back(); //desc("结束本局").click();//有可能找不到结束本局字样所在页面控件,所以直接返回到上一层 delay(2); text("再来一局").click() delay(4); if (conNum < 5) { conNum = 0; } } } else//答对了 { conNum++; } } conNum = 0; }

function main() { console.setPosition(0, device.height / 2);//部分华为手机console有bug请注释本行 console.show(); delay(1); while (currentPackage() != "cn.xuexi.android") { app.launch("cn.xuexi.android"); console.log("正在启动学习强国..."); sleep(3000); }
while (!id("home_bottom_tab_button_work").exists()); challengeQuestion(); console.hide() } main() //module.exports = main;

zhuxuedefeng commented 3 years ago

//挑战答题引入Ivan-cn的处理方式,将随机点击的正确答案写入题库 /**

uhappylearning commented 3 years ago

提示253行错误

zhuxuedefeng commented 3 years ago

请注释掉253所在代码块,UI update题库。如果喜欢在线更新题库,请自行下载lazystudy或onekey(基于不同地址)。不过现在AI QiangGuo,可使用挑战答题收集题库(挑战答题20轮,每轮30题挂机半天)

zhuxuedefeng commented 3 years ago

20201029计划加入功能: 1, 在线检查程序更新。这个好像在哪儿见过相关代码,只需要找一个外链固定不变的地址即可。蓝奏云文件夹分享可以保持不变,但需要输入密码访问。github也适合。 2,向Ivan-cn学习,多账号挂机,做在ui界面。 3,每周答题 专项答题 订阅(两个答题需要先做接近保质期的,先向下滑动找已做,再找上面临近的) 4,文章部分逻辑,已读未读文章区分,初步打算基于数据库,把对比数据库放在点击之前。

Ivan-cn commented 3 years ago

修复每日答题不能下一步的bug: if (textContains("确定").exists()) { text("确定").click(); delay(0.5); } else if (textContains("下一题").exists()){ //click("下一题"); text("下一题").click(); delay(0.5); } else if (textContains("完成").exists()) { text("完成").click(); delay(0.5); } else { console.warn("未找到右上角确定按钮控件,根据坐标点击"); click(device.width 0.85, device.height 0.06);//右上角确定按钮,根据自己手机实际修改 }

checkAndUpdate(question, ansTiku, answer);//检查提示答案,更新本地题库
console.log("------------------------");
delay(2);

}

Ivan-cn commented 3 years ago

以及填空题卡住不能填写的bug: if (textStartsWith("填空题").exists()) { if (answer == "") { //答案空,前面题库未找到答案,找提示 var tipsStr = getTipsStr(); answer = getAnswerFromTips(questionArray, tipsStr); console.info("提示答案:" + answer); var answerinput=className("EditText").findOnce().parent().child(0);//10.28修改填空题的输入方法 answerinput.setText(answer);//10.28修改填空题的输入方法 delay(0.1); / setText(0, answer.substr(0, blankArray[0])); if (blankArray.length > 1) { for (var i = 1; i < blankArray.length; i++) { setText(i, answer.substr(blankArray[i - 1], blankArray[i])); } } /
} else { //答案非空,题库中已找到答案 console.info("答案:" + answer); var answerinput=className("EditText").findOnce().parent().child(0);//10.28修改填空题的输入方法 answerinput.setText(answer);//10.28修改填空题的输入方法 delay(0.1); / setText(0, answer.substr(0, blankArray[0])); if (blankArray.length > 1) { for (var i = 1; i < blankArray.length; i++) { setText(i, answer.substr(blankArray[i - 1], blankArray[i])); }
}
/ } }

zhuxuedefeng commented 3 years ago

计划加入功能5,题库自净化(针对挑战答题,如果争上游和对战可以识别正误则跟进):如果基于题库答题却错误,则在数据库删除此题。因为目前所用题库中有部分错误题,或者适配每日答题却导致挑战和争上游/对战不适配的题,该部分内容还是删除了吧。 需要数据库操作语句:删除,哪位来试下?

silent0910 commented 3 years ago

计划加入功能5,题库自净化(针对挑战答题,如果争上游和对战可以识别正误则跟进):如果基于题库答题却错误,则在数据库删除此题。因为目前所用题库中有部分错误题,或者适配每日答题却导致挑战和争上游/对战不适配的题,该部分内容还是删除了吧。 需要数据库操作语句:删除,哪位来试下?

感谢大佬的无私奉献!!!!!!!!!!

Lee-20 commented 3 years ago

分享两段自用脚本里的,我也不知道出自哪里了,提供一个思路吧。 //写库 if (text("v5IOXn6lQWYTJeqX2eHuNcrPesmSud2JdogYyGnRNxujMT8RS7y43zxY4coWepspQkvwRDTJtCTsZ5JW+8sGvTRDzFnDeO+BcOEpP0Rte6f+HwcGxeN2dglWfgH8P0C7HkCMJOAAAAAElFTkSuQmCC").exists() == false) { //如果答对,插入记录 if (ansSearchArray.length == 0 && clickAns != "") { var sqlstr = "INSERT INTO tiku VALUES ('" + question + "','" + clickAns + "','')"; executeSQL(sqlstr); toastLog("增加答案" + answer); } } else { //tiku表中有,但答错,删除错误记录 if (ansSearchArray.length > 0 && hasError == false) { //删掉这条 toastLog("删除答案: " + answer); var sqlstr = "DELETE FROM tiku WHERE question LIKE '" + question + "'"; executeSQL(sqlstr); } }

以上是挑战答题的。 以下是每日答题的。

/**

zhuxuedefeng commented 3 years ago

else{ if (ansTiku == "" && answer != "") { //正确进入下一题,且题库答案为空
var sql = "INSERT INTO tiku VALUES ('" + question + "','" + answer + "','')";//写库语句 insertOrUpdate(sql); console.log("更新题库答案..."); } if(ansTiku != "" && answer != ""){ var sql = "DELETE FROM tiku WHERE question LIKE '" + question + "'";//删库语句 insertOrUpdate(sql); console.log("删除题库答案!!!") } } 理论执行结果:碰上错题,X号答错来到更新题库函数,因不符合上面每日答题部分,来到else,之后应该看ansTiku题库搜索结果和answer答案获取结果:如果上面题库搜索为空,(随机点击正确)答案获取到,更新到题库;如果上面题库搜索不为空(表示有错误答案),<已经错误>,(随机点击无论正误都不影响)答案获取到,则说明题库错误,应该删除。 实际执行看log输出:答错,题库无答案,更新(到此正常),但紧接着又触发了删除语句。 另外,字形题题库有答案但错误,因为用的like question匹配删除,会清掉全部字形题目,所以需要前置if判断字形题不能执行删库/写库语句。之前的字形题在题库格式是 question 选项,answer ;现在看到的题库格式是question,answer,那么如何处理确保精确不误删?

zhuxuedefeng commented 3 years ago

挑战答题情况: question题干: 获取到 ansTiku/ansTikuNet题库:有 答题结果:正确!x 执行:进下一题 question题干: 获取到 ansTiku/ansTikuNet题库:有 答题结果:错误x 执行:删除题库记录(如果能获取到颜色,则还可以提取正确答案再写入) question题干: 获取到 ansTiku/ansTikuNet题库:有 答题结果:不能点击,触发不能点击随机点击 随机点击 answer正确!x,执行 更新题库,进下一题 question题干: 获取到 ansTiku/ansTikuNet题库:无 答题结果:触发随机点击 随机点击 answer正确!x,执行 更新题库,进下一题 question题干: 获取到 ansTiku/ansTikuNet题库:无 答题结果:触发随机点击 随机点击 answer错误x,执行 无 已答足够,随机点击 question题干 :可以获取 ansTiku/ansTikuNet题库:无 答题结果:随机点击 answer正确!x,执行 更新题库,进下一题随机点击 已答足够,随机点击 question题干 :可以获取 ansTiku/ansTikuNet题库:无 答题结果:随机点击 answer错误x,执行 退出

以上需去除字形题,基于question改动,字形题会整个改动

zhuxuedefeng commented 3 years ago

每日答题情况: 视频题需依赖更新;字形题需视其在数据库内结构 构造语句,不然也是全局变动;提示与题干结构不符的情况,依赖更新。

zhuxuedefeng commented 3 years ago

争上游和对战:可以尝试依靠结束答题后的温故知新环节来检查答案,正误能区分id控件,尚未测试是否容易提取题干和答案。可以在UI中做选择选项是否执行。

xiaodiaoz commented 3 years ago

疫情期间无聊研究的新闻标题抓取及判断

/**

function nwpd(){ var news = className("android.view.View").depth(21).findOnce(1).desc()//获取新闻标题 var dbName = "tiku.db"; var path = files.path(dbName); var db = SQLiteDatabase.openOrCreateDatabase(path, null);//读取数据库三部 sql = "SELECT * FROM dad WHERE news = '" + news + "'" var cursor = db.rawQuery(sql, null);//用来执行select

if (cursor.moveToFirst()) {
    console.log("当前新闻看过了哦,即将退出");

    cursor.close();    
}
cursor.close();//关闭数据库

}

老版本的,新版本我还没下过,需要在数据库里创建“dad” 组 然后名字为“news” 进入新闻页面 抓取标题,数据库中有就退出 没有就保存

Ivan-cn commented 3 years ago

疫情期间无聊研究的新闻标题抓取及判断

/**

  • @description: 新闻标题判断函数
  • @param: null
  • @return: null */

function nwpd(){ var news = className("android.view.View").depth(21).findOnce(1).desc()//获取新闻标题 var dbName = "tiku.db"; var path = files.path(dbName); var db = SQLiteDatabase.openOrCreateDatabase(path, null);//读取数据库三部 sql = "SELECT * FROM dad WHERE news = '" + news + "'" var cursor = db.rawQuery(sql, null);//用来执行select

if (cursor.moveToFirst()) {
    console.log("当前新闻看过了哦,即将退出");

    cursor.close();    
}
cursor.close();//关闭数据库

}

老版本的,新版本我还没下过,需要在数据库里创建“dad” 组 然后名字为“news” 进入新闻页面 抓取标题,数据库中有就退出 没有就保存

视频学习标题: if (textContains("展开").exists) { if (s == "央视网" || s =="中央广播电视总台"){ currentNewsTitle = textContains("展开").findOne().parent().parent().parent().children()[1].text(); //10.29测试,央视网/中央广播电视总台 视频标题 // console.log('视频名称1:'+currentNewsTitle); }

            if (s == "央视新闻") {
                currentNewsTitle = textContains("展开").findOne().parent().parent().parent().children()[2].text(); //10.29测试,央视新闻 视频标题
                //console.log('视频名称2:'+currentNewsTitle);
                let currentNewsTitle1=currentNewsTitle.substr(0,4);
                //console.log('视频名称2:'+currentNewsTitle1);
                if  (currentNewsTitle1=="央视新闻") {
                    currentNewsTitle = textContains("展开").findOne().parent().parent().parent().children()[1].text(); 
                   // console.log('视频名称2:'+currentNewsTitle);
                }
            } 
        } else {
            console.log("无法定位视频标题,即将退出并观看下一个")
            t++;
            back();
            delay(1);
            continue;        
        }
Ivan-cn commented 3 years ago

每日/每周答题卡住的bug,无法点击下一题或确定,修复function dailyQuestionLoop() 部分内容,以下为主要代码:

//按钮点击 var clickNextOk=false; if (text("下一题").exists()){ console.log('点击下一题'); clickNextOk=text("下一题").findOnce().click(); //console.log(clickNextOk); delay(0.5); } else if (text("确定").exists()) { console.log('点击确定'); clickNextOk=text("确定").findOnce().click(); //console.log(clickNextOk); delay(0.5); } else if (text("完成").exists()) { console.log('点击完成'); clickNextOk=text("完成").findOnce().click(); //console.log(clickNextOk); delay(0.5); }

if (!clickNextOk){ //按钮点击不成功,坐标点击 
    console.warn("未找到右上角确定按钮控件,根据坐标点击");
    click(device.width * 0.85, device.height * 0.06);//右上角确定按钮,根据自己手机实际修改
    delay(0.5);
}
Ivan-cn commented 3 years ago

更新了项目,除了在线题库没有,其他基本ok了。

maple0917 commented 3 years ago

更新了项目,除了在线题库没有,其他基本ok了。 手机MIUI 12,脚本2.8版本 大佬,试用了一下你的多账户版本,发现挺多BUG的 一,设置好账号和密码,无法自动登陆,需要手动输入密码 二,登陆状态下,会一直持续启动强国APP,第一次启动,然后切换到AUTO.JS,再切换回强国,然后就一直提示启动强国 只有一开始没有登陆状态的时候,然后提示输入密码,手动输入密码登陆之后才可以运行 三,运行的效率貌似没有原来的高,而且昨天我在运行脚本的时候,每周答题里有一道题答错了 四,运行到一半的时候,差不多文章看了5篇,不知为何又出错直接停了,错误原因我也忘了,我发现了就直接停了改回原来的脚本了,去看积分,文章只看了三篇。

最早使用2.7.1版本的时候,在NO.UI.JS里修改了账户密码,还是持续使用默认的12345678901用户,后来看到更新就又试了一下,发现可以使用修改过的用户了,但是还是发现了以上问题,希望大佬能改进一下,麻烦大佬了。

Ivan-cn commented 3 years ago

更新了项目,除了在线题库没有,其他基本ok了。 手机MIUI 12,脚本2.8版本 大佬,试用了一下你的多账户版本,发现挺多BUG的 一,设置好账号和密码,无法自动登陆,需要手动输入密码 二,登陆状态下,会一直持续启动强国APP,第一次启动,然后切换到AUTO.JS,再切换回强国,然后就一直提示启动强国 只有一开始没有登陆状态的时候,然后提示输入密码,手动输入密码登陆之后才可以运行 三,运行的效率貌似没有原来的高,而且昨天我在运行脚本的时候,每周答题里有一道题答错了 四,运行到一半的时候,差不多文章看了5篇,不知为何又出错直接停了,错误原因我也忘了,我发现了就直接停了改回原来的脚本了,去看积分,文章只看了三篇。

最早使用2.7.1版本的时候,在NO.UI.JS里修改了账户密码,还是持续使用默认的12345678901用户,后来看到更新就又试了一下,发现可以使用修改过的用户了,但是还是发现了以上问题,希望大佬能改进一下,麻烦大佬了。

账号密码是保存在config文件的,你看一下备份文件夹。答题逻辑应该没什么变化,但文章阅读改了,好像效率确实差了点,再改进吧。

Ivan-cn commented 3 years ago

function getAnswer(question, table_name) {//11.3取得时光在线题库的授权 if (table_name == "NET") {//网络搜题
let netTiku = "http://sg89.cn/api/tk1.php"; //在线题库 //let netziXingTi = "选择词语的正确词形        。"; //字形题网络原题,含空格+第一选项 let netziXingTi = "选择词语的正确词形%。"; //字形题网络原题,含空格+第一选项,改为通配% let netquestion = question.replace(ziXingTi, netziXingTi);//还原字形题的原题目(含空格)+第一个选项 //发送日志post try { let zxda = http.post(netTiku, {//在线答案 "t": "da", "q": netquestion }); //判断发送是否成功 // (zxda.statusCode = 200) {//post成功info let zxanswer = zxda.body.json(); if (zxanswer.code == -1) { //未找到答案 console.error("在线题库未找到答案"); return ''; } else {//找到答案 (0||1) let answer = zxanswer.as;//在线答案 //console.log("网络题目:"+netquestion);//调试用 console.info("题库题目:" + question);//调试用
console.log("------------------------"); //调试用
添加或更新本地题库答案 if (localTiku) { UpdateOrDeleteTK('up', question, answer);//添加或更新到本地题库 } return answer;//返回答案 } } catch (e) { console.log(e);//调试用 console.error("搜索在线题库出错,请检查!"); //toastLog("搜索在线题库出错,请检查"); return '';

    } else {//搜本地题库
    let dbName = "tiku.db";//题库文件名
    let path = files.path(dbName);
    let db = SQLiteDatabase.openOrCreateDatabase(path, null);
    let sql = "SELECT answer FROM " + table_name + " WHERE question LIKE '%" + question + "%'"// 关键词前后都加%,增加搜索准确率
    //log(sql)
    let cursor = db.rawQuery(sql, null);
    if (cursor.moveToFirst()) {
        let answer = cursor.getString(0);
        cursor.close();
        db.close();
        return answer;
    } else {
        console.error("本地题库中未找到答案");
        cursor.close();
        db.close();
        return '';
    }
}

}

nanmeng-sujin commented 3 years ago

function getAnswer(question, table_name) {//11.3取得时光在线题库的授权 if (table_name == "NET") {//网络搜题 let netTiku = "http://sg89.cn/api/tk1.php"; //在线题库 //let netziXingTi = "选择词语的正确词形        。"; //字形题网络原题,含空格+第一选项 let netziXingTi = "选择词语的正确词形%。"; //字形题网络原题,含空格+第一选项,改为通配% let netquestion = question.replace(ziXingTi, netziXingTi);//还原字形题的原题目(含空格)+第一个选项 //发送日志post try { let zxda = http.post(netTiku, {//在线答案 "t": "da", "q": netquestion }); //判断发送是否成功 // (zxda.statusCode = 200) {//post成功info let zxanswer = zxda.body.json(); if (zxanswer.code == -1) { //未找到答案 console.error("在线题库未找到答案"); return ''; } else {//找到答案 (0||1) let answer = zxanswer.as;//在线答案 //console.log("网络题目:"+netquestion);//调试用 console.info("题库题目:" + question);//调试用 console.log("------------------------"); //调试用 添加或更新本地题库答案 if (localTiku) { UpdateOrDeleteTK('up', question, answer);//添加或更新到本地题库 } return answer;//返回答案 } } catch (e) { console.log(e);//调试用 console.error("搜索在线题库出错,请检查!"); //toastLog("搜索在线题库出错,请检查"); return '';

  } else {//搜本地题库
    let dbName = "tiku.db";//题库文件名
    let path = files.path(dbName);
    let db = SQLiteDatabase.openOrCreateDatabase(path, null);
    let sql = "SELECT answer FROM " + table_name + " WHERE question LIKE '%" + question + "%'"// 关键词前后都加%,增加搜索准确率
    //log(sql)
    let cursor = db.rawQuery(sql, null);
    if (cursor.moveToFirst()) {
        let answer = cursor.getString(0);
        cursor.close();
        db.close();
        return answer;
    } else {
        console.error("本地题库中未找到答案");
        cursor.close();
        db.close();
        return '';
    }
}

} 大佬,你新的答题文件,第147行代码错误

nanmeng-sujin commented 3 years ago

function getAnswer(question, table_name) {//11.3取得时光在线题库的授权 if (table_name == "NET") {//网络搜题 let netTiku = "http://sg89.cn/api/tk1.php"; //在线题库 //let netziXingTi = "选择词语的正确词形        。"; //字形题网络原题,含空格+第一选项 let netziXingTi = "选择词语的正确词形%。"; //字形题网络原题,含空格+第一选项,改为通配% let netquestion = question.replace(ziXingTi, netziXingTi);//还原字形题的原题目(含空格)+第一个选项 //发送日志post try { let zxda = http.post(netTiku, {//在线答案 "t": "da", "q": netquestion }); //判断发送是否成功 // (zxda.statusCode = 200) {//post成功info let zxanswer = zxda.body.json(); if (zxanswer.code == -1) { //未找到答案 console.error("在线题库未找到答案"); return ''; } else {//找到答案 (0||1) let answer = zxanswer.as;//在线答案 //console.log("网络题目:"+netquestion);//调试用 console.info("题库题目:" + question);//调试用 console.log("------------------------"); //调试用 添加或更新本地题库答案 if (localTiku) { UpdateOrDeleteTK('up', question, answer);//添加或更新到本地题库 } return answer;//返回答案 } } catch (e) { console.log(e);//调试用 console.error("搜索在线题库出错,请检查!"); //toastLog("搜索在线题库出错,请检查"); return '';

  } else {//搜本地题库
    let dbName = "tiku.db";//题库文件名
    let path = files.path(dbName);
    let db = SQLiteDatabase.openOrCreateDatabase(path, null);
    let sql = "SELECT answer FROM " + table_name + " WHERE question LIKE '%" + question + "%'"// 关键词前后都加%,增加搜索准确率
    //log(sql)
    let cursor = db.rawQuery(sql, null);
    if (cursor.moveToFirst()) {
        let answer = cursor.getString(0);
        cursor.close();
        db.close();
        return answer;
    } else {
        console.error("本地题库中未找到答案");
        cursor.close();
        db.close();
        return '';
    }
}

}

由于新玩github不懂,就新弄了一个问题(转发了你发的那个),由于不知道怎么删除,非常抱歉

maple0917 commented 3 years ago

更新了项目,除了在线题库没有,其他基本ok了。 手机MIUI 12,脚本2.8版本 大佬,试用了一下你的多账户版本,发现挺多BUG的 一,设置好账号和密码,无法自动登陆,需要手动输入密码 二,登陆状态下,会一直持续启动强国APP,第一次启动,然后切换到AUTO.JS,再切换回强国,然后就一直提示启动强国 只有一开始没有登陆状态的时候,然后提示输入密码,手动输入密码登陆之后才可以运行 三,运行的效率貌似没有原来的高,而且昨天我在运行脚本的时候,每周答题里有一道题答错了 四,运行到一半的时候,差不多文章看了5篇,不知为何又出错直接停了,错误原因我也忘了,我发现了就直接停了改回原来的脚本了,去看积分,文章只看了三篇。

最早使用2.7.1版本的时候,在NO.UI.JS里修改了账户密码,还是持续使用默认的12345678901用户,后来看到更新就又试了一下,发现可以使用修改过的用户了,但是还是发现了以上问题,希望大佬能改进一下,麻烦大佬了。

账号密码是保存在config文件的,你看一下备份文件夹。答题逻辑应该没什么变化,但文章阅读改了,好像效率确实差了点,再改进吧。

大佬,再咨询一下,最新版的修改账户和密码之后,运行no-ui.js,会出现以下错误 syntax error (file:/storage/emulated/0/脚本/LazyStudy-onekey/!xxqg_v3.1.3(fixall).js#1309) syntax error at _load (file:///android_asset/modules/jvm-npm.js:60:0) at start_xx (/storage/emulated/0/脚本/LazyStudy-onekey/!NO_UI.js:190:0) at main (/storage/emulated/0/脚本/LazyStudy-onekey/!NO_UI.js:393:0) at /storage/emulated/0/脚本/LazyStudy-onekey/!NO_UI.js:475:0 请问这怎么解决啊? 运行ui.js,打开悬浮窗之后,点击一键学习,会提示正在启动进程,但是没有出现悬浮窗口,也不会启动学习强国app自动学习 另外,旧版的每周答题和专项答题是采用最新的答题,不知能否修改成回答旧的答题,不然专项答题一直回答最新的,有些旧的可能就会过期了

ghost commented 3 years ago

争上游和对战:可以尝试依靠结束答题后的温故知新环节来检查答案,正误能区分id控件,尚未测试是否容易提取题干和答案。 可以在UI中做选择选项是否执行。

针对字形题,可否创建一个包含所有正确答案的题库,判断哪一个选项包含在题库中,则点击该选项?

ghost commented 3 years ago

谢谢大家通力合作。 代码与xxqg_help,lazystudy可通用,哪位有时间做下合并? 建议,合并时更改下函数模块顺序。 可以考虑对时长做随机数,难度不大。 另外,哪位熟悉SQLlite数据库,对流行的几个题库做下去重合并?

小弟萌新,其他的不会,题库已经更新去重,且加上了最近更新的题目,经测试成功率大增,大佬测试下,亟待解决字形题,感谢大佬。附下载地址:https://wwa.lanzous.com/iAaM4i5qrsj

ghost commented 3 years ago

else{ if (ansTiku == "" && answer != "") { //正确进入下一题,且题库答案为空 var sql = "INSERT INTO tiku VALUES ('" + question + "','" + answer + "','')";//写库语句 insertOrUpdate(sql); console.log("更新题库答案..."); } if(ansTiku != "" && answer != ""){ var sql = "DELETE FROM tiku WHERE question LIKE '" + question + "'";//删库语句 insertOrUpdate(sql); console.log("删除题库答案!!!") } } 理论执行结果:碰上错题,X号答错来到更新题库函数,因不符合上面每日答题部分,来到else,之后应该看ansTiku题库搜索结果和answer答案获取结果:如果上面题库搜索为空,(随机点击正确)答案获取到,更新到题库;如果上面题库搜索不为空(表示有错误答案),<已经错误>,(随机点击无论正误都不影响)答案获取到,则说明题库错误,应该删除。 实际执行看log输出:答错,题库无答案,更新(到此正常),但紧接着又触发了删除语句。 另外,字形题题库有答案但错误,因为用的like question匹配删除,会清掉全部字形题目,所以需要前置if判断字形题不能执行删库/写库语句。之前的字形题在题库格式是 question 选项,answer ;现在看到的题库格式是question,answer,那么如何处理确保精确不误删?

我在在tiku.db中新加一个cixing表用于存放字形题(CREATE TABLE cixing (answer CHAR(4));),下载地址https://wwa.lanzous.com/iLgIVi6eqih answer中包含了目前知道的177个正确词形, 判断逻辑:如果题干中包含“选择词语的正确词形”则到cixing表中查找选项,使用select命令包含在题库中的返回1,否则返回null 请大佬们尝试一下,@zhuxuedefeng @Ivan-cn感谢!

Ivan-cn commented 3 years ago

else{ if (ansTiku == "" && answer != "") { //正确进入下一题,且题库答案为空 var sql = "INSERT INTO tiku VALUES ('" + question + "','" + answer + "','')";//写库语句 insertOrUpdate(sql); console.log("更新题库答案..."); } if(ansTiku != "" && answer != ""){ var sql = "DELETE FROM tiku WHERE question LIKE '" + question + "'";//删库语句 insertOrUpdate(sql); console.log("删除题库答案!!!") } } 理论执行结果:碰上错题,X号答错来到更新题库函数,因不符合上面每日答题部分,来到else,之后应该看ansTiku题库搜索结果和answer答案获取结果:如果上面题库搜索为空,(随机点击正确)答案获取到,更新到题库;如果上面题库搜索不为空(表示有错误答案),<已经错误>,(随机点击无论正误都不影响)答案获取到,则说明题库错误,应该删除。 实际执行看log输出:答错,题库无答案,更新(到此正常),但紧接着又触发了删除语句。 另外,字形题题库有答案但错误,因为用的like question匹配删除,会清掉全部字形题目,所以需要前置if判断字形题不能执行删库/写库语句。之前的字形题在题库格式是 question 选项,answer ;现在看到的题库格式是question,answer,那么如何处理确保精确不误删?

我在在tiku.db中新加一个cixing表用于存放字形题(CREATE TABLE cixing (answer CHAR(4));),下载地址https://wwa.lanzous.com/iLgIVi6eqih answer中包含了目前知道的177个正确词形, 判断逻辑:如果题干中包含“选择词语的正确词形”则到cixing表中查找选项,使用select命令包含在题库中的返回1,否则返回null 请大佬们尝试一下,@zhuxuedefeng @Ivan-cn感谢!

我是字形题的的本地题目是(原题目去掉空格+第一个选项)作为题库的question字段,网络题目也是+第一个选项(题目有空格和或空格为通配符)。目前在用无故障。

qq272285154 commented 3 years ago

萌新表示git困难, 还是一键的好 111!!!!!

jazk2004 commented 3 years ago

找到这个真不容易,谢谢各位的辛苦更新。

enoang commented 3 years ago

20201215 网盘链接https://wws.lanzous.com/b01npbw7a  密码:263a v2.19 20201212 推荐更新。 更新日志: 修正题库已知错题。 修改词形题与注音题答题逻辑,对应修改题库内格式。* 修正双人对战连续答题逻辑。 跟随强国APP升级电台收听逻辑。 修改题目输出日志与题库实际搜索一致。 加入运行日志输出功能,默认/脚本/AiQiangGuo日志.txt。

  • 词形与注音题格式为 题目去除空格,带句号,紧跟第一选项。示例如下: 选择词语的正确词形。一愁莫展

20201028 https://wws.lanzous.com/b01npbw7a 密码:263a 使用Ivan-cn处理挑战答题的逻辑:随机点击,如果正确,写入题库。 挑战答题支持自定义次数和题数,所以可以用来挂机刷题库。 增加争上游答题次数自定义,双人对战次数=争上游次数-1,因不容易判断答题错误,故该部分未加入随机点击正确写入题库功能。

20201017 https://wws.lanzous.com/iD9ouhihdxi 该版本加入挑战答题分享复活功能,完善部分争上游 对战答题逻辑。

20201016 https://wws.lanzous.com/iZVeahgrufa

0,源代码基于https://github.com/ivanwhaf/xxqg-helper V3.1.3 UI版本进行修改而来。 1,修改学习按钮点击方式,由基于文本"学习"(强国改版后为“工作”)改为基于控件"home_bottom_tab_button_work"点击。 2,积分执行加入循环判断,引入顺序执行(因测试部分手机积分获取时返回Null,获取不到积分)。 3,部分手机本地频道控件位置为13,故引入基于是否存在"切换地区"的判断。文章视频使用随机数(随机1 2 3文章点击推荐 要闻 综合,视频点击第一频道 学习视频 联播频道)。 3,执行逻辑为:文章 12篇_30秒(含前2篇文章分享点赞评论),视频 6个_60秒,本地频道,挑战答题 1轮*5题,每日答题(至领取奖励已达今日上限),之后循环检查 文章个数时长积分、视频个数积分,本地,挑战,每日答题 积分,不足则循环执行。以上足够之后,检查分享评论积分,不足则学习2篇文章执行分享点赞评论;检查视频时长,不足则收听广播补时长(注意广播不会自动退出,但不影响接下来执行);检查双人对战积分,<1执行一次双人对战;检查争上游答题积分,<2执行两次争上游答题。 4,双人对战和争上游答题为基于延时执行,不算很准确,重在参与(参与分1+2)。提取的题目(已去除题目号1. 2.)在题库中搜索不到答案。争上游两轮结束判断偶尔出错导致执行报错,故放在最后执行。这两项可以提前手动答题,均为单选题也可执行中辅助点击。 5,计划加入:挑战答题不足1轮5题 失败时的分享复活。 6,存在问题:文章 视频重复点击;文章有概率点击到广播,然后不能自动执行,需手动返回学习主页(执行逻辑将文章优先执行后已降低此问题概率)。

@lolisaikou 将已点击文章标题写入数据库避免重复点击,解决思路很棒。挑战答题的结束判断部分,提取不到题目弹出提示而不是报错。 在线题库更新,@ivanwhaf xxqg-helper原链接已挂掉。

感谢大佬分享

silent0910 commented 3 years ago

大佬,1225,争上游和双人对战不能用了

sephiroth945 commented 3 years ago

界面改版了,去掉了答题结束的计时,所以原来的判断 if (textContains('距离答题结束').exists() && !text('继续挑战').exists()) { 为false,无法进入判断内的函数

elceric commented 3 years ago

感谢大神更新,大家可以去大神分享的下载页面下载