def knowledgeStart(self, knowledegList): try: knowledge = knowledegList[0] nodes = str(knowledge["knowledgeId"]) for node in knowledegList: nodes += "," + str(node["knowledgeId"]) data = { 'clazzid': knowledge["clazzId"], 'userid': self.puid, 'view': 'json', 'nodes': nodes, 'courseid': knowledge["courseId"] } response = self.session.post( 'https://mooc1-api.chaoxing.com/job/myjobsnodesmap', data=data).json() unfinish_knowledgeList = [] for knowledge in knowledegList: knowledgeId = str(knowledge["knowledgeId"]) if response[knowledgeId]["unfinishcount"] > 0: unfinish_knowledgeList.append(knowledge) return unfinish_knowledgeList except: loger.error("获取课程起始点失败", exc_info=True) return None
def init_clazzList(self): """ :return 以course id作为对班列表的key """ try: params = ( ('view', 'json'), ('rss', '1'), ) response = self.session.get( 'http://mooc1-api.chaoxing.com/mycourse/backclazzdata', params=params) clazzList = response.json()["channelList"] self.clazzList = {} for clazz in clazzList: for i in range(len(clazz["content"]["course"]["data"])): self.clazzList[ clazz["content"]["course"]["data"][i]["id"]] = { "courseTeacher": clazz["content"]["course"]["data"][i] ["teacherfactor"], "clazzId": clazz["content"]["id"], "courseName": clazz["content"]["course"]["data"][i]["name"] } return True except Exception as e: loger.error('', exc_info=True) loger.info(self.user_info["uname"] + "\t" + "获取班级列表失败") exit(1)
def shuake(self): self.init_clazzList() self.init_knowledegList() for courseId in self.knowlegeList: flag = 0 if "courseName" in self.user_info: for course in self.user_info['courseName']: if self.clazzList[courseId]['courseName'].find( course) >= 0: flag = 1 break if flag != 1: continue knowlegeList = self.knowledgeStart(self.knowlegeList[courseId]) if knowlegeList is None: continue # 获取起始点出错 for knowledge in knowlegeList: try: scoreInfo = {} if knowledge["courseName"].find('四史学习') >= 0: scoreInfo = self.get_scoreInfo( self.clazzList[knowledge['courseId']]['clazzId'], knowledge['courseId']) if scoreInfo["dayScore"] >= scoreInfo["dailyMaxScore"]: print("\r", self.user_info["ps"], "今天已刷够", scoreInfo["dailyMaxScore"], "分") break else: scoreInfo["dayScore"] = 100 self.submit_study(knowledge) for num in range(len(knowledge["card"])): time.sleep(3) cardsInfoList, reportInfo, success = self.get_cards_info( knowledge, num) if success == False: continue # print(cardsInfoList) for cardInfo in cardsInfoList: if 'type' not in cardInfo: continue # cardinfo 如果没有type信息 ,则此card为视频简介信息 不计分 跳过即可 elif cardInfo['type'] == "video": if "v" not in self.user_info["courseType"]: continue self.watch_video(cardInfo, reportInfo, knowledge, scoreInfo) elif cardInfo['type'] == "read": if "r" not in self.user_info["courseType"]: continue self.read_book(cardInfo, reportInfo, knowledge, scoreInfo) elif cardInfo['type'] == "workid": if "w" not in self.user_info["courseType"]: continue self.dati(cardInfo, reportInfo, knowledge) except: loger.error("刷课异常", exc_info=True)
def funShuake(user_info): JSON_INFO = utils.users_info_load(config.users_path) GLOBAL = JSON_INFO["GLOBAL"] for glo in GLOBAL: if glo not in user_info: user_info[glo] = GLOBAL[glo] shuake = Shuake() if shuake.login(user_info): try: # pass shuake.shuake() except Exception: loger.error('', exc_info=True) else: loger.info(users_info[user_uname]["ps"] + "\t" + ": 密码错误")
def get_scoreInfo(self, classId, courseId): try: params = ( ('classId', classId), ('userId', self.puid), ) response = self.session.get( 'https://tsjy.chaoxing.com/plaza/score/{}/day-score'.format( courseId), params=params) return response.json()["data"]["rule"] except Exception as e: loger.error('', exc_info=True) loger.info(self.user_info["uname"] + "\t" + "获取分数信息失败") return False
def post(self, *args, islogin=False, **kwargs): for i in range(10): try: response = super(Session, self).post(*args, **kwargs, timeout=self.timeOut) if response.text.find("请输入验证码") >= 0: loger.error("发现验证码" + "Url:" + args[0]) raise YZM return response except Exception as e: if i < 9: if type(e) == YZM and not islogin: exit(1) elif type(e) == YZM: raise e time.sleep(5) else: raise e
def login(self, user_info): self.user_info = user_info login_info = { "uname": self.user_info["uname"], "code": self.user_info["code"], "loginType": GLOBAL["loginType"], "roleSelect": GLOBAL["roleSelect"], } try: if not self.sessionload(): self.session = Session(config.timeOut) # self.session.keep_alive = False self.session.headers = { 'Upgrade-Insecure-Requests': '1', 'User-Agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 13_4_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 ChaoXingStudy/ChaoXingStudy_3_4.3.2_ios_phone_201911291130_27 (@Kalimdor)_2092948143612148043', 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8', 'Accept-Language': 'zh-CN,en-US;q=0.8', 'X-Requested-With': 'com.chaoxing.mobile', } params = (('cx_xxt_passport', 'json'), ) response = self.session.post( 'https://passport2-api.chaoxing.com/v11/loginregister', params=params, data=login_info) response = self.session.get( 'https://sso.chaoxing.com/apis/login/userLogin4Uname.do') resp = response.text.encode("utf-8", "ignore").decode("utf-8") self.puid = re.search(r"puid\":(.*?),", resp).group(1) self.login_flag = True self.sessionDump() return self.login_flag else: self.login_flag = True self.sessionDump() return self.login_flag except Exception as e: loger.error('', exc_info=True) loger.info(self.user_info["uname"] + "登陆失败") exit(1)
def answer(question): url = None ans = None try: question = question.replace(" ", "") url = "http://api.gochati.cn/jsapi.php?token=test123&q=" + question response = self.session.get(url).json() ans = response["da"] except: loger.error(url + "出错") loger.error('题目:' + question) loger.error('答案:' + ans) if ans is None or ans == "": try: url = "http://c.ykhulian.com/chati/0/" + question response = self.session.get(url).json() ans = response["answer"] if response["success"] != 200 or response["question"].find( "维护") >= 0 or ans == "": return None except Exception as e: loger.error(url + "出错") loger.error('题目:' + question) loger.error('答案:' + ans) loger.error('搜索答案出错', exc_info=True) raise e #若发生异常 答案没找到 ans = ans.replace("\n\n", "\n \n") ans = ans.replace("#", "\n \n") # '资本主义道路#民主社会主义道路' ans = ans.replace("\u0001", "\n \n") # '资本主义道路#民主社会主义道路' ans = ans.replace(" --- ", "\n \n") # '资本主义道路#民主社会主义道路''效度 --- 信度' ans = ans.replace("===", "\n \n") # '资本主义道路#民主社会主义道路''效度 --- 信度' ans = ans.split("\n \n") while ('' in ans): ans.remove('') return ans
def dati(self, cardInfo, reportInfo, knowledge): def get_method(form): try: return form["method"] except: return "post2" def answer(question): url = None ans = None try: question = question.replace(" ", "") url = "http://api.gochati.cn/jsapi.php?token=test123&q=" + question response = self.session.get(url).json() ans = response["da"] except: loger.error(url + "出错") loger.error('题目:' + question) loger.error('答案:' + ans) if ans is None or ans == "": try: url = "http://c.ykhulian.com/chati/0/" + question response = self.session.get(url).json() ans = response["answer"] if response["success"] != 200 or response["question"].find( "维护") >= 0 or ans == "": return None except Exception as e: loger.error(url + "出错") loger.error('题目:' + question) loger.error('答案:' + ans) loger.error('搜索答案出错', exc_info=True) raise e #若发生异常 答案没找到 ans = ans.replace("\n\n", "\n \n") ans = ans.replace("#", "\n \n") # '资本主义道路#民主社会主义道路' ans = ans.replace("\u0001", "\n \n") # '资本主义道路#民主社会主义道路' ans = ans.replace(" --- ", "\n \n") # '资本主义道路#民主社会主义道路''效度 --- 信度' ans = ans.replace("===", "\n \n") # '资本主义道路#民主社会主义道路''效度 --- 信度' ans = ans.split("\n \n") while ('' in ans): ans.remove('') return ans print("\r{}\t正在答题:".format(self.user_info["ps"], ), knowledge["courseName"], knowledge["parentnodeNmae"], "label:" + knowledge["label"], knowledge["knowlegeName"], cardInfo["property"]['title'], end="") try: params = ( ('workId', cardInfo["property"]["workid"]), ('courseId', knowledge["courseId"]), ('clazzId', knowledge["clazzId"]), ('knowledgeId', knowledge["knowledgeId"]), ('jobId', cardInfo["property"]["_jobid"]), ('enc', cardInfo["enc"]), ('cpi', reportInfo['cpi']), ) response = self.session.get( 'https://mooc1-api.chaoxing.com/work/phone/work', params=params) paramsurl = response.url params_info = dict( urllib.parse.parse_qsl(urllib.parse.urlsplit(paramsurl).query)) soup = BeautifulSoup(response.text, "lxml") titleList = soup.find_all(name="title") for title in titleList: if title.text.find("已批阅") >= 0: return else: form = soup.find(attrs={"id": "form1"}) params = ( ('keyboardDisplayRequiresUserAction', 1), ('_classId', knowledge["clazzId"]), ('courseid', params_info["courseId"]), ('token', form.find(attrs={"id": "enc_work"})["value"]), # ('workAnswerId', params_info["workAnswerId"]), ('totalQuestionNum', form.find(attrs={"id": "totalQuestionNum"})["value"]), ('ua', 'app'), ('formType2', get_method(form)), ('saveStatus', '1'), # ('pos', ''), ('version', '1'), ) data = { 'pyFlag': '', 'courseId': form.find(attrs={"id": "courseId"})["value"], 'classId': form.find(attrs={"id": "classId"})["value"], 'api': form.find(attrs={"id": "api"})["value"], 'mooc': form.find(attrs={"id": "mooc"})["value"], 'workAnswerId': form.find(attrs={"id": "workAnswerId"})["value"], 'totalQuestionNum': form.find(attrs={"id": "totalQuestionNum"})["value"], 'fullScore': form.find(attrs={"id": "fullScore"})["value"], 'knowledgeid': form.find(attrs={"id": "knowledgeid"})["value"], 'oldSchoolId': form.find(attrs={"id": "oldSchoolId"})["value"], 'oldWorkId': form.find(attrs={"id": "oldWorkId"})["value"], 'jobid': form.find(attrs={"id": "jobid"})["value"], 'workRelationId': form.find(attrs={"id": "workRelationId"})["value"], 'enc_work': form.find(attrs={"id": "enc_work"})["value"], 'isphone': 'true', 'userId': self.puid } questionList = form.find_all(attrs={"class": "Py-mian1"}) answerwqbid = "" for question in questionList: questionName = question.find(attrs={ "class": "Py-m1-title fs16" }).text.split("\n")[2].lstrip() questionAnswer = answer(questionName) submits = question.find_all("input") for submit in submits: if submit["id"].find("type") < 0: flag = 0 data[submit["id"].replace("answers", "answer")] = "" if question.find(attrs={ "class": "quesType" }).text == '[单选题]': formAnswers = question.find_all("li") answerwqbid += formAnswers[0]["id-param"] answerwqbid += "," for formAns in formAnswers: if formAns.text.find( questionAnswer[0] ) >= 0: #or questionAnswer[0].find(re.search(r"\n\n(.*?)\n\n",formAns.text).group(1))>=0: data[ submit["id"]] = formAns.text.split( "\n")[1] flag = 1 break elif question.find(attrs={ "class": "quesType" }).text == '[多选题]': formAnswers = question.find_all("li") if questionName.find( "以下说法正确的") >= 0 and questionName.find( "以下说法正确的") <= 5: questionAnswer = answer( formAnswers[0].text.split("\n")[3]) answerwqbid += formAnswers[0]["id-param"] answerwqbid += "," if len(questionAnswer) <= 1: return dataAns = [] for quesAns in questionAnswer: flag = 0 for formAns in formAnswers: if formAns.text.find( quesAns ) >= 0: #or quesAns.find(re.search(r"\n\n(.*?)\n\n",formAns.text).group(1))>=0: dataAns.append( formAns.text.split("\n")[1]) flag = 1 break dataAns.sort() for dataAn in dataAns: data[submit["id"].replace( "answers", "answer")] += dataAn elif question.find(attrs={ "class": "quesType" }).text == "[判断题]": formAnswers = question.find_all("li") answerwqbid += formAnswers[0]["id-param"] answerwqbid += "," if questionAnswer[0].find( "对") >= 0 or questionAnswer[0].find( "正确" ) >= 0 or questionAnswer[0].find( "√") >= 0 or questionAnswer[ 0].find("是") >= 0: data[submit["id"]] = "true" flag = 1 else: data[submit["id"]] = "false" flag = 1 else: raise Exception("题型:" + question.find( attrs={ "class": "quesType" }).text + " 需补充") assert flag == 1 # 若发生异常 答案不匹配 else: data[submit["id"]] = submit["value"] data["answerwqbid"] = answerwqbid self.session.headers[ 'Content-Type'] = 'application/x-www-form-urlencoded; charset=UTF-8' response = self.session.post( 'https://mooc1-api.chaoxing.com/work/addStudentWorkNew', params=params, data=urlencode(data), allow_redirects=False) del self.session.headers['Content-Type'] assert response.json()["msg"] == 'success!' except Exception: loger.error(knowledge["courseName"] + "\t" + knowledge["parentnodeNmae"] + "\t" + knowledge["knowlegeName"] + "\t" + cardInfo["property"]['title']) loger.error('答题出错', exc_info=True)
def init_knowledegList(self): """ :return courseId作为对knowledge列表的key """ try: self.knowlegeList = {} for courseid in self.clazzList: clazzId = self.clazzList[courseid]['clazzId'] params = ( ('id', clazzId), ('personid', self.puid), ('fields', 'id,bbsid,classscore,isstart,allowdownload,chatid,information,discuss,name,state,isfiled,isthirdaq,visiblescore,begindate,course.fields(id,name,infocontent,objectid,app,mappingcourseid,coursesetting.fields(id,courseid,hiddencoursecover,hiddenwrongset),imageurl,bulletformat,knowledge.fields(id,lastmodifytime,createtime,begintime,name,indexOrder,parentnodeid,status,layer,label,card.fields(id,title),attachment.fields(id,objectid,type,extension).type(video)))' ), ('view', 'json'), ) response = self.session.get( 'https://mooc1-api.chaoxing.com/gas/clazz', params=params) course = response.json()["data"][0]["course"]["data"][0] knowledegList = course["knowledge"]["data"] if course["id"] not in self.knowlegeList: self.knowlegeList[course["id"]] = [] jDict = {} def knowledeg_sort(knowlege): labels = knowlege["label"] labels = labels.split(".") label = labels[0] ff = "" for f in labels[0:]: ff += f label += "." label += ff return float(label) for knowlege in knowledegList: jDict[knowlege["id"]] = knowlege for knowlege in knowledegList: if knowlege["parentnodeid"] == 0: continue # 章标题 #if knowlege["parentnodeid"] not in jDict:continue#问题节点 parentnodeid = knowlege["parentnodeid"] while (True): if jDict[parentnodeid]["parentnodeid"] == 0: break else: parentnodeid = jDict[parentnodeid]["parentnodeid"] self.knowlegeList[course["id"]].append({ "knowlegeName": knowlege["name"], "courseName": course["name"], "knowledgeId": knowlege["id"], "courseId": course["id"], "clazzId": clazzId, "parentnodeid": parentnodeid, # 章id "parentnodeNmae": jDict[parentnodeid]["name"], "label": knowlege["label"], "card": knowlege["card"]["data"], "status": knowlege["status"] }) self.knowlegeList[course["id"]].sort(key=knowledeg_sort) # print(self.knowlegeList) return True except Exception as e: loger.error('', exc_info=True) loger.info(self.user_info["uname"] + "\t" + "获取课程列表失败") exit(1)
class myThread(threading.Thread): def __init__(self, user_info): threading.Thread.__init__(self) self.user_info = user_info def run(self): funShuake(self.user_info) if __name__ == '__main__': loger.info("运行") threadList = [] JSON_INFO = utils.users_info_load(config.users_path) GLOBAL = JSON_INFO["GLOBAL"] ###### users_info = JSON_INFO["users_info"] try: for user_uname in users_info: #if user_uname == "18110329539": #continue mythread = myThread(users_info[user_uname]) mythread.start() threadList.append(mythread) time.sleep(5) #if user_uname == "18235275180": #funShuake(users_info[user_uname]) for thread in threadList: thread.join() except Exception as e: loger.error('', exc_info=True)