123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197 |
- #!/usr/bin/env python
- # -*- encoding: utf-8 -*-
- '''
- @Contact : liuyuqi.gov@msn.cn
- @Time : 2022/05/31 01:04:55
- @License : Copyright © 2017-2022 liuyuqi. All Rights Reserved.
- @Desc : cuit.edu.cn 自动选课
- '''
- import platform
- from auto_cuit.libs.json_conf import JsonConf
- from auto_cuit import api
- import requests
- import os
- import sys
- import re
- import json
- import time
- import random
- class Cuit(object):
- def __init__(self, configPath="conf/config.josn"):
- self.sess = requests.session()
- self.conf = JsonConf(configPath)
- self.sess.cookies = self.conf.data['cookies']
- self.sess.headers = {
- "X-Requested-With": "XMLHttpRequest",
- "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.0 Safari/537.36 Edg/84.0.521.0"
- }
- def run(self):
- profiledId = self.conf.data['profiled_id']
- courseName = self.conf.data['course_name']
- # 验证码
- cnt = 0
- while True:
- pic = self.getCaptcha()
- ocrResult = self.postOCRPic(pic)
- print('OCR: ' + ocrResult['result'])
- checkResult = self.checkCaptcha(ocrResult['result'], profiledId)
- if checkResult:
- break
- cnt += 1
- time.sleep(0.5)
- if cnt % 5 == 0:
- print('验证码错误次数过多, 等待5秒')
- time.sleep(5)
- print('验证码检测通过,等待1秒')
- time.sleep(1)
- # 检测开放状态
- print('获取lessonId')
- lessonId = self.courseName2Id(profiledId, courseName)
- if lessonId == None:
- print('没有找到相关课程:' + courseName)
- exit(1)
- print('检测选课开放状态')
- cnt = 0
- while True:
- if self.isAvailable(ocrResult['result'], profiledId):
- break
- pass
- cnt += 1
- print('没有到选课时间,等待5秒 - ' + str(cnt))
- time.sleep(5)
- # 抢课
- print('开始抢课')
- i = 0
- while True:
- i += 1
- print(i)
- if self.fuckCourse(str(profiledId), str(lessonId)):
- break
- time.sleep(0.5)
- if i >= 20:
- i = 0
- if platform.system().lower() == 'linux':
- os.system("clear")
- elif platform.system().lower() == 'windows':
- os.system("cls")
- pass
- pass
- pass
- def fuckCourse(self, profiledId, lessonId):
- try:
- body = {
- "optype": "true",
- "operator0": lessonId + ":true:0",
- "lesson0": lessonId,
- "schLessonGroup_" + lessonId: "undefined"
- }
- req = requests.post(api.chooseCourse % profiledId,
- data=body, timeout=5, allow_redirects=False)
- req.encoding = 'utf-8'
- html = req.text
- ret = re.search(r"margin:auto;\">\n\t\t\t\t(.*)<\/br>", html)
- if ret == None:
- print("cookie过期")
- exit(-1)
- pass
- print(ret.group(1))
- req.close()
- if '成功' in ret.group(1):
- print('get')
- return True
- except Exception as err:
- print("出错")
- print(err)
- return False
- pass
- pass
- def getCaptcha(self):
- try:
- picReq = self.sess.get(url=api.getCaptcha, timeout=5)
- except Exception as err:
- print(err)
- return picReq.content
- def postOCRPic(self, pic):
- url = self.ocrServer
- files = {'captcha': pic}
- data = {
- 'enctype': 'multipart/form-data',
- 'name': 'captcha'
- }
- ocrReq = requests.post(url=url, data=data, files=files)
- return json.loads(ocrReq.content)
- def checkCaptcha(self, captcha, profiledId):
- data = {
- 'captcha_response': captcha,
- 'electionProfile.id': profiledId
- }
- try:
- checkReq = requests.post(
- url=api.checkCode, data=data, allow_redirects=False, timeout=5)
- except Exception as err:
- logger.error(err)
- # print(checkReq.text)
- # 未登录与验证码错误都是302,但Location去向不同
- if checkReq.status_code == 200:
- return True
- elif 'sso' in checkReq.headers['Location']:
- # 转到统一登录中心
- print('cookie失效!!!')
- exit(1)
- return False
- def isAvailable(self, captcha, profiledId):
- '''
- 检测登录状态
- '''
- data = {
- 'captcha_response': captcha,
- 'electionProfile.id': profiledId
- }
- try:
- checkReq = self.sess.post(
- url=api.checkCode, data=data, allow_redirects=False, timeout=5)
- # 未登录与验证码错误都是302,但Location去向不同
- if checkReq.status_code == 200:
- return '不在选课时间内' not in checkReq.text
- elif 'sso' in checkReq.headers['Location']:
- # 转到统一登录中心
- print('cookie失效')
- False
- except Exception as err:
- logger.error(err)
- return False
- return False
- def courseName2Id(self, profileId, courseName):
- try:
- courseListReq = self.sess.get(
- url=api.getCourseList % str(profileId), allow_redirects=False, timeout=5)
- except Exception as err:
- print(err)
- courseList = courseListReq.text
- jsData = execjs.compile(courseList)
- lessonJSONs = jsData.eval('lessonJSONs')
- # print(lessonJSONs)
- for lesson in lessonJSONs:
- if courseName in lesson['name']:
- return lesson['id']
- return None
|