2 Star 14 Fork 2

Mr.Hu/fuckdailyCP

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
index.py 10.92 KB
一键复制 编辑 原始数据 按行查看 历史
Mr.Hu 提交于 2021-02-08 12:39 . update index.py.
import requests
import json
import io
import random
import time
import re
import pyDes
import base64
import uuid
import sys
import os
import hashlib
from Crypto.Cipher import AES
class DailyCP:
def __init__(self, schoolName):
self.key = "b3L26XNL" # "ST83=@XV"#dynamic when app update版本低了请改这个
self.session = requests.session()
self.host = ""
self.loginUrl = ""
self.isIAPLogin = True
self.session.headers.update({
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.61 Safari/537.36 Edg/83.0.478.37",
# "X-Requested-With": "XMLHttpRequest",
"Pragma": "no-cache",
"Accept": "application/json, text/plain, */*",
# "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9",
# "User-Agent": "okhttp/3.12.4"
})
extension = {"deviceId": str(uuid.uuid4()), "systemName": "未来操作系统", "userId": "5201314", "appVersion": "8.1.13",
"model": "红星一号量子计算机", "lon": 0.0, "systemVersion": "初号机", "lat": 0.0}
self.session.headers.update({"Cpdaily-Extension": self.encrypt(json.dumps(extension))})
self.setHostBySchoolName(schoolName)
def setHostBySchoolName(self, schoolName):
ret = self.request("https://static.campushoy.com/apicache/tenantListSort")
school = [j for i in ret["data"] for j in i["datas"] if j["name"] == schoolName]
if len(school) == 0:
print("不支持的学校或者学校名称错误,以下是支持的学校列表")
print(ret)
exit()
ret = self.request(
"https://mobile.campushoy.com/v6/config/guest/tenant/info?ids={ids}".format(ids=school[0]["id"]))
self.loginUrl = ret["data"][0]["ampUrl"]
if ret == "":
print("学校并没有申请入驻今日校园平台")
exit()
print("{name}的登录地址{url}".format(name=schoolName, url=self.loginUrl))
self.host = re.findall(r"//(.*?)/", self.loginUrl)[0]
def encrypt(self, text):
k = pyDes.des(self.key, pyDes.CBC, b"\x01\x02\x03\x04\x05\x06\x07\x08", pad=None, padmode=pyDes.PAD_PKCS5)
ret = k.encrypt(text)
return base64.b64encode(ret).decode()
def passwordEncrypt(self, text: str, key: str):
pad = lambda s: s + (len(key) - len(s) % len(key)) * chr(len(key) - len(s) % len(key))
# unpad = lambda s: s[:-ord(s[len(s) - 1:])]
text = pad("TdEEGazAXQMBzEAisrYaxRRax5kmnMJnpbKxcE6jxQfWRwP2J78adKYm8WzSkfXJ" + text).encode("utf-8")
aes = AES.new(str.encode(key), AES.MODE_CBC, str.encode("ya8C45aRrBEn8sZH"))
return base64.b64encode(aes.encrypt(text))
def request(self, url: str, body=None, parseJson=True, JsonBody=True, Referer=None):
url = url.format(host=self.host)
if Referer != None: self.session.headers.update({"Referer": Referer})
if body == None:
ret = self.session.get(url)
else:
self.session.headers.update(
{"Content-Type": ("application/json" if JsonBody else "application/x-www-form-urlencoded")})
ret = self.session.post(url, data=(json.dumps(body) if JsonBody else body))
# print(json.loads(ret.text))
if parseJson:
return json.loads(ret.text)
else:
return ret
def decrypt(self, text):
k = pyDes.des(self.key, pyDes.CBC, b"\x01\x02\x03\x04\x05\x06\x07\x08", pad=None, padmode=pyDes.PAD_PKCS5)
ret = k.decrypt(base64.b64decode(text))
return ret.decode()
def checkNeedCaptcha(self, username):
url = "https://{host}/iap/checkNeedCaptcha?username={username}".format(host=self.host, username=username)
ret = self.session.get(url)
ret = json.loads(ret.text)
return ret["needCaptcha"]
def generateCaptcha(self):
# url = "https://{host}/iap/generateCaptcha?ltId={client}&codeType=2".format(host=self.host,client=self.client)
# ret = self.session.get(url)
# return ret.content
pass
def getBasicInfo(self):
return self.request("https://{host}/iap/tenant/basicInfo", "{}")
def login(self, username, password, captcha=""):
print('登陆状态' + self.loginUrl)
return self.loginIAP(username, password, captcha)
def loginIAP(self, username, password, captcha=""):
self.session.headers.update({"X-Requested-With": "XMLHttpRequest"})
ret = self.session.get(
"https://{host}/iap/login?service=https://{host}/portal/login".format(host=self.host)).url
client = ret[ret.find("=") + 1:]
ret = self.request("https://{host}/iap/security/lt", "lt={client}".format(client=client), True, False)
client = ret["result"]["_lt"]
# self.encryptSalt = ret["result"]["_encryptSalt"]
body = {
"username": username,
"password": password,
"lt": client,
"captcha": captcha,
"rememberMe": "true",
"dllt": "",
"mobile": ""
}
ret = self.request("https://{host}/iap/doLogin", body, True, False)
if ret["resultCode"] == "REDIRECT":
self.session.get(ret["url"])
return True
else:
return False
def checkNeedCaptchaAuthServer(self, username):
ret = self.request(
"http://{host}/authserver/needCaptcha.html?username={username}&pwdEncrypt2=pwdEncryptSalt".format(
username=username), parseJson=False).text
return ret == "true"
def getCollectorList(self):
body = {
"pageSize": 10,
"pageNumber": 1
}
ret = self.request("https://{host}/wec-counselor-collector-apps/stu/collector/queryCollectorProcessingList",
body)
##返回最新的收集表
print(ret)
return ret["datas"]["rows"]
def getNoticeList(self):
body = {
"pageSize": 10,
"pageNumber": 1
}
ret = self.request("https://{host}/wec-counselor-stu-apps/stu/notice/queryProcessingNoticeList", body)
print(ret)
return ret["datas"]["rows"]
def confirmNotice(self, wid):
body = {
"wid": wid
}
ret = self.request("https://{host}/wec-counselor-stu-apps/stu/notice/confirmNotice", body)
print(ret["message"])
return ret["message"] == "SUCCESS"
def getCollectorDetail(self, collectorWid):
body = {
"collectorWid": collectorWid
}
return self.request("https://{host}/wec-counselor-collector-apps/stu/collector/detailCollector", body)["datas"]
def getCollectorFormFiled(self, formWid, collectorWid):
body = {
"pageSize": 50,
"pageNumber": 1,
"formWid": formWid,
"collectorWid": collectorWid
}
print(formWid, collectorWid)
return self.request("https://{host}/wec-counselor-collector-apps/stu/collector/getFormFields", body)["datas"][
"rows"]
def submitCollectorForm(self, formWid, collectWid, schoolTaskWid, rows, address):
body = {
"formWid": formWid,
"collectWid": collectWid,
"schoolTaskWid": schoolTaskWid,
"form": rows,
"address": address,
"uaIsCpadaily": True,
##定位失败解决
'latitude': 0.0,
'longitude': 0.0
}
ret = self.request("https://{host}/wec-counselor-collector-apps/stu/collector/submitForm", body)
print(ret)
##返回今日打卡结果
Message = message()
Message.sendMessage(ret["message"])
print('打卡结果:' + ret["message"])
return ret["message"] == "SUCCESS"
def autoFill(self, rows):
for item in rows:
index = 0
while index < len(item["fieldItems"]):
if item["fieldItems"][index]["isSelected"] == 1:
index = index + 1
else:
item["fieldItems"].pop(index)
def getFormCharac(self, detail):
ret = self.request(detail["content"], parseJson=False, JsonBody=False)
return hashlib.md5(ret.content).digest().hex()
def autoComplete(self, address):
collectList = self.getCollectorList()
for item in collectList:
detail = self.getCollectorDetail(item["wid"])
form = self.getCollectorFormFiled(detail["collector"]["formWid"], detail["collector"]["wid"])
##从这里开始填写表单数据:见最下方说明
form[0]['fieldItems'][0]['isSelected'] = 1
form[1]['fieldItems'][0]['isSelected'] = 1
form[2]['fieldItems'][0]['isSelected'] = 1
form[3]['fieldItems'][0]['isSelected'] = 1
##截至
self.autoFill(form)
self.submitCollectorForm(detail["collector"]["formWid"], detail["collector"]["wid"],
detail["collector"]["schoolTaskWid"], form, address)
exit()
confirmList = self.getNoticeList()
print(confirmList)
for item in confirmList: self.confirmNotice(item["noticeWid"])
class message:
def sendMessage(self, content):
data ={'msg':str('[今日校园打卡]' +'\n'+ content+'\n'+self.datetime())}
ret = requests.post("你自己的接收消息的接口",data=data)
print(ret.content)
def main_handler(event, context):
userinfo = ["学校名称", "学号", "密码", "签到地址"]
app = DailyCP(userinfo[0])
app.login(userinfo[1], userinfo[2])
app.autoComplete(userinfo[3])
##测试 main_handler(1, 2)
'''
需要填写的内容:
1.填写main_handler中的 userinfo = ["学校名称", "学号", "密码", "签到地址"]
2.填写表单函数:autoComplete
类型1 选择题
A:[题目号]填写数值:题目号-1 例如:第一题则为:1-1=0 填写0 依次类推
B:[题目号]填写数值: 答案号-1 例如:第一题选择答案第一个则为:1-1=0 填写0
form[A]['fieldItems'][B]['isSelected'] = 1
类型2 填空题、或者下拉菜单题
A:[题目号]填写数值:题目号-1 例如:第一题则为:1-1=0 填写0 依次类推
form[A]['value']='湖北省/武汉市/武昌区' ====>对应下拉菜单题,“/”不能掉了
form[A]['value']='无' ====>对应填空题
3.消息推送函数:message中的消息接收地址
自己写扩展函数:邮件,短信,微信,QQ都可以,自己找接口
'''
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/hujixiong/fuckdailyCP.git
git@gitee.com:hujixiong/fuckdailyCP.git
hujixiong
fuckdailyCP
fuckdailyCP
master

搜索帮助