2023年6月29日发(作者:)
icode青少年编程⽐赛⽹站学⽣刷题进度爬⾍需求分析:本⼈是带学⽣参加icode编程⽐赛的python项⽬的⽼师,学⽣⽐较懒,所以每天⽹络教学的同时,更要督促学⽣每天刷训练场的编程题。尤其决赛训练阶段,我每天都要登陆⽐赛同学的账号,然后登陆进去,依次记录学⽣四个训练场刷题所得的星数在excle表格⾥:如下图
检查学⽣每天是否努⼒做题了,所以我的需求,⾃动循环读取excle的学⽣账号,切换登陆学⽣的账号,然后爬取学⽣四个训练场所得的星数并记录在excle⾥。下⾯是我⼿⼯操作每天记录的学⽣刷题情况。如图:实战解错:此⽹站post提交的密码采⽤md5加密,因为只是学⽣⽐赛⽹站,安全性要求不⾼,也没有验证码检验的烦琐程序。相对js解密定位加密相关代码还是⽐较容易的。因为本⼈⽔平有限,也不会分析具体是哪些函数涉及md5加密的,索性把整个md5加密js⽂件代码都复制出来并且经过发条js调试⼯具通过,能够得到加密之后的密码。 但是怪就怪在这⾥,我在第⼀天直接把这个所有的md5加密的js⽂件⾥的密码,通过python ,pyexecjs类库执⾏还没问题,第⼆天准备加⼊excle读写功能,再次运⾏相关解密代码时,竟然 报错了,⼀开始报错,md5 is not defined的错误,后来各种折腾⼀直显⽰编码报错: 百度了好久,把pycharm所有的编码设置项,所设为"utf-8",报错都存在,实在没办法就想把md5加密的js⽂件⼀些⽆关代码去掉⼀些,我虽然学过⼀些前端,但是⽔平也很低,⽆奈中的尝试,竟然解决了问题,把下⾯的代码去掉竟然 解决了问题: 实战源码:import requestsimport execjsimport xlwings as xwimport mathimport timeimport datetime#==================================#==所有⽤到的变量==#标志作业检查⼯作表,之前是否存在,存在不写⼊相关信息,不存在则创建写⼊相关信息,避免第⼆次打开的重复写⼊作业检查=False#定义查询⼏级训练场的参数leval=["0","10","20","30"]#间隔写⼊需要传⼊的间隔列数intervalCols=4#===================================# 打开Excel程序,默认设置:程序可见,只打开不新建⼯作薄,屏幕更新打开app=(visible=True,add_book=False)y_alerts=_updating= True#另⼀种打开⼯作簿的⽅法#workBook= ('./icode账号.xlsx')workBook=('./icode账号.xlsx')#得到打开⼯作的所有⼯作表sheets = if "作业检查" in str(sheets): print("作业检查⼯作表存在") 作业检查 = Trueelse: print("作业检查⼯作表不存在") (name="作业检查", after="账号")print("打开的⼯作簿的所有⼯作表:",sheets)#打开第⼀张学⽣账号⼯作表sheet1st = [0]print("第⼀张⼯作表名字:",)# 获取⼯作表的活动区域rng = ('a1').expand('table')# 获取活动区域的⾏数nrows = rint("学⽣账户⼯作表总⾏数:",nrows)print("学⽣账户⼯作表总⾏数:",nrows)# 接着就可以按准确范围读取了accounts=(f'c1:c{nrows}').valuepwds = (f'd1:d{nrows}').value#print("读取学⽣账号试验:",str((accounts[1])))print("学⽣密码:",pwds)#读取姓名names=(f'b1:b{nrows}').valueprint("学⽣姓名:",names)#-------------------------------------------------#打开作业检查⼯作表sheet2nd=["作业检查"]#作业检查⼯作表⾃动调整宽度t()#之前作业检查⼯作不存在,证明是第⼀次打开,则写⼊基本信息if 作业检查==False: ('A1').value="姓名" ('A2').value="⽇期"# 获取第2张⼯作表的活动区域rng2nd = ('a1').expand('table')# 获取第2张⼯作表的活动区域的⾏数nrows2ndUsed = rint("作业检查⼯作表总⾏数:",nrows2ndUsed )#获取并写⼊时间nowTime = ()(nrows2ndUsed+1,1).value=nowTime#--------------------------------------------------------------------------------#1实例化⼀个node对象node = ()#2js源⽂件编译ctx = e(open("./", encoding="utf-8").read())#----------------------------------------------------------------------------------------------#创建⼀个session对象session = n()signInUrl = "/user/userLogin"signInUrlHeaders = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.87 Safari/537.36 SE 2.X MetaSr 1.0", "Origin": "", "Referer": "/signIn"}GameListUrl="/user/getGameList"GameListUrlHeaders = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) /80.0.3987.87 Safari/537.36 SE 2.X MetaSr 1.0", "Origin": "", "Referer": "/index"}#===================================================================================================for i in range(nrows-1): # 之前作业检查⼯作不存在,证明是第⼀次打开,则写⼊基本信息 if 作业检查 == False: #每隔4列写⼊数据 (1,2+intervalCols*i).value=names[1+i] #合并姓名单元格 # ((1, 2 + intervalCols * i), (1, 2 + intervalCols * i + 3)).() #写⼊四个训练场⽂字 (2, 2 + 4 * i).value = ["1级训练场","2级训练场","3级训练场","4级训练场"] #-------------------------------------------------------- # 3.执⾏js函数 funcName = 'getPwd("{0}")'.format(pwds[i+1]) pwdEncrypted = (funcName) signInData = { #读出的账号数据是类似".0"这样的数据所以必须作下处理,取出整数,并转换成字符串 "email": str((accounts[i+1])), "password": pwdEncrypted } } text = (url=signInUrl, headers=signInUrlHeaders, data=signInData).text print("登陆请求返回的信息:",text) for j in range(4): GameListData = { "mode": "1", # 0是1级训练场,10是2级训练场;20是3级训练场;30是4级训练场 "level": leval[j] } GameListJson = (url=GameListUrl, headers=GameListUrlHeaders, data=GameListData).json() # print(str(GameListJson["data"]["star"])+"/"+str(GameListJson["data"]["totalStar"])) # print('"{0}/{1}"'.format(str(GameListJson["data"]["star"]),str(GameListJson["data"]["totalStar"]))) (nrows2ndUsed+1, 2+intervalCols*i + j).value ="{0}/{1}".format(GameListJson["data"]["star"],GameListJson["data"]["totalStar"]) # print(”所得星数:“,GameListJson["data"]["star"]) # print(”总星数:“,GameListJson["data"]["totalStar"]) #--------------------------------------------------------------------------- #--取消息上次最后⼀⾏数据的下边框-- ((1, 1), (nrows2ndUsed, 1)).s(9).LineStyle = 0 ((1, 2 + intervalCols * i), (nrows2ndUsed, 2 + intervalCols * i + 3)).s(9).LineStyle = 0 #-------------------------------------------------------------------------------------------------------------------- #--第⼀列边框处理-- ((1, 1), (nrows2ndUsed+1, 1)).s(7).LineStyle = 1 ((1, 1), (nrows2ndUsed+1, 1)).s(7).Weight = 3 ((1, 1), (nrows2ndUsed + 1, 1)).s(8).LineStyle = 1 ((1, 1), (nrows2ndUsed + 1, 1)).s(8).Weight = 3 ((1, 1), (nrows2ndUsed + 1, 1)).s(9).LineStyle = 1 ((1, 1), (nrows2ndUsed + 1, 1)).s(9).Weight = 3 #------------------------------------------------------------------------------------------------------------------------------------ #--对⼀个⼈的四列数据加上边框便于好看-- ((1, 2 + intervalCols * i), (nrows2ndUsed+1, 2 + intervalCols * i + 3)).s(7).LineStyle = 1 ((1, 2 + intervalCols * i), (nrows2ndUsed+1, 2 + intervalCols * i + 3)).s(7).Weight = 3 ((1, 2 + intervalCols * i), (nrows2ndUsed+1, 2 + intervalCols * i + 3)).s(8).LineStyle = 1 ((1, 2 + intervalCols * i), (nrows2ndUsed+1, 2 + intervalCols * i + 3)).s(8).Weight = 3 ((1, 2 + intervalCols * i), (nrows2ndUsed+1, 2 + intervalCols * i + 3)).s(9).LineStyle = 1 ((1, 2 + intervalCols * i), (nrows2ndUsed+1, 2 + intervalCols * i + 3)).s(9).Weight = 3 ((1, 2 + intervalCols * i), (nrows2ndUsed+1, 2 + intervalCols * i + 3)).s(10).LineStyle = 1 ((1, 2 + intervalCols * i), (nrows2ndUsed+1, 2 + intervalCols * i + 3)).s(10).Weight = 3 (1)#==================================================================================================# 所有列宽度⾃适应# ('a1').expand('table').t()# 所有列宽⽔平居中 -4108 ⽔平居中。 -4131 靠左,-4152 靠右。('a1').expand('table').ntalAlignment = -4108# 保存⼯作簿,若未指定路径,保存在当前⼯作⽬录。()实现效果:⾃动读取学⽣账号⼯作表的姓名,账户和密码,模拟登陆,获取学⽣账户的闯关成绩,接着创建⼀个作业检查的⼯作表,然后把学⽣每天完成四个训练场的编程关卡所得的星数采集到excle⾥,便于每天检查学⽣的每天努⼒情况
发布者:admin,转转请注明出处:http://www.yc00.com/news/1687982970a63576.html
评论列表(0条)