需求分析:本人是带学生参加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 requests
import execjs
import xlwings as xw
import math
import time
import datetime
#==================================
#==所有用到的变量==
#标志作业检查工作表,之前是否存在,存在不写入相关信息,不存在则创建写入相关信息,避免第二次打开的重复写入
作业检查=False
#定义查询几级训练场的参数
leval=["0","10","20","30"]
#间隔写入需要传入的间隔列数
intervalCols=4
#===================================
# 打开Excel程序,默认设置:程序可见,只打开不新建工作薄,屏幕更新打开
app=xw.App(visible=True,add_book=False)
app.display_alerts=False
app.screen_updating= True
#另一种打开工作簿的方法
#workBook= xw.Book('./icode账号.xlsx')
workBook=app.books.open('./icode账号.xlsx')
#得到打开工作的所有工作表
sheets = workBook.sheets
if "作业检查" in str(sheets):print("作业检查工作表存在")作业检查 = True
else:print("作业检查工作表不存在")sheets.add(name="作业检查", after="账号")
print("打开的工作簿的所有工作表:",sheets)
#打开第一张学生账号工作表
sheet1st = workBook.sheets[0]
print("第一张工作表名字:",sheet1st.name)
# 获取工作表的活动区域
rng = sheet1st.range('a1').expand('table')
# 获取活动区域的行数
nrows = rng.rows.count
print("学生账户工作表总行数:",nrows)
# 接着就可以按准确范围读取了
accounts=sheet1st.range(f'c1:c{nrows}').value
pwds = sheet1st.range(f'd1:d{nrows}').value
#print("读取学生账号试验:",str(math.floor(accounts[1])))
print("学生密码:",pwds)
#读取姓名
names=sheet1st.range(f'b1:b{nrows}').value
print("学生姓名:",names)
#-------------------------------------------------
#打开作业检查工作表
sheet2nd=workBook.sheets["作业检查"]
#作业检查工作表自动调整宽度
sheet2nd.autofit()
#之前作业检查工作不存在,证明是第一次打开,则写入基本信息
if 作业检查==False:sheet2nd.range('A1').value="姓名"sheet2nd.range('A2').value="日期"
# 获取第2张工作表的活动区域
rng2nd = sheet2nd.range('a1').expand('table')
# 获取第2张工作表的活动区域的行数
nrows2ndUsed = rng2nd.rows.count
print("作业检查工作表总行数:",nrows2ndUsed )
#获取并写入时间
nowTime = datetime.datetime.now()
sheet2nd.range(nrows2ndUsed+1,1).value=nowTime
#--------------------------------------------------------------------------------
#1实例化一个node对象
node = execjs.get()
#2js源文件编译
ctx = node.compile(open("./icode.js", encoding="utf-8").read())
#----------------------------------------------------------------------------------------------
#创建一个session对象
session = requests.session()
signInUrl = "https://service.icode.org.cn/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": "https://home.icode.org.cn","Referer": "https://home.icode.org.cn/signIn"
}
GameListUrl="https://service.icode.org.cn/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": "https://home.icode.org.cn","Referer": "https://home.icode.org.cn/index"
}
#===================================================================================================for i in range(nrows-1):# 之前作业检查工作不存在,证明是第一次打开,则写入基本信息if 作业检查 == False:#每隔4列写入数据sheet2nd.range(1,2+intervalCols*i).value=names[1+i]#合并姓名单元格# sheet2nd.range((1, 2 + intervalCols * i), (1, 2 + intervalCols * i + 3)).api.merge()#写入四个训练场文字sheet2nd.range(2, 2 + 4 * i).value = ["1级训练场","2级训练场","3级训练场","4级训练场"]#--------------------------------------------------------# 3.执行js函数funcName = 'getPwd("{0}")'.format(pwds[i+1])pwdEncrypted = ctx.eval(funcName)signInData = {#读出的账号数据是类似"13813396052.0"这样的数据所以必须作下处理,取出整数,并转换成字符串"email": str(math.floor(accounts[i+1])),"password": pwdEncrypted}text = session.post(url=signInUrl, headers=signInUrlHeaders, data=signInData).textprint("登陆请求返回的信息:",text)for j in range(4):GameListData = {"mode": "1",# 0是1级训练场,10是2级训练场;20是3级训练场;30是4级训练场"level": leval[j]}GameListJson = session.post(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"])))sheet2nd.range(nrows2ndUsed+1, 2+intervalCols*i + j).value ="{0}/{1}".format(GameListJson["data"]["star"],GameListJson["data"]["totalStar"])# print(”所得星数:“,GameListJson["data"]["star"])# print(”总星数:“,GameListJson["data"]["totalStar"])#---------------------------------------------------------------------------#--取消息上次最后一行数据的下边框--sheet2nd.range((1, 1), (nrows2ndUsed, 1)).api.Borders(9).LineStyle = 0sheet2nd.range((1, 2 + intervalCols * i), (nrows2ndUsed, 2 + intervalCols * i + 3)).api.Borders(9).LineStyle = 0#--------------------------------------------------------------------------------------------------------------------#--第一列边框处理--sheet2nd.range((1, 1), (nrows2ndUsed+1, 1)).api.Borders(7).LineStyle = 1sheet2nd.range((1, 1), (nrows2ndUsed+1, 1)).api.Borders(7).Weight = 3sheet2nd.range((1, 1), (nrows2ndUsed + 1, 1)).api.Borders(8).LineStyle = 1sheet2nd.range((1, 1), (nrows2ndUsed + 1, 1)).api.Borders(8).Weight = 3sheet2nd.range((1, 1), (nrows2ndUsed + 1, 1)).api.Borders(9).LineStyle = 1sheet2nd.range((1, 1), (nrows2ndUsed + 1, 1)).api.Borders(9).Weight = 3#------------------------------------------------------------------------------------------------------------------------------------#--对一个人的四列数据加上边框便于好看--sheet2nd.range((1, 2 + intervalCols * i), (nrows2ndUsed+1, 2 + intervalCols * i + 3)).api.Borders(7).LineStyle = 1sheet2nd.range((1, 2 + intervalCols * i), (nrows2ndUsed+1, 2 + intervalCols * i + 3)).api.Borders(7).Weight = 3sheet2nd.range((1, 2 + intervalCols * i), (nrows2ndUsed+1, 2 + intervalCols * i + 3)).api.Borders(8).LineStyle = 1sheet2nd.range((1, 2 + intervalCols * i), (nrows2ndUsed+1, 2 + intervalCols * i + 3)).api.Borders(8).Weight = 3sheet2nd.range((1, 2 + intervalCols * i), (nrows2ndUsed+1, 2 + intervalCols * i + 3)).api.Borders(9).LineStyle = 1sheet2nd.range((1, 2 + intervalCols * i), (nrows2ndUsed+1, 2 + intervalCols * i + 3)).api.Borders(9).Weight = 3sheet2nd.range((1, 2 + intervalCols * i), (nrows2ndUsed+1, 2 + intervalCols * i + 3)).api.Borders(10).LineStyle = 1sheet2nd.range((1, 2 + intervalCols * i), (nrows2ndUsed+1, 2 + intervalCols * i + 3)).api.Borders(10).Weight = 3time.sleep(1)
#==================================================================================================
# 所有列宽度自适应
# sheet2nd.range('a1').expand('table').columns.autofit()
# 所有列宽水平居中 -4108 水平居中。 -4131 靠左,-4152 靠右。
sheet2nd.range('a1').expand('table').api.HorizontalAlignment = -4108
# 保存工作簿,若未指定路径,保存在当前工作目录。
workBook.save()

实现效果:

自动读取学生账号工作表的姓名,账户和密码,模拟登陆,获取学生账户的闯关成绩,接着创建一个作业检查的工作表,然后把学生每天完成四个训练场的编程关卡所得的星数采集到excle里,便于每天检查学生的每天努力情况

icode青少年编程比赛网站学生刷题进度爬虫相关推荐

  1. 历届蓝桥杯Scratch编程国赛 初级 中级 青少年编程比赛国赛真题解析【持续更新 已更新至27题】

    历届蓝桥杯国赛真题 第十三界.十二届.十一届等历届青少年蓝桥杯Scratch编程比赛国赛真题解析 国赛真题01-河马带球[试看] [蓝桥杯国赛真题01]Scratch河马带球 少儿编程蓝桥杯Scrat ...

  2. 历届蓝桥杯Scratch编程省赛 初级 中级 青少年编程比赛省赛真题解析【持续更新 已更新至35题】

    历届蓝桥杯scratch省赛真题 历年蓝桥杯Scratch编程比赛省赛真题详细解析 省赛真题35-水面倒影 [蓝桥杯省赛真题35]Scratch水面倒影 少儿编程scratch编程蓝桥杯省赛真题讲解_ ...

  3. 《编程能力基础》刷题笔记(41 题)

    <编程能力基础>刷题笔记 1. 单调数列 题解:递归.模拟.API 2. 实现 strStr() 题解:API.暴力.滑动窗口 3. 平衡二叉树 题解:迭代 4. 重复的子字符串 题解:模 ...

  4. LeetCode《编程能力入门》刷题笔记(34 题全)

    LeetCode<编程能力入门>刷题笔记 基本数据类型 1. 在区间范围内统计奇数数目 _解法1:暴力迭代 _解法2:数学(找规律) 2. 去掉最低工资和最高工资后的工资平均值 _解法1: ...

  5. 如何在新版csp网站上刷题

    CCF目前已经推出新版CSP网站,许多小可爱问过我怎么在新版CSP网站上刷题,这篇博客主要说一下如何进入CSP刷题页面. 首先进入新版CSP网址 http://www.cspro.org/ ,如果已有 ...

  6. 数据结构与算法书籍、视频、项目、网站、刷题技巧推荐(2021 年持续更新)...

    今天整理出一些算法相关学习资源,包括书籍.算法刷题网站.项目资源.视频课程.面试要领这5个方面. 首先介绍一下技术书阅读方法论. 一.速读一遍(最好在1~2天内完成) 人的大脑记忆力有限,在一天内快速 ...

  7. 数据结构与算法书籍、视频、项目、网站、刷题技巧推荐(2021 年持续更新)......

    今天整理出一些算法相关学习资源,包括书籍.算法刷题网站.项目资源.视频课程.面试要领这5个方面. 首先介绍一下技术书阅读方法论. 一.速读一遍(最好在1~2天内完成) 人的大脑记忆力有限,在一天内快速 ...

  8. ACM比赛经验、刷题记录及模板库总结(更新中)

    前言 本文所提及的部分题目代码,可以在我的Github上找到 第一部分 经验分享及感受 第二部分 刷题记录 一.基础算法&程序语言 //strlen()函数的复杂度是O(n)要小心 //截取字 ...

  9. Scratch青少年编程能力等级测试模拟题(四级)

    「青少年编程竞赛交流群」已成立(适合6至18周岁的青少年),公众号后台回复[Scratch]或[Python],即可进入.如果加入了之前的社群不需要重复加入. 我们将有关编程题目的教学视频已经发布到抖 ...

  10. Scratch青少年编程能力等级测试模拟题(三级)

    青少年编程竞赛交流群已成立(适合6至18周岁的青少年),公众号后台回复[Scratch]或[Python],即可进入.如果加入了之前的社群不需要重复加入. 微信后台回复"资料下载" ...

最新文章

  1. 饥荒海难机器人怎么用_饥荒:海难是一款野外生存游戏
  2. 2016年秋季个人阅读计划
  3. Android nomedia 避免图片等资源泄露在系统图库其中
  4. [Leetcode] Binary Tree PosterOrder Travel
  5. 读书几年收藏的编程利器网站,给大家分享出来
  6. 基于HTML5手机上下滑动翻页特效
  7. UVA 11584 Partitioning by Palindromes (字符串区间dp)
  8. 笔记 | 《机器学习》中计算学习理论(上)
  9. git解决冲突 merge 不提示_Merge,Rebase,Cherry-Pick 了解一下
  10. 数据:比特币和以太坊的证券产品规模已超过百亿美元
  11. 如何让一个函数返回多个值(C#)
  12. STL容器 之 vector
  13. windows server 2003 远程拨号服务器
  14. 低代码指南100方案:28高效HR如何做好面试管理,提高招聘效率?
  15. 给ESXi虚拟机硬盘瘦身
  16. 了解DPDK——内核NIC接口
  17. uni-app新闻小程序
  18. 制作移动硬盘或U盘的MAC安装盘
  19. C#调用FFMPEG实现桌面录制(视频+音频+生成本地文件)【笔记】
  20. Xshell安装Docker并安装mysql5.7

热门文章

  1. NVivo for Mac中的编码难理解?这6个视频帮助你!
  2. 通信原理及系统系列38——图解过采样和欠采样
  3. Netlink组播机制
  4. Python处理图片缩略图
  5. 几款好用的串口和网络调试助手
  6. 时间序列分析实验报告总结_时间序列分析实验报告
  7. 初学云计算:华为vs阿里vs红帽,如何选择?
  8. 南京大学2020计算机考研分数线,2020南京大学考研复试分数线已公布
  9. 手机APP逆向工具介绍
  10. matlab 带积分的方程,在Matlab中实现积分方程的迭代解