├── PRO-test
├── chaoxingsign.py
└── conf.json
├── README.md
├── chaoxingsign.py
├── config.json
├── old
├── .gitignore
├── account.json.example
├── chaoxingSignServerless.py
├── chaoxingsign.py
└── 多用户-test
│ ├── chaoxingsign.py
│ ├── conf.json
│ └── 云函数版
│ ├── cloud.py
│ └── conf.json
├── tools
├── 刷关注.py
├── 刷收藏量.py
└── 刷笔记.py
└── 异步版
└── emmm.py
/PRO-test/chaoxingsign.py:
--------------------------------------------------------------------------------
1 | import requests
2 | import json
3 | import time
4 | import datetime
5 | import numpy as np
6 | import re
7 | import urllib3
8 | #from retrying import retry
9 |
10 | headers = {
11 | 'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.108 Safari/537.36'}#这个头目前没什么用,留着备用...
12 | try:
13 | with open('conf.json', 'r', encoding='utf-8') as f: # 读取配置文件
14 | conf = json.loads(f.read())
15 | print('获取配置成功')
16 | except FileNotFoundError:
17 | print('未找到配置文件')
18 | print('软件退出')
19 | exit()
20 | urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
21 |
22 | # def retry_if_connection_error(exception):
23 | # return isinstance(exception, requests.exceptions.ConnectionError)
24 | class CxSign():
25 | def __init__(self,conf_user): # 转换一下配置文件
26 | self.username = conf_user['username']
27 | self.passwd = conf_user['passwd']
28 | self.SCKEY = conf_user['SCKEY']
29 | self.name = conf_user['name']
30 | self.address = conf_user['address']
31 | self.longitude = conf_user['longitude']
32 | self.latitude = conf_user['latitude']
33 | self.picname = conf_user['picname']
34 | self.item_all=[]
35 | self.aid_all=[]
36 | try:
37 | self.activates=np.load('activates.npy').tolist()
38 | except IOError: #文件不存在
39 | self.activates=[]
40 | # @retry(retry_on_exception=retry_if_connection_error)
41 | def login(self): # 获取cookie
42 | url = 'https://passport2-api.chaoxing.com/v11/loginregister'
43 | data = {'uname': self.username, 'code': self.passwd }
44 | self.session = requests.session()
45 | cookie_jar = self.session.post(url=url, data=data, headers=headers).cookies
46 | self.session.cookies=cookie_jar
47 | self.cookie = requests.utils.dict_from_cookiejar(cookie_jar)
48 | print('获取cookie成功')
49 |
50 | # @retry(retry_on_exception=retry_if_connection_error)
51 | def subject(self): # 获取课程
52 | url = "http://mooc1-api.chaoxing.com/mycourse/backclazzdata"
53 | res = requests.get(url, headers=headers, cookies=self.cookie)
54 | cdata = json.loads(res.text)
55 | if (cdata['result'] != 1):
56 | print("课程列表获取失败\n重试中")
57 | raise(requests.exceptions.ConnectionError)
58 | for item in cdata['channelList']:
59 | if ("course" in item['content']):
60 | self.item_all.append(item['content'])
61 | # # pushdata['user'] = str(i) # 插入用户标记
62 | # courseid.append(item['content']['course']['data'][0]['id'])
63 | # name.append(item['content']['course']['data'][0]['name'])
64 | # classid.append(item['content']['id'])
65 | #print(self.item_all)
66 |
67 | # @retry(retry_on_exception=retry_if_connection_error)
68 | def taskactivelist(self): # 查找签到任务
69 | url = "https://mobilelearn.chaoxing.com/ppt/activeAPI/taskactivelist"
70 | for i in self.item_all:
71 | payload={'courseId': str(i['course']['data'][0]['id']), 'classId': str(i['id']),'uid': self.cookie['UID']}
72 | print(datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'),'正在查询课程:', i['course']['data'][0]['name'])
73 | res = requests.get(url, params=payload, headers=headers, cookies=self.cookie)
74 | if res.status_code==200: #状态码正常
75 | data = json.loads(res.text)
76 | for item in data['activeList']: #轮询签到任务
77 | if ("nameTwo" in item):
78 | if (item['activeType'] == 2 and item['status'] == 1): # 查找进行中的签到任务
79 | aid = item['id'] # 提取activePrimaryId
80 | if (aid not in self.activates): # 查看是否签到过
81 | print(datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
82 | '[签到]', i['course']['data'][0]['name'], '查询到待签到活动 活动名称:%s 活动状态:%s 活动时间:%s aid:%s' % (
83 | item['nameOne'], item['nameTwo'], item['nameFour'], aid))
84 | self.aid_all.append(aid) #所有进行中的签到任务
85 | self.sign(item['nameOne'],i['course']['data'][0]['id'],i['id'],i['course']['data'][0]['name'],aid) # 调用签到函数
86 |
87 | # @retry(retry_on_exception=retry_if_connection_error)
88 | def upload(self): # 上传图片
89 | if self.picname == '':
90 | return
91 | else:
92 | print('上传图片~~')
93 | tokenurl = 'https://pan-yz.chaoxing.com/api/token/uservalid'
94 | tokenres = requests.get(tokenurl, headers=headers, cookies=self.cookie)
95 | tokendict = json.loads(tokenres.text)
96 | token = tokendict['_token']
97 | uploadurl = 'https://pan-yz.chaoxing.com/upload'
98 | picname = self.picname
99 | try:
100 | files = {'file': (picname, open(picname, 'rb'), 'image/webp,image/*')}
101 | except FileNotFoundError:
102 | print('图片不存在 不上传图片')
103 | return
104 | uploadres = requests.post(uploadurl, data={'puid': self.cookie['UID'], '_token': token}, files=files,headers=headers, cookies=self.cookie)
105 | resdict = json.loads(uploadres.text)
106 | return (resdict['objectId'])
107 |
108 | # @retry(retry_on_exception=retry_if_connection_error)
109 | def sign(self,sign_type,course_id,class_id,course_name,aid): # 签到,偷了个懒,所有的签到类型都用这个,我测试下来貌似都没问题
110 | status=False #一般签到就直接签完了 要加状态判断以用于决定后面的sever酱是否推送
111 | url = "https://mobilelearn.chaoxing.com/pptSign/stuSignajax"
112 | if '位置' in sign_type:
113 | data = {
114 | 'name': self.name,
115 | 'address': self.address,
116 | 'activeId': aid,
117 | 'uid': self.cookie['UID'],
118 | 'longitude': self.longitude,
119 | 'latitude': self.latitude,
120 | }
121 | elif '手势' in sign_type:
122 | data = {
123 | 'name': self.name,
124 | 'activeId': aid,
125 | 'uid': self.cookie['UID'],
126 | 'longitude': -1,
127 | 'latitude': -1,
128 | }
129 | elif '二维码' in sign_type:
130 | data = {
131 | 'name': self.name,
132 | 'activeId': aid,
133 | 'uid': self.cookie['UID'],
134 | 'longitude': -1,
135 | 'latitude': -1,
136 | }
137 | else:
138 | r = self.session.get('https://mobilelearn.chaoxing.com/widget/sign/pcStuSignController/preSign?activeId={}&classId={}&fid=39037&courseId={}'.format(aid,class_id,course_id),headers=headers,verify=False)
139 | title = re.findall('
(.*)', r.text)[0]
140 | if "签到成功" not in title:
141 | objectId = self.upload()
142 | data = {
143 | 'name': self.name,
144 | 'address': self.address,
145 | 'activeId': aid,
146 | 'uid': self.cookie['UID'],
147 | 'longitude': self.longitude,
148 | 'latitude': self.latitude,
149 | 'objectId': objectId
150 | }
151 | else:
152 | status=True
153 | if not status:
154 | res = requests.post(url, data=data, headers=headers, cookies=self.cookie)
155 | text=res.text
156 | else:
157 | text="success"
158 | print("签到状态:", text)
159 | #这边不直接append的原因是长时间运行后这个列表肯定会越来越大
160 | #然后这边直接等于aid_all的话好像逻辑又有点奇怪 感觉好像activates是多余的
161 | self.activates=self.aid_all
162 | #存入所有正在进行中的且签到过的任务 这边的aid_all逻辑有点绕 但是试下来是可行的
163 | #如果是存入activates的话这个文件会越来越大
164 | try:
165 | np.save('activates.npy',np.array(self.aid_all))
166 | except OSError:
167 | pass
168 | if ((not self.SCKEY.isspace()) and (not self.SCKEY=='')) and text=='success':
169 | print('推送中')
170 | self.push(course_name,text)
171 |
172 | # @retry(retry_on_exception=retry_if_connection_error)
173 | def push(self,course_name,status):
174 | api = 'https://sc.ftqq.com/' + self.SCKEY + '.send'
175 | title = u"签到辣!"
176 | content = '课程: '+ course_name+'\n\n签到状态:' + status
177 | data = {
178 | "text": title,
179 | "desp": content
180 | }
181 | requests.post(api, data=data)
182 | print('已推送~')
183 |
184 |
185 | if __name__ == "__main__":
186 | print("运行于普通模式")
187 | all_user=[]
188 | for user_conf in conf:
189 | user=CxSign(user_conf)
190 | all_user.append(user)
191 | print('用户'+user_conf['username']+'登陆中')
192 | user.login()
193 | print('拉取用户'+user_conf['username']+'课程中')
194 | user.subject()
195 | while(1):
196 | for user in all_user:
197 | user.taskactivelist()
198 | user.aid_all=[]
199 | else:
200 | print("运行于云函数模式")
201 | def main_handler(event, context):
202 | for user_conf in conf:
203 | user=CxSign(user_conf)
204 | print('用户'+user_conf['username']+'登陆中')
205 | user.login()
206 | print('拉取用户'+user_conf['username']+'课程中')
207 | user.subject()
208 | user.taskactivelist()
209 |
--------------------------------------------------------------------------------
/PRO-test/conf.json:
--------------------------------------------------------------------------------
1 | [{
2 | "username": "",
3 | "passwd": "",
4 | "SCKEY": "",
5 | "name": "",
6 | "address": "",
7 | "latitude": "32.2829260000",
8 | "longitude": "43.9237990000",
9 | "picname": ""
10 | }]
11 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ## 超星学习通自动签到
2 | 原作者https://www.bilibili.com/video/av94208525
3 |
4 | 云函数完整食用方法https://yuban10703.xyz/archives/527
5 | 有问题直接issue提,别在blog写.....
6 |
7 | 支持学习通的所有签到
8 | 支持server酱推送
9 | 能自定义照片,地址以及名字
10 | 用screen后台挂住就好了,断网的话可能会boom(一般不会断网⑧..)
11 | ## 配置文件
12 | 1. "username":手机号
13 | 2. "passwd":密码
14 | 3. "SCKEY":server酱的key
15 | 4. "name":老师那里显示的名字,无特殊需要默认就行
16 | 5. "address":地址信息
17 | 6. "latitude":经度,同上
18 | 7. "longitude":纬度,同上
19 | 8. "picname":同目录的图片名字
20 | ## 本地使用教程
21 | 1. python3环境
22 | 2. 安装模块: pip install requests
23 | 3. 在同目录下的conf.json中写入配置
24 | 4. 双击运行...
25 | ## 云函数使用教程
26 | 1. 去腾讯云创建一个云函数,目前测试广州好像不能用.其他地区可以.
27 | 2. 环境选择`Python 3.6`
28 | 3. 内存最低实测`64M`可以跑.
29 | 4. 时间看个人课程数量.详细解释看下面
30 | 5. 测试运行,成功后设定定时触发.关于如何设定Cron也可以看下面
31 |
32 | #### 关于时间设定
33 |
34 |
35 | 在`Serverless`版里面,所有课程扫描/签到一次就会停止,这样做是为了符合云函数的设计,同时也节省运行时间.
36 | 最简单的估算办法就是:
37 | * 签到或扫描的请求撑死不会超过2S,记为`x`
38 | * 中间等待时间由`account.json`决定,记为`y`
39 | * 课程数量,记为`z`
40 | 那么最后总时间应该是:
41 | $$z*(x+y)$$
42 |
43 | 绝大多数情况下这个请求时间可以直接忽略.
44 |
45 | 再懒人一点的话,可以直接在命令行运行并统计时间,参考Linux命令`time`
46 |
47 | #### 关于Cron设定
48 | 我们先来看一个例子
49 |
50 | ```
51 | 0 */10 8-12,14-18 * * 1-5
52 | ```
53 |
54 | 云函数的Cron跟Linux Cron非常相似,不过左边多了一个秒.
55 | 以上Cron可以解释为:
56 |
57 | ```
58 | 0 */10 8-12,14-18 * * 1-5
59 | | | | | | |
60 | | | | | | .------- 在周几 (周一到周五)
61 | | | | | .---------- 在哪个月 (所有)
62 | | | | .------------ 在哪一天 (所有)
63 | | | .----------------------- 在几点 (8-12和14-18)
64 | | .---------------------------- 在第几分钟 (每隔10分钟)
65 | .------------------------------ 在第几秒 (第0秒)
66 | ```
67 | 这是比较符合现在上课的情况的Cron,各位也可以根据这个列表进行自定义
68 |
--------------------------------------------------------------------------------
/chaoxingsign.py:
--------------------------------------------------------------------------------
1 | import requests
2 | import json
3 | import time
4 | import datetime
5 |
6 | session = requests.session()
7 | headers = {
8 | 'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.108 Safari/537.36'}
9 | allsubject = []
10 | allname = []
11 | allclassid = []
12 | allcourseid = []
13 | activates = []
14 | allaid = []
15 | cook = []
16 | allobjectid = []
17 | with open('config.json', 'r', encoding='utf-8') as f:
18 | conf = json.loads(f.read())
19 | print('获取配置成功')
20 |
21 |
22 | class CxSign():
23 | def __init__(self, num):
24 | CxSign.username = conf['username'][num]
25 | CxSign.passwd = conf['passwd'][num]
26 | if len(conf['SCKEY']) == 1:
27 | CxSign.SCKEY = conf['SCKEY'][0]
28 | else:
29 | CxSign.SCKEY = conf['SCKEY'][num]
30 |
31 | if len(conf['name']) == 1:
32 | CxSign.name = conf['name'][0]
33 | else:
34 | CxSign.name = conf['name'][num]
35 |
36 | if len(conf['address']) == 1:
37 | CxSign.address = conf['address'][0]
38 | else:
39 | CxSign.address = conf['address'][num]
40 |
41 | if len(conf['longitude']) == 1:
42 | CxSign.longitude = conf['longitude'][0]
43 | else:
44 | CxSign.longitude = conf['longitude'][num]
45 |
46 | if len(conf['latitude']) == 1:
47 | CxSign.latitude = conf['latitude'][0]
48 | else:
49 | CxSign.latitude = conf['latitude'][num]
50 |
51 | if len(conf['picname']) == 1:
52 | CxSign.picname = conf['picname'][0]
53 | else:
54 | CxSign.picname = conf['picname'][num]
55 | # self.name = conf['name'][num]
56 | # self.address = conf['address'][num]
57 | # self.longitude = conf['longitude'][num]
58 | # self.latitude = conf['latitude'][num]
59 | # self.picname = conf['picname'][num]
60 | # self.speed = conf['speed']
61 |
62 | def login(num): # 获取cookie
63 | url = 'https://passport2-api.chaoxing.com/v11/loginregister'
64 | data = {'uname': CxSign(num).username, 'code': CxSign(num).passwd, }
65 | session = requests.session()
66 | cookie_jar = session.post(url=url, data=data, headers=headers).cookies
67 | cookie_t = requests.utils.dict_from_cookiejar(cookie_jar)
68 | cook.append(cookie_t)
69 | print('用户:',num,'获取cookie成功')
70 | # return cookie_t
71 |
72 | def subject(i): # 获取课程
73 | url = "http://mooc1-api.chaoxing.com/mycourse/backclazzdata"
74 | res = requests.get(url, headers=headers, cookies=cook[i])
75 | cdata = json.loads(res.text)
76 | # coursedata=[]
77 | # dict_n = {}
78 | name = []
79 | classid = []
80 | courseid = []
81 | if (cdata['result'] != 1):
82 | print("课程列表获取失败")
83 | for item in cdata['channelList']:
84 | if ("course" not in item['content']):
85 | continue
86 | pushdata = {}
87 | # pushdata['user'] = str(i) # 插入用户标记
88 | courseid.append(item['content']['course']['data'][0]['id'])
89 | name.append(item['content']['course']['data'][0]['name'])
90 | classid.append(item['content']['id'])
91 | allname.append(name)
92 | allclassid.append(classid)
93 | allcourseid.append(courseid)
94 | # coursedata.append(pushdata)
95 | # allsubject.append(coursedata)
96 | # return coursedata
97 |
98 | def taskactivelist(i): # 查找签到任务
99 | global a
100 | aid = []
101 | url = "https://mobilelearn.chaoxing.com/ppt/activeAPI/taskactivelist"
102 | for index in range(len(allname[i])):
103 | payload = {'courseId': str(allcourseid[i][index]), 'classId': str(allclassid[i][index]),
104 | 'uid': cook[i]['UID']}
105 | time.sleep(1.5)
106 | print(datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'), '用户:', i, '正在查询课程:', allname[i][index])
107 | res = requests.get(url, params=payload, headers=headers, cookies=cook[i])
108 | respon = res.status_code
109 | # print(index)
110 | if respon == 200: # 网页状态码正常
111 | # print(res.text)
112 | data = json.loads(res.text)
113 | # print(data)
114 | activeList = data['activeList'] # 把所有任务提出来
115 | for item in activeList: # 轮询所有的任务
116 | if ("nameTwo" not in item):
117 | continue
118 | if (item['activeType'] == 2 and item['status'] == 1): # 查找进行中的签到任务
119 | # signurl = item['url'] # 提取activePrimaryId
120 | aid = item['id'] # 提取activePrimaryId
121 | if (aid not in activates): # 查看是否签到过
122 | print(datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
123 | '[签到]', allname[i][index], '查询到待签到活动 活动名称:%s 活动状态:%s 活动时间:%s aid:%s' % (
124 | item['nameOne'], item['nameTwo'], item['nameFour'], aid))
125 | CxSign.sign(aid, i, index) # 调用签到函数
126 | else:
127 | print('error', respon) # 不知道为啥...
128 |
129 | def token(self): # 获取上传图片用的token
130 | url = 'https://pan-yz.chaoxing.com/api/token/uservalid'
131 | res = requests.get(url, headers=headers, cookies=cook[0])
132 | tokendict = json.loads(res.text)
133 | return (tokendict['_token'])
134 |
135 | def upload(i): # 上传图片
136 | try:
137 | picname = CxSign(i).picname
138 | except:
139 | picname = ''
140 |
141 | if picname.isspace() or len(picname) == 0:
142 | return
143 | else:
144 | url = 'https://pan-yz.chaoxing.com/upload'
145 | files = {'file': (picname, open(picname, 'rb'),
146 | 'image/webp,image/*',), }
147 | res = requests.post(url, data={'puid': cook[0]['UID'], '_token': CxSign.token(i)}, files=files,
148 | headers=headers, cookies=cook[0])
149 | resdict = json.loads(res.text)
150 | allobjectid.append(resdict['objectId'])
151 | # return (resdict['objectId'])
152 |
153 | def sign(aid, i, index): # 签到,偷了个懒,所有的签到类型都用这个,我测试下来貌似都没问题
154 | url = "https://mobilelearn.chaoxing.com/pptSign/stuSignajax"
155 | if len(CxSign(i).picname) == 0:
156 | allobjectid.append('')
157 | objectId = ''
158 |
159 | else:
160 | CxSign.upload(i)
161 | objectId = allobjectid[i]
162 | try:
163 | name = CxSign(i).name
164 | except:
165 | try:
166 | name = CxSign.name
167 | except:
168 | name = ''
169 |
170 | try:
171 | address = CxSign(i).address
172 | except:
173 | try:
174 | address = CxSign.address
175 | except:
176 | address = ''
177 |
178 | try:
179 | longitude = CxSign(i).longitude
180 | except:
181 | try:
182 | longitude = CxSign.longitude
183 | except:
184 | longitude = ''
185 | try:
186 | latitude = CxSign(i).latitude
187 | except:
188 | try:
189 | latitude = CxSign.latitude
190 | except:
191 | latitude = ''
192 |
193 | data = {'name': name, 'address': address, 'activeId': aid, 'uid': cook[i]['UID'],
194 | 'longitude': longitude, 'latitude': latitude, 'objectId': objectId}
195 | # data = { 'activeId': aid, 'uid': cook[i]['UID'],}
196 | res = requests.post(url, data=data, headers=headers, cookies=cook[i])
197 | print("签到状态:", res.text)
198 | if res.text == 'success':
199 | CxSign.push(i, index, res.text)
200 | activates.append(aid)
201 |
202 | def push(i, index, msg):
203 | try:
204 | E_SCKEY = CxSign(i).SCKEY
205 | except:
206 | try:
207 | E_SCKEY = CxSign.SCKEY
208 | except:
209 | E_SCKEY = ''
210 | if E_SCKEY.isspace() or len(E_SCKEY) == 0:
211 |
212 | return
213 | else:
214 | api = 'https://sc.ftqq.com/' + E_SCKEY + '.send'
215 | title = u"签到辣!"
216 | content = '用户:' + str(i) + '\n\n课程: ' + allname[i][index] + '\n\n签到状态:' + msg
217 | data = {
218 | "text": title,
219 | "desp": content
220 | }
221 | requests.post(api, data=data)
222 | print('已推送')
223 |
224 | number = len(conf['username'])
225 | if __name__ == "__main__":
226 | print("运行于普通模式")
227 |
228 | for n in range(number):
229 | CxSign.login(n)
230 | time.sleep(0.8)
231 |
232 | for m in range(number):
233 | CxSign.subject(m)
234 | time.sleep(0.8)
235 | while 1:
236 | for o in range(number):
237 | CxSign.taskactivelist(o)
238 |
239 | else:
240 | print("运行于云函数模式")
241 | def main_handler(event, context):
242 | for n in range(number):
243 | CxSign.login(n)
244 | time.sleep(0.5)
245 |
246 | for m in range(number):
247 | CxSign.subject(m)
248 | time.sleep(0.5)
249 |
250 | for o in range(number):
251 | CxSign.taskactivelist(o)
252 |
253 |
254 | if __name__ == "__main__":
255 | main_handler("", "")
256 |
--------------------------------------------------------------------------------
/config.json:
--------------------------------------------------------------------------------
1 | {
2 | "username": [""],
3 | "passwd": [""],
4 | "SCKEY": [""],
5 | "name": [""],
6 | "address": [""],
7 | "latitude": ["32.2829260000"],
8 | "longitude": ["43.9237990000"],
9 | "picname": [""]
10 | }
11 |
--------------------------------------------------------------------------------
/old/.gitignore:
--------------------------------------------------------------------------------
1 | .idea/
2 | account.json
--------------------------------------------------------------------------------
/old/account.json.example:
--------------------------------------------------------------------------------
1 | {
2 | "username": "",
3 | "passwd": "",
4 | "SCKEY": "",
5 | "name": "",
6 | "address": "火星",
7 | "latitude": "32.2829260000",
8 | "longitude": "43.9237990000",
9 | "picname": "a.png",
10 | "speed": 10
11 | }
12 |
--------------------------------------------------------------------------------
/old/chaoxingSignServerless.py:
--------------------------------------------------------------------------------
1 | # -*- coding: UTF-8 -*-
2 |
3 | import requests
4 | import json
5 | import time
6 | import datetime
7 |
8 |
9 | class CxSign:
10 | username = '' # 账号
11 | passwd = '' # 密码
12 | # server酱推送
13 | SCKEY = ''
14 | name = '' # 签到后老师那里显示的名字,空着的话就是默认
15 | address = '火星' # 地址
16 | latitude = '32.2829260000' # 纬度
17 | longitude = '43.9237990000' # 经度
18 | picname = 'a.png' # 同目录下的照片名字,如果不用就留空 picname=''
19 | # 设置轮询间隔(单位:秒,建议不低于5)
20 | speed = 10
21 |
22 | headers = {
23 | 'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.108 Safari/537.36'
24 | }
25 | coursedata = []
26 | activeList = []
27 | course_index = 0
28 | status = 0
29 | activates = []
30 | a = 1
31 | index = 0
32 | cookie = ''
33 | uid = 0
34 |
35 | def __init__(self, account):
36 | CxSign.username = account['username'] # 账号
37 | CxSign.passwd = account['passwd'] # 密码
38 | # server酱推送
39 | CxSign.SCKEY = account['SCKEY']
40 | CxSign.name = account['name'] # 签到后老师那里显示的名字,空着的话就是默认
41 | CxSign.address = account['address'] # 地址
42 | CxSign.latitude = account['latitude'] # 纬度
43 | CxSign.longitude = account['longitude'] # 经度
44 | CxSign.picname = account['picname'] # 同目录下的照片名字,如果不用就留空 picname=''
45 | # 设置轮询间隔(单位:秒,建议不低于5)
46 | CxSign.speed = account['speed']
47 | CxSign.login(self)
48 |
49 | def login(self): # 获取cookie
50 | url = 'https://passport2-api.chaoxing.com/v11/loginregister'
51 | data = {'uname': CxSign.username, 'code': CxSign.passwd, }
52 | session = requests.session()
53 | cookie_jar = session.post(
54 | url=url, data=data, headers=CxSign.headers).cookies
55 | cookie_t = requests.utils.dict_from_cookiejar(cookie_jar)
56 | CxSign.cookie = cookie_t
57 | CxSign.uid = cookie_t['UID']
58 | # return cookie_t
59 |
60 | def token(self): # 获取上传图片用的token
61 | url = 'https://pan-yz.chaoxing.com/api/token/uservalid'
62 | res = requests.get(url, headers=CxSign.headers, cookies=CxSign.cookie)
63 | tokendict = json.loads(res.text)
64 | return (tokendict['_token'])
65 |
66 | def upload(self): # 上传图片
67 | picname = CxSign.picname
68 | if picname.isspace() or len(picname) == 0:
69 | return
70 | else:
71 | url = 'https://pan-yz.chaoxing.com/upload'
72 | files = {
73 | 'file': (picname, open(picname, 'rb'),
74 | 'image/webp,image/*',),
75 | }
76 | res = requests.post(url, data={
77 | 'puid': CxSign.uid, '_token': CxSign.token(
78 | )
79 | }, files=files, headers=CxSign.headers, cookies=CxSign.cookie)
80 | resdict = json.loads(res.text)
81 | return (resdict['objectId'])
82 |
83 | def taskactivelist(self, courseId, classId): # 查找签到任务
84 | CxSign.a
85 | url = "https://mobilelearn.chaoxing.com/ppt/activeAPI/taskactivelist?courseId=" + \
86 | str(courseId) + "&classId=" + str(classId) + "&uid=" + CxSign.uid
87 | res = requests.get(url, headers=CxSign.headers, cookies=CxSign.cookie)
88 | respon = res.status_code
89 | if respon == 200: # 网页状态码正常
90 | data = json.loads(res.text)
91 | activeList = data['activeList']
92 | # print(activeList)
93 | for item in activeList:
94 | if "nameTwo" not in item:
95 | continue
96 | if item['activeType'] == 2 and item['status'] == 1:
97 | signurl = item['url'] # 提取activePrimaryId
98 | aid = CxSign.getvar(signurl)
99 | if aid not in CxSign.activates:
100 | print(datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
101 | '[签到]', CxSign.coursedata[i]['name'], '查询到待签到活动 活动名称:%s 活动状态:%s 活动时间:%s aid:%s' % (
102 | item['nameOne'], item['nameTwo'], item['nameFour'], aid))
103 | CxSign.sign(aid, CxSign.uid) # print('调用签到函数')
104 |
105 | CxSign.a = 2
106 |
107 | else:
108 | print('error', respon) # 不知道为啥...
109 |
110 | def getvar(self, url): # 查找activePrimaryId
111 | var1 = url.split("&")
112 | for var in var1:
113 | var2 = var.split("=")
114 | if (var2[0] == "activePrimaryId"):
115 | return var2[1]
116 | return "ccc"
117 |
118 | def sign(self, aid, uid): # 签到,偷了个懒,所有的签到类型都用这个,我测试下来貌似都没问题
119 | # CxSign.status, CxSign.activates
120 | url = "https://mobilelearn.chaoxing.com/pptSign/stuSignajax"
121 | objectId = CxSign.upload()
122 | res = requests.post(url, data={
123 | "name": CxSign.name, "address": CxSign.address, 'activeId': aid, 'uid': uid,
124 | 'longitude': CxSign.longitude, 'latitude': CxSign.latitude, 'objectId': objectId
125 | }, headers=CxSign.headers, cookies=CxSign.cookie)
126 | CxSign.push(res.text)
127 | if (res.text == "success"):
128 | print("用户:" + uid + " 签到成功!")
129 | CxSign.activates.append(aid)
130 | CxSign.status = 2
131 | else:
132 | print(res.text, '签到失败')
133 | CxSign.activates.append(aid)
134 |
135 | def push(self, msg):
136 | if CxSign.SCKEY.isspace() or len(CxSign.SCKEY) == 0:
137 | return
138 | else:
139 | api = 'https://sc.ftqq.com/' + CxSign.SCKEY + '.send'
140 | title = u"签到辣!"
141 | content = '课程: ' + CxSign.coursedata[i]['name'] + '\n\n签到状态:' + msg
142 | data = {
143 | "text": title,
144 | "desp": content
145 | }
146 | req = requests.post(api, data=data)
147 |
148 | def doSign(self):
149 | url = "http://mooc1-api.chaoxing.com/mycourse/backclazzdata?view=json&rss=1"
150 | res = requests.get(url, headers=CxSign.headers, cookies=CxSign.cookie)
151 | cdata = json.loads(res.text)
152 | if (cdata['result'] != 1):
153 | print("课程列表获取失败")
154 | for item in cdata['channelList']:
155 | if ("course" not in item['content']):
156 | continue
157 | pushdata = {}
158 | pushdata['courseid'] = item['content']['course']['data'][0]['id']
159 | pushdata['name'] = item['content']['course']['data'][0]['name']
160 | # pushdata['imageurl']=item['content']['course']['data'][0]['imageurl']
161 | pushdata['classid'] = item['content']['id']
162 | CxSign.coursedata.append(pushdata)
163 | print("获取成功:")
164 |
165 | for item in CxSign.coursedata: # 打印课程
166 | print(str(CxSign.index) + ".课程名称:" + item['name'])
167 | CxSign.index += 1
168 | if __name__ == "__main__":
169 | print("运行于普通模式")
170 | while 1:
171 | for i in range(CxSign.index):
172 | CxSign.taskactivelist(self, CxSign.coursedata[i]['courseid'],
173 | CxSign.coursedata[i]['classid'])
174 | if CxSign.a == 2:
175 | CxSign.a = 0
176 | else:
177 | print(datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
178 | '[监控运行中]课程:', CxSign.coursedata[i]['name'], '未查询到签到活动')
179 | time.sleep(CxSign.speed) # 休眠
180 | else:
181 | print("运行于云函数模式")
182 | for i in range(CxSign.index):
183 | CxSign.taskactivelist(self, CxSign.coursedata[i]['courseid'],
184 | CxSign.coursedata[i]['classid'])
185 | if CxSign.a == 2:
186 | CxSign.a = 0
187 | else:
188 | print(datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
189 | '[监控运行中]课程:', CxSign.coursedata[i]['name'], '未查询到签到活动')
190 | time.sleep(CxSign.speed) # 休眠
191 |
192 |
193 | def main_handler(event, context):
194 | # 通过 __name__ 来确定是云函数还是普通模式
195 | # print(__name__)
196 | # 此处读取json文件获取信息
197 | with open("account.json", 'r') as f:
198 | account = json.loads(f.read())
199 | sign = CxSign(account)
200 | sign.doSign()
201 |
202 |
203 | if __name__ == "__main__":
204 | main_handler("", "")
205 |
--------------------------------------------------------------------------------
/old/chaoxingsign.py:
--------------------------------------------------------------------------------
1 | import requests
2 | import json
3 | import time
4 | import datetime
5 |
6 | username = '' # 账号
7 | passwd = '' # 密码
8 | # server酱推送
9 | SCKEY = ''
10 | name = '' # 签到后老师那里显示的名字,空着的话就是默认
11 | address = '火星' # 地址
12 | latitude = '32.2829260000' # 纬度
13 | longitude = '43.9237990000' # 经度
14 | picname = 'a.png' # 同目录下的照片名字,如果不用就留空 picname='',不然会报错...
15 | # 设置轮询间隔(单位:秒,建议不低于5)
16 | speed = 1
17 |
18 | headers = {
19 | 'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.108 Safari/537.36'}
20 | coursedata = []
21 | activeList = []
22 | course_index = 0
23 | status = 0
24 | activates = []
25 | a = 1
26 | index = 0
27 |
28 |
29 | def login(username, passwd): # 获取cookie
30 | url = 'https://passport2-api.chaoxing.com/v11/loginregister'
31 | data = {'uname': username, 'code': passwd, }
32 | session = requests.session()
33 | cookie_jar = session.post(url=url, data=data, headers=headers).cookies
34 | cookie_t = requests.utils.dict_from_cookiejar(cookie_jar)
35 | return cookie_t
36 |
37 |
38 | cookie = login(username, passwd)
39 | uid = cookie['UID']
40 |
41 |
42 | def token(): # 获取上传图片用的token
43 | url = 'https://pan-yz.chaoxing.com/api/token/uservalid'
44 | res = requests.get(url, headers=headers, cookies=cookie)
45 | tokendict = json.loads(res.text)
46 | return (tokendict['_token'])
47 |
48 |
49 | def upload(): # 上传图片
50 | if picname.isspace() or len(picname) == 0:
51 | return
52 | else:
53 | url = 'https://pan-yz.chaoxing.com/upload'
54 | files = {'file': (picname, open(picname, 'rb'),
55 | 'image/webp,image/*',), }
56 | res = requests.post(url, data={'puid': uid, '_token': token(
57 | )}, files=files, headers=headers, cookies=cookie)
58 | resdict = json.loads(res.text)
59 | return (resdict['objectId'])
60 |
61 |
62 | def taskactivelist(courseId, classId): # 查找签到任务
63 | global a
64 | url = "https://mobilelearn.chaoxing.com/ppt/activeAPI/taskactivelist"
65 | payload = {'courseId': str(courseId), 'classId': str(classId), 'uid': uid}
66 | res = requests.get(url, params=payload, headers=headers, cookies=cookie)
67 | respon = res.status_code
68 | if respon == 200: # 网页状态码正常
69 | data = json.loads(res.text)
70 | activeList = data['activeList'] # 把所有任务提出来
71 | for item in activeList:
72 | if ("nameTwo" not in item):
73 | continue
74 | if (item['activeType'] == 2 and item['status'] == 1): # 查找进行中的签到任务
75 | # signurl = item['url'] # 提取activePrimaryId
76 | aid = item['id'] # 提取activePrimaryId
77 | if (aid not in activates): # 查看是否签到过
78 | print(datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
79 | '[签到]', coursedata[i]['name'], '查询到待签到活动 活动名称:%s 活动状态:%s 活动时间:%s aid:%s' % (
80 | item['nameOne'], item['nameTwo'], item['nameFour'], aid))
81 | sign(aid, uid) # 调用签到函数
82 | a = 2
83 | else:
84 | print('error', respon) # 不知道为啥...
85 |
86 |
87 | def sign(aid, uid): # 签到,偷了个懒,所有的签到类型都用这个,我测试下来貌似都没问题
88 | global status, activates
89 | url = "https://mobilelearn.chaoxing.com/pptSign/stuSignajax"
90 | objectId = upload()
91 | data = {'name': name, 'address': address, 'activeId': aid, 'uid': uid,
92 | 'longitude': longitude, 'latitude': latitude, 'objectId': objectId}
93 | res = requests.post(url, data=data, headers=headers, cookies=cookie)
94 | push(SCKEY, res.text)
95 | print("签到状态:", res.text)
96 | activates.append(aid)
97 | status = 2
98 |
99 |
100 | def push(SCKEY, msg):
101 | if SCKEY.isspace() or len(SCKEY) == 0:
102 | return
103 | else:
104 | api = 'https://sc.ftqq.com/' + SCKEY + '.send'
105 | title = u"签到辣!"
106 | content = '课程: ' + coursedata[i]['name'] + '\n\n签到状态:' + msg
107 | data = {
108 | "text": title,
109 | "desp": content
110 | }
111 | req = requests.post(api, data=data)
112 |
113 |
114 | url = "http://mooc1-api.chaoxing.com/mycourse/backclazzdata?view=json&rss=1"
115 | res = requests.get(url, headers=headers, cookies=cookie)
116 | cdata = json.loads(res.text)
117 | if (cdata['result'] != 1):
118 | print("课程列表获取失败")
119 | for item in cdata['channelList']:
120 | if ("course" not in item['content']):
121 | continue
122 | pushdata = {}
123 | pushdata['courseid'] = item['content']['course']['data'][0]['id']
124 | pushdata['name'] = item['content']['course']['data'][0]['name']
125 | # pushdata['imageurl']=item['content']['course']['data'][0]['imageurl']
126 | pushdata['classid'] = item['content']['id']
127 | coursedata.append(pushdata)
128 | print("获取成功:")
129 |
130 | for item in coursedata: # 打印课程
131 | print(str(index) + ".课程名称:" + item['name'])
132 | index += 1
133 |
134 | while 1:
135 | for i in range(index):
136 | time.sleep(speed) # 休眠
137 | taskactivelist(coursedata[i]['courseid'], coursedata[i]['classid'])
138 | if a == 2:
139 | a = 0
140 | else:
141 | print(datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
142 | '[监控运行中]课程:', coursedata[i]['name'], '未查询到签到活动')
143 |
--------------------------------------------------------------------------------
/old/多用户-test/chaoxingsign.py:
--------------------------------------------------------------------------------
1 | import requests
2 | import json
3 | import time
4 | import datetime
5 | # 用户写在同目录的json文件里
6 | # server酱推送
7 | SCKEY = ''
8 | name = '' # 签到后老师那里显示的名字,空着的话就是默认
9 | address = '火星' # 地址
10 | latitude = '32.2829260000' # 纬度
11 | longitude = '43.9237990000' # 经度
12 | picname = '' # 同目录下的照片名字,如果不用就留空 picname=''
13 | speed = 5
14 | with open('conf.json', 'r') as f:
15 | dict = json.load(f)
16 | print('获取配置成功')
17 |
18 | username = list(dict.keys())
19 | passwd = list(dict.values()) # 将字典变成列表,方便操作
20 | session = requests.session()
21 | coursedata = []
22 | activeList = []
23 | activates = []
24 | headers = {
25 | 'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.108 Safari/537.36'}
26 |
27 |
28 | def login(username, password): # 获取cookie
29 | url = 'https://passport2-api.chaoxing.com/v11/loginregister'
30 | data = {'uname': username, 'code': password, }
31 | session = requests.session()
32 | cookie_jar = session.post(url=url, data=data, headers=headers).cookies
33 | cookie_t = requests.utils.dict_from_cookiejar(cookie_jar)
34 | return cookie_t
35 |
36 |
37 | def subject(i): # 获取课程
38 | url = "http://mooc1-api.chaoxing.com/mycourse/backclazzdata"
39 | res = requests.get(url, headers=headers, cookies=cook[i])
40 | cdata = json.loads(res.text)
41 |
42 | dict_n = {}
43 | if (cdata['result'] != 1):
44 | print("课程列表获取失败")
45 | for item in cdata['channelList']:
46 | if ("course" not in item['content']):
47 | continue
48 | pushdata = {}
49 | pushdata['user'] = str(i) # 插入用户标记
50 | pushdata['courseid'] = item['content']['course']['data'][0]['id']
51 | pushdata['name'] = item['content']['course']['data'][0]['name']
52 | pushdata['classid'] = item['content']['id']
53 |
54 | coursedata.append(pushdata)
55 | # return coursedata
56 |
57 |
58 | def token(): # 获取上传图片用的token
59 | url = 'https://pan-yz.chaoxing.com/api/token/uservalid'
60 | res = requests.get(url, headers=headers, cookies=cook[0])
61 | tokendict = json.loads(res.text)
62 | return (tokendict['_token'])
63 |
64 |
65 | def upload(): # 上传图片
66 | if picname.isspace() or len(picname) == 0:
67 | return
68 | else:
69 | url = 'https://pan-yz.chaoxing.com/upload'
70 | files = {'file': (picname, open(picname, 'rb'),
71 | 'image/webp,image/*',), }
72 | res = requests.post(url, data={'puid': str(cook[0]['UID']), '_token': token(
73 | )}, files=files, headers=headers, cookies=cook[0])
74 | resdict = json.loads(res.text)
75 | return (resdict['objectId'])
76 |
77 |
78 | def taskactivelist(user, courseId, classId): # 查找签到任务
79 | global a
80 | url = "https://mobilelearn.chaoxing.com/ppt/activeAPI/taskactivelist?courseId=" + \
81 | str(courseId) + "&classId=" + str(classId) + "&uid=" + str(cook[user]['UID'])
82 | res = requests.get(url, headers=headers, cookies=cook[user])
83 | respon = res.status_code
84 | if respon == 200: # 网页状态码正常
85 | data = json.loads(res.text)
86 | activeList = data['activeList']
87 | for item in activeList:
88 | if ("nameTwo" not in item):
89 | continue
90 | if (item['activeType'] == 2 and item['status'] == 1):
91 | aid = item['id'] # 提取activePrimaryId
92 | if (aid not in activates):
93 | print(datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
94 | '[签到]', coursedata[i]['name'], '查询到待签到活动 活动名称:%s 活动状态:%s 活动时间:%s aid:%s' % (
95 | item['nameOne'], item['nameTwo'], item['nameFour'], aid))
96 | sign(user, aid) # print('调用签到函数')
97 | a = 2
98 | else:
99 | print('error', respon) # 不知道为啥...
100 |
101 |
102 | def getvar(url): # 查找activePrimaryId
103 | var1 = url.split("&")
104 | for var in var1:
105 | var2 = var.split("=")
106 | if (var2[0] == "activePrimaryId"):
107 | return var2[1]
108 | return "ccc"
109 |
110 |
111 | def sign(user, aid): # 签到,偷了个懒,所有的签到类型都用这个,我测试下来貌似都没问题
112 | global status, activates
113 | url = "https://mobilelearn.chaoxing.com/pptSign/stuSignajax"
114 | objectId = upload()
115 | res = requests.post(url, data={"name": name, "address": address, 'activeId': aid, 'uid': str(cook[user]['UID']),
116 | 'longitude': longitude, 'latitude': latitude, 'objectId': objectId}, headers=headers,
117 | cookies=cook[user])
118 | push(SCKEY, res.text)
119 | print("签到状态:", res.text)
120 | activates.append(aid)
121 | status = 2
122 |
123 |
124 | def push(SCKEY, msg):
125 | if SCKEY.isspace() or len(SCKEY) == 0:
126 | return
127 | else:
128 | api = 'https://sc.ftqq.com/' + SCKEY + '.send'
129 | title = u"签到辣!"
130 | content = '课程: ' + coursedata[i]['name'] + '\n\n签到状态:' + msg
131 | data = {
132 | "text": title,
133 | "desp": content
134 | }
135 | req = requests.post(api, data=data)
136 |
137 |
138 | cook = []
139 | for i in range(len(dict)):
140 | a = login(username[i], passwd[i])
141 | cook.append(a)
142 |
143 | for i in range(len(dict)):
144 | subject(i)
145 | index = 1
146 | for item in coursedata: # 打印课程
147 | if item['user'] != a:
148 | index = 1
149 | print("-" * 40)
150 | print('用户:' + item['user'], '-', str(index) + ".课程名称:" + item['name'])
151 |
152 | index += 1
153 | a = item['user']
154 |
155 | while 1:
156 | for i in range(len(coursedata)):
157 | time.sleep(speed) # 休眠
158 | taskactivelist(eval(coursedata[i]['user']), coursedata[i]['courseid'], coursedata[i]['classid'])
159 | if a == 2:
160 | a = 0
161 | else:
162 | print(datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'), '用户', coursedata[i]['user'], '[监控运行中]课程:',
163 | coursedata[i]['name'], '未查询到签到活动')
164 |
--------------------------------------------------------------------------------
/old/多用户-test/conf.json:
--------------------------------------------------------------------------------
1 | {
2 | "账号":"密码",
3 | "账号":"密码",
4 | "账号":"密码"
5 | }
6 |
--------------------------------------------------------------------------------
/old/多用户-test/云函数版/cloud.py:
--------------------------------------------------------------------------------
1 | import requests
2 | import json
3 | import time
4 | import datetime
5 | session = requests.session()
6 | headers = {
7 | 'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.108 Safari/537.36'}
8 | allsubject = []
9 | allname = []
10 | allclassid = []
11 | allcourseid=[]
12 | activates=[]
13 | allaid=[]
14 | cook=[]
15 | allobjectid=[]
16 | with open('conf.json', 'r', encoding='utf-8') as f:
17 | conf = json.loads(f.read())
18 | print('获取配置成功')
19 | class CxSign(): #搞不懂class怎么用.........
20 | def __init__(self,num): #读取配置......(感觉可以写的更简单的......)
21 | CxSign.username = conf['username'][num]
22 | CxSign.passwd = conf['passwd'][num]
23 | if len(conf['SCKEY'])==1:
24 | CxSign.SCKEY = conf['SCKEY'][0]
25 | else:
26 | CxSign.SCKEY = conf['SCKEY'][num]
27 |
28 | if len(conf['name'])==1:
29 | CxSign.name = conf['name'][0]
30 | else:
31 | CxSign.name = conf['name'][num]
32 |
33 | if len(conf['address'])==1:
34 | CxSign.address = conf['address'][0]
35 | else:
36 | CxSign.address = conf['address'][num]
37 |
38 | if len(conf['longitude'])==1:
39 | CxSign.longitude = conf['longitude'][0]
40 | else:
41 | CxSign.longitude = conf['longitude'][num]
42 |
43 | if len(conf['latitude'])==1:
44 | CxSign.latitude = conf['latitude'][0]
45 | else:
46 | CxSign.latitude = conf['latitude'][num]
47 |
48 | if len(conf['picname'])==1:
49 | CxSign.picname = conf['picname'][0]
50 | else:
51 | CxSign.picname = conf['picname'][num]
52 | # self.name = conf['name'][num]
53 | # self.address = conf['address'][num]
54 | # self.longitude = conf['longitude'][num]
55 | # self.latitude = conf['latitude'][num]
56 | # self.picname = conf['picname'][num]
57 | # self.speed = conf['speed']
58 |
59 | def login(num): # 获取cookie
60 | url = 'https://passport2-api.chaoxing.com/v11/loginregister'
61 | data = {'uname': CxSign(num).username, 'code': CxSign(num).passwd, }
62 | session = requests.session()
63 | cookie_jar = session.post(url=url, data=data, headers=headers).cookies
64 | cookie_t = requests.utils.dict_from_cookiejar(cookie_jar)
65 | cook.append(cookie_t) #把所有用户的cookie写进一个列表
66 | return cookie_t
67 |
68 | def subject(i): # 获取课程
69 | url = "http://mooc1-api.chaoxing.com/mycourse/backclazzdata"
70 | res = requests.get(url, headers=headers, cookies=cook[i])
71 | cdata = json.loads(res.text)
72 | # coursedata=[]
73 | # dict_n = {}
74 | name = []
75 | classid = []
76 | courseid = []
77 | if (cdata['result'] != 1):
78 | print("课程列表获取失败")
79 | for item in cdata['channelList']:
80 | if ("course" not in item['content']):
81 | continue
82 | pushdata = {}
83 | # pushdata['user'] = str(i) # 插入用户标记
84 | courseid.append(item['content']['course']['data'][0]['id'])
85 | name.append(item['content']['course']['data'][0]['name'])
86 | classid.append(item['content']['id'])
87 | allname.append(name)#把所有用户的数据存进列表......
88 | allclassid.append(classid)
89 | allcourseid.append(courseid)
90 | # coursedata.append(pushdata)
91 | # allsubject.append(coursedata)
92 | # return coursedata
93 |
94 | def taskactivelist(i): # 查找签到任务
95 | global a
96 | aid=[]
97 | url = "https://mobilelearn.chaoxing.com/ppt/activeAPI/taskactivelist"
98 | for index in range(len(allname[i])):#轮询这个用户的所有课程...
99 | payload = {'courseId': str(allcourseid[i][index]), 'classId': str(allclassid[i][index]), 'uid': cook[i]['UID']}
100 | time.sleep(1.5)
101 | print(datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'),'用户:',i,'正在查询课程:',allname[i][index])
102 | res = requests.get(url, params=payload, headers=headers, cookies=cook[i])
103 | respon = res.status_code
104 | # print(index)
105 | if respon == 200: # 网页状态码正常
106 | # print(res.text)
107 | data = json.loads(res.text)
108 | # print(data)
109 | activeList = data['activeList'] # 把所有任务提出来
110 | for item in activeList: # 轮询所有的任务
111 | if ("nameTwo" not in item):
112 | continue
113 | if (item['activeType'] == 2 and item['status'] == 1): # 查找进行中的签到任务
114 | # signurl = item['url'] # 提取activePrimaryId
115 | aid = item['id'] # 提取activePrimaryId
116 | if (aid not in activates): # 查看是否签到过
117 | print(datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
118 | '[签到]', allname[i][index], '查询到待签到活动 活动名称:%s 活动状态:%s 活动时间:%s aid:%s' % (
119 | item['nameOne'], item['nameTwo'], item['nameFour'], aid))
120 | CxSign.sign(aid,i,index) # 调用签到函数
121 | else:
122 | print('error', respon) # 不知道为啥...
123 |
124 | def token(self): # 获取上传图片用的token
125 | url = 'https://pan-yz.chaoxing.com/api/token/uservalid'
126 | res = requests.get(url, headers=headers, cookies=cook[0])
127 | tokendict = json.loads(res.text)
128 | return (tokendict['_token'])
129 |
130 | def upload(i): # 上传图片
131 | try:
132 | picname=CxSign(i).picname
133 | except:
134 | picname=''
135 |
136 | if picname.isspace() or len(picname) == 0:
137 | return
138 | else:
139 | url = 'https://pan-yz.chaoxing.com/upload'
140 | files = {'file': (picname, open(picname, 'rb'),
141 | 'image/webp,image/*',), }
142 | res = requests.post(url, data={'puid': cook[0]['UID'], '_token': CxSign.token(i)}, files=files, headers=headers, cookies=cook[0])
143 | resdict = json.loads(res.text)
144 | allobjectid.append(resdict['objectId'])
145 | # return (resdict['objectId'])
146 |
147 | def sign(aid,i,index): # 签到,偷了个懒,所有的签到类型都用这个,我测试下来貌似都没问题
148 | url = "https://mobilelearn.chaoxing.com/pptSign/stuSignajax"
149 | if len(CxSign(i).picname)==0:
150 | allobjectid.append('') #占位置,不然和用户ID对不上
151 | objectId =''
152 |
153 | else:
154 | CxSign.upload(i)
155 | objectId=allobjectid[i]
156 | try:
157 | name=CxSign(i).name
158 | except:
159 | try:
160 | name = CxSign.name
161 | except:
162 | name=''
163 |
164 | try:
165 | address=CxSign(i).address
166 | except:
167 | try:
168 | address = CxSign.address
169 | except:
170 | address=''
171 |
172 | try:
173 | longitude = CxSign(i).longitude
174 | except:
175 | try:
176 | longitude = CxSign.longitude
177 | except:
178 | longitude=''
179 | try:
180 | latitude = CxSign(i).latitude
181 | except:
182 | try:
183 | latitude = CxSign.latitude
184 | except:
185 | latitude = ''
186 |
187 | data = {'name': name, 'address': address, 'activeId': aid, 'uid': cook[i]['UID'],
188 | 'longitude': longitude, 'latitude': latitude, 'objectId': objectId}
189 | # data = { 'activeId': aid, 'uid': cook[i]['UID'],}
190 | res = requests.post(url, data=data, headers=headers, cookies=cook[i])
191 | print("签到状态:", res.text)
192 | if res.text == 'success':
193 | CxSign.push(i, index, res.text)
194 |
195 | def push(i,index, msg):
196 | try:
197 | E_SCKEY=CxSign(i).SCKEY
198 | except:
199 | try:
200 | E_SCKEY = CxSign.SCKEY
201 | except:
202 | E_SCKEY =''
203 | if E_SCKEY.isspace() or len(E_SCKEY) == 0:
204 |
205 | return
206 | else:
207 | api = 'https://sc.ftqq.com/' +E_SCKEY + '.send'
208 | title = u"签到辣!"
209 | content ='用户:'+ str(i) + '\n\n课程: ' + allname[i][index] + '\n\n签到状态:' + msg
210 | data = {
211 | "text": title,
212 | "desp": content
213 | }
214 | requests.post(api, data=data)
215 | print('已推送')
216 |
217 | def main_handler(event, context):
218 | number=len(conf['username'])
219 | for n in range(number):
220 | CxSign.login(n)
221 | time.sleep(0.5)
222 |
223 | for m in range(number):
224 | CxSign.subject(m)
225 | time.sleep(0.5)
226 |
227 | for o in range(number):
228 | CxSign.taskactivelist(o)
229 |
230 |
231 | if __name__ == "__main__":
232 | main_handler("", "")
233 |
--------------------------------------------------------------------------------
/old/多用户-test/云函数版/conf.json:
--------------------------------------------------------------------------------
1 | {
2 | "username": [""],
3 | "passwd": [""],
4 | "SCKEY": [""],
5 | "name": [""],
6 | "address": [""],
7 | "latitude": ["32.2829260000"],
8 | "longitude": ["43.9237990000"],
9 | "picname": [""]
10 | }
11 |
--------------------------------------------------------------------------------
/tools/刷关注.py:
--------------------------------------------------------------------------------
1 | import time,hashlib,requests,json
2 | b=53551893#用户开始的ID,一般不用改
3 | username=''#账号
4 | passwd=''#密码
5 |
6 | def enc():
7 | m_time=str(int(time.time()*1000))
8 | m_token='4faa8662c59590c6f43ae9fe5b002b42'
9 | m_encrypt_str='token='+m_token+'&_time='+m_time+'&DESKey=Z(AfY@XS'
10 | md5=hashlib.md5()
11 | md5.update(m_encrypt_str.encode('utf-8'))
12 | m_inf_enc=md5.hexdigest()
13 | return m_time,m_inf_enc
14 | def login(username,passwd):
15 | payload={'uname':username,'code':passwd,'roleSelect':'true','loginType':'1'}
16 | # headers1 = {
17 | # 'User-Agent': 'Dalvik/2.1.0 (Linux; U; Android 6.0.1; HUAWEI ALE-CL00 Build/MOB31T) com.chaoxing.mobile/ChaoXingStudy_3_4.3.6_android_phone_496_27 (@Kalimdor)_57c3eb14b06a443db750026b3754a8ad',}
18 |
19 | s = requests.session()
20 | url='https://passport2-api.chaoxing.com/v11/loginregister'
21 | cookie_jar = s.post(url=url, params=payload, )
22 |
23 | url2='https://sso.chaoxing.com/apis/login/userLogin4Uname.do'
24 | cookie_jar2 = s.get(url=url2,).cookies
25 | cookie_full = requests.utils.dict_from_cookiejar(cookie_jar2)
26 | return cookie_full
27 |
28 | cookie=login(username,passwd)
29 | headers = {'User-Agent': 'Dalvik/2.1.0 (Linux; U; Android 6.0.1; HUAWEI ALE-CL00 Build/MOB31T) com.chaoxing.mobile/ChaoXingStudy_3_4.3.6_android_phone_496_27 (@Kalimdor)_57c3eb14b06a443db750026b3754a8ad',
30 | 'Connection': 'Keep-Alive'}
31 | url='http://learn.chaoxing.com/apis/friend/addUserFollow'
32 |
33 |
34 | for i in range(50000):
35 | a = enc()
36 | payload = {'token': '4faa8662c59590c6f43ae9fe5b002b42',
37 | '_time': a[0],
38 | 'uid': '42528010',
39 | 'puid': b,
40 | 'followedUid': cookie['_tid'],
41 | 'followedPuid': cookie['_uid'],
42 | 'inf_enc': a[1],
43 | }
44 | b+=1
45 | req=requests.get(url,params=payload,cookies=cookie,headers=headers,allow_redirects=False)
46 | print(req.text)
47 | print(b)
48 | time.sleep(0.2)
49 |
--------------------------------------------------------------------------------
/tools/刷收藏量.py:
--------------------------------------------------------------------------------
1 | import time,hashlib,requests,json,time
2 |
3 | username=''#账号
4 | passwd=''#密码
5 | book='nmsl'#书名
6 | writer='nmsl'#作者名字
7 | folder='109687111'#文件夹ID随便填就行
8 |
9 | picurl="https://i.loli.net/2020/04/03/kbzNxYAL7fstuoX.png"#图片链接
10 |
11 |
12 | data = []
13 | data.append('--bBtm2w4jqNNple2J0jfYCgGEwpfAgF2zTaZZqG6Q\r\n')
14 | data.append('Content-Disposition: form-data; name="uid"\r\n')
15 | data.append('Content-Type: text/plain; charset=UTF-8\r\n')
16 | data.append('Content-Transfer-Encoding: 8bit\r\n')
17 | data.append('\r\n')
18 | data.append('117729841'+ '\r\n')
19 | data.append('--bBtm2w4jqNNple2J0jfYCgGEwpfAgF2zTaZZqG6Q\r\n')
20 | data.append('Content-Disposition: form-data; name="cfid"\r\n')
21 | data.append('Content-Type: text/plain; charset=UTF-8\r\n')
22 | data.append('Content-Transfer-Encoding: 8bit\r\n')
23 | data.append('\r\n')
24 | data.append(folder + '\r\n')
25 | data.append('--bBtm2w4jqNNple2J0jfYCgGEwpfAgF2zTaZZqG6Q\r\n')
26 | data.append('Content-Disposition: form-data; name="source"\r\n')
27 | data.append('Content-Type: text/plain; charset=UTF-8\r\n')
28 | data.append('Content-Transfer-Encoding: 8bit\r\n')
29 | data.append('\r\n')
30 | data.append('0\r\n')
31 | data.append('--bBtm2w4jqNNple2J0jfYCgGEwpfAgF2zTaZZqG6Q\r\n')
32 | data.append('Content-Disposition: form-data; name="resinfo"\r\n')
33 | data.append('Content-Type: text/plain; charset=UTF-8\r\n')
34 | data.append('Content-Transfer-Encoding: 8bit\r\n')
35 | datas = ''
36 | for i in data:
37 | datas += i
38 | data2=[]
39 | data2.append('\r\n')
40 | data2.append('--bBtm2w4jqNNple2J0jfYCgGEwpfAgF2zTaZZqG6Q\r\n')
41 | data2.append('Content-Disposition: form-data; name="version"\r\n')
42 | data2.append('Content-Type: text/plain; charset=UTF-8\r\n')
43 | data2.append('Content-Transfer-Encoding: 8bit\r\n')
44 | data2.append('\r\n')
45 | data2.append('8.6' + '\r\n')
46 | data2.append('--bBtm2w4jqNNple2J0jfYCgGEwpfAgF2zTaZZqG6Q--\r\n')
47 | datas2 = ''
48 | for i in data2:
49 | datas2 += i
50 | headers = {'User-Agent': 'Dalvik/2.1.0 (Linux; U; Android 6.0.1; HUAWEI ALE-CL00 Build/MOB31T) com.chaoxing.mobile/ChaoXingStudy_3_4.3.6_android_phone_496_27 (@Kalimdor)_57c3eb14b06a443db750026b3754a8ad',
51 | 'Content-Type':'multipart/form-data; boundary=bBtm2w4jqNNple2J0jfYCgGEwpfAgF2zTaZZqG6Q',
52 | 'Host':'apps.chaoxing.com',
53 | 'Connection': 'Keep-Alive'}
54 |
55 | def login(username,passwd):
56 | payload={'uname':username,'code':passwd,'roleSelect':'true','loginType':'1'}
57 | # headers1 = {
58 | # 'User-Agent': 'Dalvik/2.1.0 (Linux; U; Android 6.0.1; HUAWEI ALE-CL00 Build/MOB31T) com.chaoxing.mobile/ChaoXingStudy_3_4.3.6_android_phone_496_27 (@Kalimdor)_57c3eb14b06a443db750026b3754a8ad',}
59 |
60 | s = requests.session()
61 | url='https://passport2-api.chaoxing.com/v11/loginregister'
62 | cookie_jar = s.post(url=url, params=payload, )
63 |
64 | url2='https://sso.chaoxing.com/apis/login/userLogin4Uname.do'
65 | cookie_jar2 = s.get(url=url2,).cookies
66 | cookie_full = requests.utils.dict_from_cookiejar(cookie_jar2)
67 | return cookie_full
68 |
69 | cookie=login(username,passwd)
70 |
71 |
72 | def enc():
73 | m_time=str(int(time.time()*1000))
74 | m_token='4faa8662c59590c6f43ae9fe5b002b42'
75 | m_encrypt_str='token='+m_token+'&_time='+m_time+'&DESKey=Z(AfY@XS'
76 | md5=hashlib.md5()
77 | md5.update(m_encrypt_str.encode('utf-8'))
78 | m_inf_enc=md5.hexdigest()
79 | return m_time,m_inf_enc
80 | a=enc()
81 | print(a[0],a[1])
82 |
83 | def favorite(time,enc):
84 | data1 = {"cataid": "100000001", "cataName": "专题", "key": 'mooc_'+id,
85 | "content": {"accountKey": "cx_fanya", "aid": "mooc_211237260", "appid": "024f788b762eefd3ea71e05d0c8e003f",
86 | "appname": book, "appurl": "https://special.zhexuezj.cn/mobile/mooc/tocourse/211237260",
87 | "available": 1, "bind": 1, "cataid": "100000001", "clientType": 127, "description": "",
88 | "focus": 0, "id": -1, "isPrivate": 1, "isWebapp": 1, "loginId": 2, "loginUrl": "",
89 | "logopath": picurl,
90 | "logoshowtype": 1, "needLogin": 0, "needRegist": 0, "norder": 0,
91 | "otherConfig": {"author": writer, "id": "mooc_211237260", "authorPuid": "126098093", "level": 1000},
92 | "productId": 3, "properties": "", "rights": 1, "usable": "", "useClientTool": 2,
93 | "res_src": "market"}, "collectionFolder": 0,}
94 | alldata = datas + '\r\n' + json.dumps(data1) + '\r\n' + datas2
95 |
96 | url='http://apps.chaoxing.com/apis/subscribe/addExternalSubscribe.jspx?token=4faa8662c59590c6f43ae9fe5b002b42'+'&_time='+time+'&inf_enc='+enc
97 | res = requests.post(url,data=alldata,cookies=cookie, headers=headers,allow_redirects=False)
98 | print(res.text)
99 | # print(url)
100 | for x in range(5000):
101 | id=str(x)
102 | a = enc()
103 | favorite(a[0],a[1])
104 | time.sleep(0.5)
105 | print(x)
106 |
--------------------------------------------------------------------------------
/tools/刷笔记.py:
--------------------------------------------------------------------------------
1 | import time,hashlib,requests,json
2 | username=''#账号
3 | passwd=''#密码
4 | text='text'
5 | title='title'
6 | id=30000 #笔记编号
7 | D='b06d289b-b69a-44d8-a7ef-'#笔记编号
8 | #如果提示非个人笔记就改上面这些值,貌似是随机的,随便改,但是格式不能变,
9 | headers = {'User-Agent': 'Dalvik/2.1.0 (Linux; U; Android 6.0.1; HUAWEI ALE-CL00 Build/MOB31T) com.chaoxing.mobile/ChaoXingStudy_3_4.3.6_android_phone_496_27 (@Kalimdor)_57c3eb14b06a443db750026b3754a8ad',
10 | 'Connection': 'Keep-Alive'}
11 | def login(username,passwd):
12 | payload={'uname':username,'code':passwd,'roleSelect':'true','loginType':'1'}
13 | # headers1 = {
14 | # 'User-Agent': 'Dalvik/2.1.0 (Linux; U; Android 6.0.1; HUAWEI ALE-CL00 Build/MOB31T) com.chaoxing.mobile/ChaoXingStudy_3_4.3.6_android_phone_496_27 (@Kalimdor)_57c3eb14b06a443db750026b3754a8ad',}
15 |
16 | s = requests.session()
17 | url='https://passport2-api.chaoxing.com/v11/loginregister'
18 | cookie_jar = s.post(url=url, params=payload, )
19 |
20 | url2='https://sso.chaoxing.com/apis/login/userLogin4Uname.do'
21 | cookie_jar2 = s.get(url=url2,).cookies
22 | cookie_full = requests.utils.dict_from_cookiejar(cookie_jar2)
23 | return cookie_full
24 |
25 | cookie=login(username,passwd)
26 | def enc():
27 | m_time=str(int(time.time()*1000))
28 | m_token='4faa8662c59590c6f43ae9fe5b002b42'
29 | m_encrypt_str='token='+m_token+'&_time='+m_time+'&DESKey=Z(AfY@XS'
30 | md5=hashlib.md5()
31 | md5.update(m_encrypt_str.encode('utf-8'))
32 | m_inf_enc=md5.hexdigest()
33 | return m_time,m_inf_enc
34 |
35 |
36 |
37 |
38 | for i in range(20000):
39 | id+=1
40 | a=enc()
41 | url='https://noteyd.chaoxing.com/apis/note_note/uploadNote'
42 | payload={'token':'4faa8662c59590c6f43ae9fe5b002b42',
43 | '_time':a[0],
44 | 'inf_enc':a[1]
45 | }
46 | cid = D + str(id)
47 | data = {'action': '1',
48 | 'attachment': '',
49 | 'cid': cid,
50 | 'content': text,
51 | 'delete': '0',
52 | 'describes': 'Test3',
53 | 'files_url': '',
54 | 'isRtf': '1',
55 | 'notebookCid': '0',
56 | 'puid': cookie['_uid'],
57 | 'rtf_content': '%3Cp%3ETest1%3C%2Fp%3E',
58 | 'sort': '0.0',
59 | 'tag': '',
60 | 'title': title,
61 | 'top': '0',
62 | 'version': '0'}
63 | req=requests.post(url,params=payload,data=data,headers=headers,cookies=cookie)
64 | print(req.text)
65 | time.sleep(0.5)
66 |
--------------------------------------------------------------------------------
/异步版/emmm.py:
--------------------------------------------------------------------------------
1 | import aiohttp
2 | import asyncio
3 | import requests
4 | import json
5 |
6 |
7 | headers = {
8 | 'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.108 Safari/537.37'}
9 | name = ''
10 | address = ''
11 | longitude = ''
12 | latitude = ''
13 | objectId = ''
14 |
15 |
16 | class Objects:
17 | def __init__(self, item):
18 | self.courseid = item['content']['course']['data'][0]['id']
19 | self.name = item['content']['course']['data'][0]['name']
20 | self.classid = item['content']['id']
21 |
22 |
23 | def login(username, passwd): # 获取cookie
24 | url = 'https://passport2-api.chaoxing.com/v11/loginregister'
25 | data = {'uname': username, 'code': passwd, }
26 | session = requests.session()
27 | cookie_jar = session.post(url=url, data=data,).cookies
28 | cookie_t = requests.utils.dict_from_cookiejar(cookie_jar)
29 | return cookie_t
30 |
31 |
32 | cookies = login('', '')
33 | uid = cookies['UID']
34 |
35 | tasks1 = []
36 |
37 | async def taskactivelist(courseId, classId, session):
38 | url = "https://mobilelearn.chaoxing.com/ppt/activeAPI/taskactivelist"
39 | payload = {'courseId': str(courseId), 'classId': str(classId), 'uid': uid}
40 | async with session.get(url, headers=headers, params=payload) as resp:
41 | if resp.status == 200:
42 | # print(await resp.text())
43 | cdata = json.loads(await resp.text())
44 | # activeList = cdata['activeList']
45 | for item in cdata['activeList']: # 轮询所有的任务
46 | # print('>>>',item)
47 | if ("nameTwo" not in item):
48 | continue
49 | if (item['activeType'] == 2 and item['status'] == 1): # 查找进行中的签到任务
50 | aid = item['id'] # 提取activePrimaryId
51 | # print(item)
52 | print('>>>',aid)
53 | tasks1.append(asyncio.create_task(sign(aid, session)))
54 | await asyncio.gather(*tasks1)
55 | # sign(aid)
56 |
57 | async def sign(aid, session): # 签到,偷了个懒,所有的签到类型都用这个,我测试下来貌似都没问题
58 | await asyncio.sleep(2)
59 | url = "https://mobilelearn.chaoxing.com/pptSign/stuSignajax"
60 | data = { 'activeId': aid, 'uid': uid,}
61 | print(data)
62 | async with session.post(url, data=data) as resp:
63 | print(resp.status)
64 | # print(await resp.text())
65 |
66 | # def sign(aid,): # 签到,偷了个懒,所有的签到类型都用这个,我测试下来貌似都没问题
67 | # url = "https://mobilelearn.chaoxing.com/pptSign/stuSignajax"
68 | # data = {'name': name, 'address': address, 'activeId': str(aid), 'uid': uid,
69 | # 'longitude': longitude, 'latitude': latitude, 'objectId': objectId}
70 | # res = requests.post(url, data=data, headers=headers, cookies=cookies)
71 | # print("签到状态:", res.text)
72 |
73 | async def subject(): # 获取课程
74 | url = "http://mooc1-api.chaoxing.com/mycourse/backclazzdata"
75 | async with aiohttp.ClientSession(cookies=cookies) as session:
76 | async with session.get(url) as resp:
77 | cdata = json.loads(await resp.text())
78 | print(cdata)
79 | tasks = []
80 | for item in cdata['channelList']:
81 | if ("course" not in item['content']):
82 | continue
83 | a = Objects(item)
84 | tasks.append(asyncio.create_task(taskactivelist(a.courseid, a.classid, session)))
85 | await asyncio.gather(*tasks)
86 |
87 |
88 | async def main():
89 | await asyncio.create_task(subject())
90 |
91 |
92 | asyncio.run(main())
93 |
--------------------------------------------------------------------------------