Closed zhuxuedefeng closed 3 years ago
多谢分享!
是对懒人学习的改进吗,带佬,可以多少分一共
老哥可以也弄个github仓库吗,这样就能关注您更新了
是对懒人学习的改进吗,带佬,可以多少分一共
您好,是对学习强国助手,@ivanwhaf xxqg_helper v3.1.3 ui的改进版。懒人学习的主流程模块,是其无ui版本的改进。 正常执行完毕,42分,登陆1,文章12,评论分享1+1,视频6+6,本地1,挑战6,每日5,争上游2,双人1(争上游和双人只保证流程正确,不保速度和答题,参与分。可以提前手工做,也可以流程中2秒左右机会手工介入辅助点击)
老哥可以也弄个github仓库吗,这样就能关注您更新了
刚建号的萌新,不熟悉github……这个严格来说,是xxqg_helper 3.1.3 ui版本的迭代演进分支,所以应该加入那边仓库。
是对懒人学习的改进吗,带佬,可以多少分一共
之前使用电脑端 PandaLearning(项目已改名AutoXuexi,迭代也已经40多分了),8月多入坑安卓端autojs,也有基于lazystudy迭代改进,只是后来感觉独立ui版本更方便,毕竟是单文件内修改,跳转 引用函数 定义参数更方便。 两者主要函数模块互通,执行逻辑相同。 当然,因独立改进,和现在@lolisaikou lazystudy中xxqg_helper已经有了分支区别,喜欢的朋友可以研究一下,互相改进。 比如,lazystudy中把文章标题写入数据库来避免重复点击的解决方案; 挑战答题执行完毕虽然不能退出,但也不会报错,可以应用到我这个里面争上游和双人对战的结束判断(这两项答题结束换题和结束标志很难捕捉,结果结束了,函数还在执行,提取不到题目报错)。 我这里面,答题流程应该比lazystudy友好,支持主流程内自动答题,单独答题支持自动拉起学习强国app。
另外,ui版本适合做测试: 文章数量 时长,视频数量 时长,挑战 轮数 数量,可自定义。做了独立答题入口。 实测发现部分手机不能返回积分(积分获取返回null),设置顺序执行,使用内置数目时长执行。 另外,部分华为机型,执行外置题库文件路径命令报错(判断题库文件是否存在时直接报错),计划改进不使用外置题库的随机点击版(反正现在做的都是每天几乎不限次数的)
以下为演进方向: 1,挑战答题,不足1轮5题答错时分享复活 2,文章向@lolisaikou学习,引入其数据库,避免重复 3,在线题库更新,更换源 4,机型适配,华为部分机型无法使用题库,去题库,答题随机点击(尚需测试只是题库存在与否判断有问题还是确实不能使用外置文件) 5,在线更新,版本判断。
6,当前每日答题题库无答案,根据提示获取答案,无论对错均写入题库(实际有些提示和题目对不上,结果提示获取到的不一定是正确答案)。计划改进为,依据答对标志,答对写入题库。另外,对题库无答案,随机点击的挑战答题和争上游/对战判断答题正确标志,正确写入题库。
老哥,可以弄个tg电报群或者qq群反馈交流吗
这样修改之后可以正常获取answer,但是只有answer from char才能正常点击,不然全都是点击失败跳转随机点击,楼主试试看能否实现正常点击答案。
function zsyQuestionLoop() {
delay(5);
if (textContains("继续挑战").exists()){//不存在本局结束标志 继续挑战,则执行
console.info("答题结束!");
return;
} else {
if (className("RadioButton").exists() || aquestion.length == 0) {
delay(0.5);
var aquestion = className("ListView").findOnce().parent().child(0).text();
var question = aquestion.substring(3);
}else {
console.error("提取题目失败!");
let listArray = className("ListView").findOnce().children();//题目选项列表
let i = random(0, listArray.length - 1);
console.log("随机点击");
listArray[i].child(0).click();//随意点击一个答案
return;
}
var chutiIndex = question.lastIndexOf("出题单位");
if (chutiIndex != -1) {
question = question.substring(0, chutiIndex - 2);
}
question = question.replace(/\s/g, "");
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;
}
console.log(aquestion.substring(0,2) + "题目:" + question);
var answer = getAnswer(question, 'tiku');
if (answer.length == 0) {//tiku表中没有则到tikuNet表中搜索答案
answer = getAnswer(question, 'tikuNet');
}
console.info("答案:" + answer);
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 == "")//如果没找到答案
{
let i = random(0, listArray.length - 1);
console.error("没有找到答案,随机点击");
listArray[i].child(0).click();//随意点击一个答案
hasClicked = true;
console.log("---------------------------");
}
else//如果找到了答案
{
listArray.forEach(item => {
var listDescStr = item.child(0).child(1).text();
if (listDescStr == 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("---------------------------");
}
} }
这样修改之后可以正常获取answer,但是只有answer from char才能正常点击,不然全都是点击失败跳转随机点击,楼主试试看能否实现正常点击答案。 function zsyQuestionLoop() { delay(5); if (textContains("继续挑战").exists()){//不存在本局结束标志 继续挑战,则执行 console.info("答题结束!"); return; } else { if (className("RadioButton").exists() || aquestion.length == 0) { delay(0.5); var aquestion = className("ListView").findOnce().parent().child(0).text(); var question = aquestion.substring(3); }else { console.error("提取题目失败!"); let listArray = className("ListView").findOnce().children();//题目选项列表 let i = random(0, listArray.length - 1); console.log("随机点击"); listArray[i].child(0).click();//随意点击一个答案 return; }
var chutiIndex = question.lastIndexOf("出题单位"); if (chutiIndex != -1) { question = question.substring(0, chutiIndex - 2); } question = question.replace(/\s/g, ""); 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; } console.log(aquestion.substring(0,2) + "题目:" + question); var answer = getAnswer(question, 'tiku'); if (answer.length == 0) {//tiku表中没有则到tikuNet表中搜索答案 answer = getAnswer(question, 'tikuNet'); } console.info("答案:" + answer); 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 == "")//如果没找到答案 { let i = random(0, listArray.length - 1); console.error("没有找到答案,随机点击"); listArray[i].child(0).click();//随意点击一个答案 hasClicked = true; console.log("---------------------------"); } else//如果找到了答案 { listArray.forEach(item => { var listDescStr = item.child(0).child(1).text(); if (listDescStr == 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("---------------------------"); }
} }
谢谢反馈,下午试下。争上游答题循环我是照抄的挑战答题循环,然后做的延时,只能大概匹配。争上游和挑战的最大区别是,争上游有1. 2. 3.……这样的题目序号需要去除。
className("RadioButton").exists() || aquestion.length == 0),这应该用while,用if在失败或成功跳出后aquestion就报错了, 争上游结束后多了一个返回,
className("RadioButton").exists() || aquestion.length == 0),这应该用while,用if在失败或成功跳出后aquestion就报错了, 争上游结束后多了一个返回,
谢谢,稍等修改测试。确实有此问题,之前解决方案是加长延时,if判断结束后标志。
className("RadioButton").exists() || aquestion.length == 0),这应该用while,用if在失败或成功跳出后aquestion就报错了, 争上游结束后多了一个返回,
谢谢,稍等修改测试。确实有此问题,之前解决方案是加长延时,if判断结束后标志。
老哥弄个群如何,方便大家反馈交流进步
7,仔细想想,好像@lolisaikou LazyStudy的文章写入数据库也不能从根本上避免重复点击,只能是检测到重复点击---退出再搜索下一篇,要从根本上避免重复点击,识别文字颜色(已读文章标题为深灰色,未读文章标题为正常黑色)来区分更能避免重复点击问题。 识别文字颜色还可以应用到挑战/争上游/对战 随机点击提取正确答案写入题库,这才是有效的更新题库方式~~~
确认@KB64ba同学建议可行 while(!className("RadioButton").exists()); if (className("RadioButton").exists() || aquestion.length == 0) { 加入该段代码后,延时已经可以由5s减至4s(测试3.5s会 徐特立>>徐特立这个得算是xxqg助手的一个梗了,数据库带空格的第一条answer是徐特立,然后question带空搜索数据库返回就是徐特立) 确认@chongyadong同学建议正确,部分题目能获取到答案 此修改了部分带出题单位的题目获取方式,然后可以返回答案。所以推测,前面获取到的题目确实是有问题的,导致搜索题库无答案。 可以确认answer from char点击正常,研究下两者点击逻辑。猜测答案布局和挑战答题也有区别。(争上游 对战答题循环整个复制的挑战答题循环)
确认@KB64ba同学建议可行 while(!className("RadioButton").exists()); if (className("RadioButton").exists() || aquestion.length == 0) { 加入该段代码后,延时已经可以由5s减至4s(测试3.5s会 徐特立>>徐特立这个得算是xxqg助手的一个梗了,数据库带空格的第一条answer是徐特立,然后question带空搜索数据库返回就是徐特立) 确认@chongyadong同学建议正确,部分题目能获取到答案 此修改了部分带出题单位的题目获取方式,然后可以返回答案。所以推测,前面获取到的题目确实是有问题的,导致搜索题库无答案。 可以确认answer from char点击正常,研究下两者点击逻辑。猜测答案布局和挑战答题也有区别。(争上游 对战答题循环整个复制的挑战答题循环)
争上游答题和双人对战能搜索到题库了,就是正确答案和实际点击的答案不符(提示:未能点击成功,随机点击一个),请各位辛苦研究下,看能不能解决这个问题,感谢!
确认@KB64ba同学建议可行 while(!className("RadioButton").exists()); if (className("RadioButton").exists() || aquestion.length == 0) { 加入该段代码后,延时已经可以由5s减至4s(测试3.5s会 徐特立>>徐特立这个得算是xxqg助手的一个梗了,数据库带空格的第一条answer是徐特立,然后question带空搜索数据库返回就是徐特立) 确认@chongyadong同学建议正确,部分题目能获取到答案 此修改了部分带出题单位的题目获取方式,然后可以返回答案。所以推测,前面获取到的题目确实是有问题的,导致搜索题库无答案。 可以确认answer from char点击正常,研究下两者点击逻辑。猜测答案布局和挑战答题也有区别。(争上游 对战答题循环整个复制的挑战答题循环)
争上游答题和双人对战能搜索到题库了,就是正确答案和实际点击的答案不符(提示:未能点击成功,随机点击一个),请各位辛苦研究下,看能不能解决这个问题,感谢!
放代码看下,按照@chongyadong同学修改的,answer from char点击正常;带出题单位的题目可以正常搜索,不能点击;其他题目依然不能搜索。
搜索不到的,可能是本地题库里没有!
哪位同学用auto.js分析下挑战答题备选答案列表和争上游/对战备选答案列表区别?目前得到答案无法点击应该是两者列表问题引起。
if (answer == "")//如果没找到答案 { let i = random(0, listArray.length - 1); console.error("没有找到答案,随机点击"); listArray[i].child(0).click();//随意点击一个答案 hasClicked = true; console.log("---------------------------"); } else//如果找到了答案 { listArray.forEach(item => { var listDescStr = item.child(0).child(1).text(); if (listDescStr == 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("---------------------------"); }
无法点击原因:挑战没有A. B. C. D.,争上游和对战有,题库返回答案依据挑战格式来,判断if (listDescStr == answer)肯定不成立,所以无法点击。 一个解决方案:参考前面题目提取去掉1.2.3.那样,listDescStr使用substring(3)去掉A. B. C. D.再判断 已测试可行,但answer from char获取到的answer是带A.B.的,故需加入判断,初步计划使用substring(0,2)取answer前两个字,如果带A.||B.||C.||D.则使用原if判断。 另一个解决方案:使用文本包含判断。
/**不能点击问题已解决,请查看点击判断部分
/**计划功能更新,挑战答题不足5题分享复活已完成,说明见下方
@zhuxuedefeng 感谢你抽空优化完善,辛苦你了!
20201017 https://wws.lanzous.com/iD9ouhihdxi 该版本加入挑战答题分享复活功能,完善部分争上游 对战答题逻辑。
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原链接已挂掉。
感谢膜拜大神,建议每一篇文章和视频的时长不要相同,设一个随机数,这样更逼真
谢谢大家通力合作。代码与xxqg_help,lazystudy可通用,哪位有时间做下合并?建议,合并时更改下函数模块顺序。 可以考虑对时长做随机数,难度不大。 另外,哪位熟悉SQLlite数据库,对流行的几个题库做下去重合并?
楼主费心了!亲测对战循环可用! 关于文章学习,我修改了另一位大神的代码,可以实现在点击之前根据“播报”按钮判断是否为文章,从而避免进入视频页面,但是需要打开Auto.js稳定模式运行,不然会无限翻页,仅供参考。 function articleStudy() { while (!desc("工作").exists()); //等待加载出主页 desc("工作").click(); //点击主页正下方的"学习"按钮 delay(2); var listView = className("ListView"); //获取文章ListView控件用于翻页 click(aCatlog); delay(2); var currentNewsTitle = ""; var fail = 0; //点击失败次数 var date_string = getTodayDateString(); //获取当天日期字符串
for (var i = 0, t = 0; i < aCount;) {
var art_obj = text(date_string).findOnce(t);
//console.info(art_obj);
if ((art_obj != null) && (art_obj.parent().childCount() == 4)) {
t++; //t为实际查找的文章控件在当前布局中的标号,和i不同,勿改动!
if ((art_obj.parent().child(3).text() == "播报") && (art_obj.parent().child(0).text() != currentNewsTitle)) //如果播报存在就进入文章正文
{
currentNewsTitle = art_obj.parent().child(0).text();
log(currentNewsTitle);
art_obj.parent().click();
delay(1);
console.log("正在学习第" + (i + 1) + "篇文章...");
fail = 0; //失败次数清0
article_timing(i, aTime);
if (i < 2)//收藏分享2篇文章
{
CollectAndShare(i);//收藏+分享 若c运行到此报错请注释本行!
Comment(i);//评论
}
back(); //返回主界面
while (!desc("工作").exists()); //等待加载出主页
delay(1);
i++;
} else { //判断非目标文章
if (t > 2) {
listView.scrollForward(); //向下滑动(翻页
log("……翻页……");
t = 0;
delay(1.5);
}
}
} else {
if (fail > 1) //连续翻几页没有点击成功则认为今天的新闻还没出来,学习昨天的
{
date_string = getYestardayDateString();
fail = 0;
console.warn("没有找到当天文章,即将学习昨日新闻!");
continue;
}
if (!textContains(date_string).exists()) //当前页面当天新闻
{
fail++; //失败次数加一
}
listView.scrollForward(); //向下滑动(翻页
log("……翻页……");
t = 0;
delay(1.5);
}
}
}
谢谢大家通力合作。代码与xxqg_help,lazystudy可通用,哪位有时间做下合并?建议,合并时更改下函数模块顺序。 可以考虑对时长做随机数,难度不大。 另外,哪位熟悉SQLlite数据库,对流行的几个题库做下去重合并?
https://lei999.lanzoui.com/b00zvulib 大佬能帮我合并下新的UI和悬浮窗吗,我这个点击按钮就卡死了…… 能力有限啊!!! 里面有各位大佬的分享,再次感谢各位大佬!!! qg.txt放在根目录,格式:账号-密码-姓名(提示用)
有那位大佬提供下非界面清空APP缓存,和检查非APP界面再次打开APP!这样可以避免部分错误
谢谢大家通力合作。代码与xxqg_help,lazystudy可通用,哪位有时间做下合并?建议,合并时更改下函数模块顺序。 可以考虑对时长做随机数,难度不大。 另外,哪位熟悉SQLlite数据库,对流行的几个题库做下去重合并?
https://lei999.lanzoui.com/b00zvulib 大佬能帮我合并下新的UI和悬浮窗吗,我这个点击按钮就卡死了…… 能力有限啊!!! 里面有各位大佬的分享,再次感谢各位大佬!!! qg.txt放在根目录,格式:账号-密码-姓名(提示用)
有那位大佬提供下非界面清空APP缓存,和检查非APP界面再次打开APP!这样可以避免部分错误
莫非,这是要多个账号连续挂机?
楼主费心了!亲测对战循环可用! 关于文章学习,我修改了另一位大神的代码,可以实现在点击之前根据“播报”按钮判断是否为文章,从而避免进入视频页面,但是需要打开Auto.js稳定模式运行,不然会无限翻页,仅供参考。 function articleStudy() { while (!desc("工作").exists()); //等待加载出主页 desc("工作").click(); //点击主页正下方的"学习"按钮 delay(2); var listView = className("ListView"); //获取文章ListView控件用于翻页 click(aCatlog); delay(2); var currentNewsTitle = ""; var fail = 0; //点击失败次数 var date_string = getTodayDateString(); //获取当天日期字符串
for (var i = 0, t = 0; i < aCount;) { var art_obj = text(date_string).findOnce(t); //console.info(art_obj); if ((art_obj != null) && (art_obj.parent().childCount() == 4)) { t++; //t为实际查找的文章控件在当前布局中的标号,和i不同,勿改动! if ((art_obj.parent().child(3).text() == "播报") && (art_obj.parent().child(0).text() != currentNewsTitle)) //如果播报存在就进入文章正文 { currentNewsTitle = art_obj.parent().child(0).text(); log(currentNewsTitle); art_obj.parent().click(); delay(1); console.log("正在学习第" + (i + 1) + "篇文章..."); fail = 0; //失败次数清0 article_timing(i, aTime); if (i < 2)//收藏分享2篇文章 { CollectAndShare(i);//收藏+分享 若c运行到此报错请注释本行! Comment(i);//评论 } back(); //返回主界面 while (!desc("工作").exists()); //等待加载出主页 delay(1); i++; } else { //判断非目标文章 if (t > 2) { listView.scrollForward(); //向下滑动(翻页 log("……翻页……"); t = 0; delay(1.5); } } } else { if (fail > 1) //连续翻几页没有点击成功则认为今天的新闻还没出来,学习昨天的 { date_string = getYestardayDateString(); fail = 0; console.warn("没有找到当天文章,即将学习昨日新闻!"); continue; } if (!textContains(date_string).exists()) //当前页面当天新闻 { fail++; //失败次数加一 } listView.scrollForward(); //向下滑动(翻页 log("……翻页……");
回头测试下。理论可行,播报按钮是文章专属标志。
楼主费心了!亲测对战循环可用! 关于文章学习,我修改了另一位大神的代码,可以实现在点击之前根据“播报”按钮判断是否为文章,从而避免进入视频页面,但是需要打开Auto.js稳定模式运行,不然会无限翻页,仅供参考。 function articleStudy() { while (!desc("工作").exists()); //等待加载出主页 desc("工作").click(); //点击主页正下方的"学习"按钮 delay(2); var listView = className("ListView"); //获取文章ListView控件用于翻页 click(aCatlog); delay(2); var currentNewsTitle = ""; var fail = 0; //点击失败次数 var date_string = getTodayDateString(); //获取当天日期字符串
for (var i = 0, t = 0; i < aCount;) { var art_obj = text(date_string).findOnce(t); //console.info(art_obj); if ((art_obj != null) && (art_obj.parent().childCount() == 4)) { t++; //t为实际查找的文章控件在当前布局中的标号,和i不同,勿改动! if ((art_obj.parent().child(3).text() == "播报") && (art_obj.parent().child(0).text() != currentNewsTitle)) //如果播报存在就进入文章正文 { currentNewsTitle = art_obj.parent().child(0).text(); log(currentNewsTitle); art_obj.parent().click(); delay(1); console.log("正在学习第" + (i + 1) + "篇文章..."); fail = 0; //失败次数清0 article_timing(i, aTime); if (i < 2)//收藏分享2篇文章 { CollectAndShare(i);//收藏+分享 若c运行到此报错请注释本行! Comment(i);//评论 } back(); //返回主界面 while (!desc("工作").exists()); //等待加载出主页 delay(1); i++; } else { //判断非目标文章 if (t > 2) { listView.scrollForward(); //向下滑动(翻页 log("……翻页……"); t = 0; delay(1.5); } } } else { if (fail > 1) //连续翻几页没有点击成功则认为今天的新闻还没出来,学习昨天的 { date_string = getYestardayDateString(); fail = 0; console.warn("没有找到当天文章,即将学习昨日新闻!"); continue; } if (!textContains(date_string).exists()) //当前页面当天新闻 { fail++; //失败次数加一 } listView.scrollForward(); //向下滑动(翻页 log("……翻页……");
回头测试下。理论可行,播报按钮是文章专属标志。
你这个还是以时间为基准,新闻或文章可能没有当天的,
延时4秒太长了,我修改了一下为1秒搜题,主要是用个全局oldquestion和question对比,两者不同以及在question不为空值时(为空值时,答案为徐特立,题库第一行?)返回question值,但在搜aquestion时先判断是否已存在"继续挑战"(防止最后一题出错)。剩下的就是题库了的问题了。
楼主费心了!亲测对战循环可用! 关于文章学习,我修改了另一位大神的代码,可以实现在点击之前根据“播报”按钮判断是否为文章,从而避免进入视频页面,但是需要打开Auto.js稳定模式运行,不然会无限翻页,仅供参考。 function articleStudy() { while (!desc("工作").exists()); //等待加载出主页 desc("工作").click(); //点击主页正下方的"学习"按钮 delay(2); var listView = className("ListView"); //获取文章ListView控件用于翻页 click(aCatlog); delay(2); var currentNewsTitle = ""; var fail = 0; //点击失败次数 var date_string = getTodayDateString(); //获取当天日期字符串
for (var i = 0, t = 0; i < aCount;) { var art_obj = text(date_string).findOnce(t); //console.info(art_obj); if ((art_obj != null) && (art_obj.parent().childCount() == 4)) { t++; //t为实际查找的文章控件在当前布局中的标号,和i不同,勿改动! if ((art_obj.parent().child(3).text() == "播报") && (art_obj.parent().child(0).text() != currentNewsTitle)) //如果播报存在就进入文章正文 { currentNewsTitle = art_obj.parent().child(0).text(); log(currentNewsTitle); art_obj.parent().click(); delay(1); console.log("正在学习第" + (i + 1) + "篇文章..."); fail = 0; //失败次数清0 article_timing(i, aTime); if (i < 2)//收藏分享2篇文章 { CollectAndShare(i);//收藏+分享 若c运行到此报错请注释本行! Comment(i);//评论 } back(); //返回主界面 while (!desc("工作").exists()); //等待加载出主页 delay(1); i++; } else { //判断非目标文章 if (t > 2) { listView.scrollForward(); //向下滑动(翻页 log("……翻页……"); t = 0; delay(1.5); } } } else { if (fail > 1) //连续翻几页没有点击成功则认为今天的新闻还没出来,学习昨天的 { date_string = getYestardayDateString(); fail = 0; console.warn("没有找到当天文章,即将学习昨日新闻!"); continue; } if (!textContains(date_string).exists()) //当前页面当天新闻 { fail++; //失败次数加一 } listView.scrollForward(); //向下滑动(翻页 log("……翻页……");
回头测试下。理论可行,播报按钮是文章专属标志。
你这个还是以时间为基准,新闻或文章可能没有当天的,
我用的随机数,找前几天的。 目前最大的问题,重复点击。半夜挂机,早上还在刷那几篇(通常倒是剩下也不多,一篇文章一个视频,手工介入,进一下没点过的就行)。即使引入lolisaikou的标题写入数据库处理方法,估计也是点击文章,获取标题,对比数据库,已有,退出 的循环。
无论是基于日期还是基于发布平台来点击,终究有限。哪位试试,能不能打开时就获取文章列表,然后再点击。 处理逻辑,如果基于数据库: 获取当前显示标题 日期 发布平台列表,与已读数据库比对,已读舍弃,未读,计入未读数据库,然后依次点击未读标题,计入已读数据库,当前显示的未读全部完成,随机滑动,再次循环。滑动数次都是已读的,换频道,再循环。
谢谢大家通力合作。代码与xxqg_help,lazystudy可通用,哪位有时间做下合并?建议,合并时更改下函数模块顺序。 可以考虑对时长做随机数,难度不大。 另外,哪位熟悉SQLlite数据库,对流行的几个题库做下去重合并?
https://lei999.lanzoui.com/b00zvulib 大佬能帮我合并下新的UI和悬浮窗吗,我这个点击按钮就卡死了…… 能力有限啊!!! 里面有各位大佬的分享,再次感谢各位大佬!!! qg.txt放在根目录,格式:账号-密码-姓名(提示用)
有那位大佬提供下非界面清空APP缓存,和检查非APP界面再次打开APP!这样可以避免部分错误
我写了个多账号切换,现在每天定时使用,迟点放上来分享,我也合并了题库,主要是没有去重。。。
延时4秒太长了,我修改了一下为1秒搜题,主要是用个全局oldquestion和question对比,两者不同以及在question不为空值时(为空值时,答案为徐特立,题库第一行?)返回question值,但在搜aquestion时先判断是否已存在"继续挑战"(防止最后一题出错)。剩下的就是题库了的问题了。
可以分享一下修改后的代码吗?
谢谢大家通力合作。代码与xxqg_help,lazystudy可通用,哪位有时间做下合并?建议,合并时更改下函数模块顺序。 可以考虑对时长做随机数,难度不大。 另外,哪位熟悉SQLlite数据库,对流行的几个题库做下去重合并?
https://lei999.lanzoui.com/b00zvulib 大佬能帮我合并下新的UI和悬浮窗吗,我这个点击按钮就卡死了…… 能力有限啊!!! 里面有各位大佬的分享,再次感谢各位大佬!!! qg.txt放在根目录,格式:账号-密码-姓名(提示用) 有那位大佬提供下非界面清空APP缓存,和检查非APP界面再次打开APP!这样可以避免部分错误
我写了个多账号切换,现在每天定时使用,迟点放上来分享,我也合并了题库,主要是没有去重。。。
我也是借鉴你的多账号,但是如果给朋友用的不合适,毕竟不是每个人都能改代码,
var file=open("/sdcard/qg.txt") var ub=file.readlines(); ub.length for(var zh=0; zh<ub.length;zh++){ var str=ub[zh] var arr=str.split("-") //log("账号"+arr[0]) //log("密码"+arr[1]) //log("姓名:"+arr[2]) user=arr[0] passward=arr[1] log("开始登录第"+(zh+1)+"个帐号★"+(arr[2])
这个接你的代码可以用,账号密码单独文档存放可以打包
楼主费心了!亲测对战循环可用! 关于文章学习,我修改了另一位大神的代码,可以实现在点击之前根据“播报”按钮判断是否为文章,从而避免进入视频页面,但是需要打开Auto.js稳定模式运行,不然会无限翻页,仅供参考。 function articleStudy() { while (!desc("工作").exists()); //等待加载出主页 desc("工作").click(); //点击主页正下方的"学习"按钮 delay(2); var listView = className("ListView"); //获取文章ListView控件用于翻页 click(aCatlog); delay(2); var currentNewsTitle = ""; var fail = 0; //点击失败次数 var date_string = getTodayDateString(); //获取当天日期字符串
for (var i = 0, t = 0; i < aCount;) { var art_obj = text(date_string).findOnce(t); //console.info(art_obj); if ((art_obj != null) && (art_obj.parent().childCount() == 4)) { t++; //t为实际查找的文章控件在当前布局中的标号,和i不同,勿改动! if ((art_obj.parent().child(3).text() == "播报") && (art_obj.parent().child(0).text() != currentNewsTitle)) //如果播报存在就进入文章正文 { currentNewsTitle = art_obj.parent().child(0).text(); log(currentNewsTitle); art_obj.parent().click(); delay(1); console.log("正在学习第" + (i + 1) + "篇文章..."); fail = 0; //失败次数清0 article_timing(i, aTime); if (i < 2)//收藏分享2篇文章 { CollectAndShare(i);//收藏+分享 若c运行到此报错请注释本行! Comment(i);//评论 } back(); //返回主界面 while (!desc("工作").exists()); //等待加载出主页 delay(1); i++; } else { //判断非目标文章 if (t > 2) { listView.scrollForward(); //向下滑动(翻页 log("……翻页……"); t = 0; delay(1.5); } } } else { if (fail > 1) //连续翻几页没有点击成功则认为今天的新闻还没出来,学习昨天的 { date_string = getYestardayDateString(); fail = 0; console.warn("没有找到当天文章,即将学习昨日新闻!"); continue; } if (!textContains(date_string).exists()) //当前页面当天新闻 { fail++; //失败次数加一 } listView.scrollForward(); //向下滑动(翻页 log("……翻页……");
回头测试下。理论可行,播报按钮是文章专属标志。
你这个还是以时间为基准,新闻或文章可能没有当天的,
时间的话,我用着不算大问题,如果是早晨运行,会翻页3-4次,找不到当天的就切换到昨天的文章学习。
工作日上午下午晚上用,那倒是基本运行正常,毕竟发布的新内容多。夜猫子半夜0点后挂机,那就不友好了,得刷会。
谢谢大家通力合作。代码与xxqg_help,lazystudy可通用,哪位有时间做下合并?建议,合并时更改下函数模块顺序。 可以考虑对时长做随机数,难度不大。 另外,哪位熟悉SQLlite数据库,对流行的几个题库做下去重合并?
https://lei999.lanzoui.com/b00zvulib 大佬能帮我合并下新的UI和悬浮窗吗,我这个点击按钮就卡死了…… 能力有限啊!!! 里面有各位大佬的分享,再次感谢各位大佬!!! qg.txt放在根目录,格式:账号-密码-姓名(提示用) 有那位大佬提供下非界面清空APP缓存,和检查非APP界面再次打开APP!这样可以避免部分错误
我写了个多账号切换,现在每天定时使用,迟点放上来分享,我也合并了题库,主要是没有去重。。。
我也是借鉴你的多账号,但是如果给朋友用的不合适,毕竟不是每个人都能改代码,
var file=open("/sdcard/qg.txt") var ub=file.readlines(); ub.length for(var zh=0; zh<ub.length;zh++){ var str=ub[zh] var arr=str.split("-") //log("账号"+arr[0]) //log("密码"+arr[1]) //log("姓名:"+arr[2]) user=arr[0] passward=arr[1] log("开始登录第"+(zh+1)+"个帐号★"+(arr[2])
这个接你的代码可以用,账号密码单独文档存放可以打包
我现在的也是放在配置文件了,帐号密码以及微信推送的key码、是否打开浮动菜单等。
争上游和对战,测试使用与或非判断答题和循环入口,再调整顺序,更有效 答题入口修改: 先判断结束标志,再做答题循环。 while (true) { if (className("android.view.View").text("继续挑战").exists() || textContains("继续挑战").exists())//使用或逻辑,遇到继续挑战,则本局结束 {console.info("争上游答题本局结束!");
if (textContains("距离答题结束").exists() && !text("继续挑战").exists()){//使用与 非逻辑 判断做题
zsyQuestionLoop();
}
答题循环部分,先做题,再延时。
if (className("android.view.View").text("继续挑战").exists() || textContains("继续挑战").exists() || !textContains("距离答题结束").exists()){//不存在本局结束标志 继续挑战,则执行
console.info("答题结束!");
return;
delay(4);
详细代码稍等。手机不能整段复制。
//基于“播报”按钮修改文章学习部分 /**
@return: null / function articleStudy0() { while (!id("home_bottom_tab_button_work").exists());//等待加载出主页 id("home_bottom_tab_button_work").findOne().click();//点击主页正下方的"学习"按钮 delay(2); var aCatlog = aCat[num] ;//文章学习类别,随机取"推荐""要闻"、"新思想" var date_string = getTodayDateString();//获取当天日期字符串 var s = date_string; var listView = className("ListView");//获取文章ListView控件用于翻页 click(aCatlog); delay(2); var zt_flag = false;//判断进入专题界面标志 var fail = 0;//点击失败次数 console.log('文章类别:' + aCatlog + '关键词:'+ s) for (var i = 0, t = 0; i < aCount;) { if (click(s, t) == true)//如果点击成功则进入文章页面,不成功意味着本页已经到底,要翻页 { let n = 0; while (!textContains("欢迎发表你的观点").exists())//如果没有找到评论框则认为没有进入文章界面,一直等待 { delay(1); console.warn("正在等待加载文章界面..."); if (n > 3)//等待超过3秒则认为进入了专题界面,退出进下一篇文章 { console.warn("没找到评论框!该界面非文章界面!"); zt_flag = true; break; } n++; } if (textContains("央视网").exists() || textContains("广播").exists() || textContains("中央广播电视总台").exists() ||textContains("播放").exists() ||textContains("展开").exists() )//如果存在“央视网、中央广播电视总台、播放、展开”则认为进入了视频需退出。关键词测试 { console.warn("进入视频界面,退出并进下一篇文章!"); t++; back(); / while (!id("home_bottom_tab_button_work").exists()); delay(0.5); click("电台"); delay(1); click("最近收听"); console.log("因广播被打断,重新收听广播..."); delay(1); back();*/ while (!id("home_bottom_tab_button_work").exists()); id("home_bottom_tab_button_work").findOne().click(); delay(1); num = random(0, commentText.length - 1) ; //重取随机数 aCatlog = aCat[num] ; s = "“学习强国”学习平台"; console.log('文章类别:' + aCatlog + '关键词:'+ s) click(aCatlog); delay(1); continue; }
if (id("v_play").exists() || id("bg_play").exists())//进入电台页面2020.09.28
{
console.warn("进入电台界面,退出并进下一篇文章!");
t++;
if (id("btn_back").exists()){
id("btn_back").findOnce().click();//返回 2020.09.28需关闭电台收听
}else{
back; }//返回 2020.09.28需关闭电台收听
while (!id("home_bottom_tab_button_work").exists());
id("home_bottom_tab_button_work").findOne().click();
delay(1);
num = random(0, commentText.length - 1) ; //重取随机数
aCatlog = aCat[num] ;
s = "“学习强国”学习平台";
console.log('文章类别:' + aCatlog + '关键词:'+ s)
click(aCatlog);
delay(1);
continue;
}
if (zt_flag == true)//进入专题页标志
{
console.warn("进入了专题界面,退出并进下一篇文章!")
t++;
back();
delay(1);
zt_flag = false;
continue;
}
console.log("正在学习第" + (i + 1) + "篇文章...");
fail = 0;//失败次数清0
article_timing(i, aTime);
if (i < cCount)//收藏分享2篇文章
{
CollectAndShare(i);//收藏+分享 若运行到此报错请注释本行!
Comment(i);//评论
}
back();//返回主界面
while (!id("home_bottom_tab_button_work").exists());//等待加载出主页
delay(1);
i++;
t++;//t为实际点击的文章控件在当前布局中的标号,和i不同,勿改动!
} else { if (id("v_play").exists() || id("bg_play").exists())//进入电台页面2020.09.28 { console.warn("进入电台界面,退出并进下一篇文章!"); t++; if (id("btn_back").exists()){ id("btn_back").findOnce().click();//返回 2020.09.28需关闭电台收听 }else{ back; } while (!id("home_bottom_tab_button_work").exists()); id("home_bottom_tab_button_work").findOne().click(); delay(1); num = random(0, commentText.length - 1) ; //重取随机数 aCatlog = aCat[num] ; s = "“学习强国”学习平台"; console.log('文章类别:' + aCatlog + '关键词:'+ s) click(aCatlog); delay(1); continue; }
if (i == 0)//如果第一次点击就没点击成功则认为首页无当天文章
{
date_string = getYestardayDateString();
s = date_string;
/*s = "“学习强国”学习平台";*/
num = random(0, commentText.length - 1) ; //重取随机数
aCatlog = aCat[num] ;
click(aCatlog);
console.warn("首页没有找到当天文章,即将学习昨日新闻!"+aCatlog + s);
continue;
}
if (fail > 3)//连续翻几页没有点击成功则认为今天的新闻还没出来,学习昨天的
{
date_string = getYestardayDateString();
/*s = date_string;*/
s = "“学习强国”学习平台";
num = random(0, commentText.length - 1) ; //重取随机数
aCatlog = aCat[num] ;
click(aCatlog);
console.warn("没有找到当天文章,即将学习昨日新闻!"+aCatlog + s);
fail = 0;//失败次数清0
continue;
}
if (!textContains(s).exists())//当前页面当天新闻
{
fail++;//失败次数加一
}
listView.scrollForward();//向下滑动(翻页)
t = 0;
delay(1.5);
}
} }
//调整争上游和对战答题入口,及答题循环,主要使用与 或 非判断结束标志,调整逻辑顺序 /**
/**
/**
@Ivan-cn 去重版题库存在字形题错误,字形题之前是基于answer from char做答的,我用sqllite工具查看过原版题库和您去重题库,原版中是question 题目 选项1 选项2 ,answer 答案。去重题库是 question 题目,answer 答案。question都是一样的。answer from char执行原理是啥? 账号切换,好像前面做完退出部分的逻辑部分不太对? 题库在线更新,能不能把现在还活动的源都添加,逐个执行? 题库的本地基于答题正确更新,每日答题也就视频题和极少部分提示与题目不同的题需要基于题库做,其他完全可以基于提示来,没必要塞题库里。倒是挑战 争上游 对战,随机选的,如果对了,有必要收集起来(字形题还得专门处理)。
@Ivan-cn 去重版题库存在字形题错误,字形题之前是基于answer from char做答的,我用sqllite工具查看过原版题库和您去重题库,原版中是question 题目 选项1 选项2 ,answer 答案。去重题库是 question 题目,answer 答案。question都是一样的。answer from char执行原理是啥? 账号切换,好像前面做完退出部分的逻辑部分不太对? 题库在线更新,能不能把现在还活动的源都添加,逐个执行? 题库的本地基于答题正确更新,每日答题也就视频题和极少部分提示与题目不同的题需要基于题库做,其他完全可以基于提示来,没必要塞题库里。倒是挑战 争上游 对战,随机选的,如果对了,有必要收集起来(字形题还得专门处理)。
我也觉得是,题库主要匹配挑战和争上游等,每日不需要。 我那个题库主要是用SQL语句group by question去重了,所以还排了序(但还有很多相似度很高的question,不知道怎么批量去除);题库搜索的修改是@lolisaikou修改的,好像是前后删一字,然后%通配符搜索之类的;字形题的是用了@admin0008的题库,我看了好像还挺多的,正确率比较高,也包含了@haoguowei98的题库;全部放在tiku表,是因为tikunet可以在线更新(内置的tikunet也去掉了空答案的字段)
账号切换主要考虑在一键的基础外添加,这样不用改动@lolisaikou的主程序,以后主程序升级就直接放进新项目就行了,所以比较简单的循环切换并以线程运行一键学习的js,运行完再备份相关文件,经测试每天auto.js设置定期运行NO_UI.js,目前还正常运行,这几天也成功推送学习结果,一般都能44、45分左右,然后有时间再检查并运行每周及专项答题等:)。我也是js菜鸟,代码都是学习别人再加以修改的,共同学习进步。
老哥你好,能把修改后的脚本再更新下吗?我直接复制替换报错,谢谢老哥!
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原链接已挂掉。