前言

之前写过一篇用webdriver爬取教务系统课表的爬虫,用的是selenium自动化的无头浏览器模拟登录,今天带来的是用requests请求实现的爬虫。

工具

requests库实现对网页的请求,execjs库实现是js脚本的执行,bs4对爬取的数据进行清洗,csv库实现对数据的储存。

步骤

①首先是登录获取会话(session)


先在输入框乱输入,按F12,登录获取登录页面的表单信息格式


发现是POST请求,表单为加密过的,此时查看页面源代码,检查是如何加密的

再往下看到js,发现是根据encodeInp()进行加密的

再次检查页面源代码并没有发现此函数,那就只能是存在JS文件里面的


虽然后来发现是Base64加密方式,但是没关系了,用python的execjs来执行加密,记得将conwork.js下载下来放在跟python文件的同个目录
request请求后获取会话,准备到目的网页进行数据爬取

    def get_js(self, msg):  # python 调用JS加密 返回 加密后的结果with open('conwork.js', encoding='utf-8') as f:js = execjs.compile(f.read())return js.call('encodeInp', msg)def login_requests(self):user = '账号'pwd = '密码'csv_file_path = r'E://py//个人学期课程表.csv'encode = str(self.get_js(user)) + "%%%" + str(self.get_js(pwd)) + "="  # 获得加密后的东西form_data = {'encoded': encode}r_session = requests.session()r_session.post(self.login_url, headers=self.header, data=form_data)return r_session

②爬取数据

直接来到网页显示的课表页面,将此时的URL复制下来
又发现课表有多选框,所以为了数据准确性,需要进行post数据

周次的数据选择全部,也就是0

学期按时间,本次选择2019-2020-2

放大也选择是

请求的数据如下

        post_data = {'zc': '0', #周次选择全部'xnxq01id': '2019-2020-2', #学期'sfFd': '1' #放大}

根据登录的会话进行再次请求

post_data = {'zc': '0',  # 周次选择全部'xnxq01id': '2019-2020-2',  # 学期'sfFd': '1'  # 放大}response = r_session.get(self.score_url, headers=self.header,data=post_data)

③数据清洗


使用beautifulsoup进行数据筛选,弄出符合csv的二维列表格式

        soup = BeautifulSoup(response.text, 'lxml')page = soup.find_all('div', attrs={'class': "kbcontent"})teachers1, teachers2 = [], []weeks1, weeks2 = [], []classrooms1, classrooms2 = [], []for i in page:teachers1.append(i.find('font', attrs={'title': '老师'}))weeks1.append(i.find('font', attrs={'title': '周次(节次)'}))classrooms1.append(i.find('font', attrs={'title': '教室'}))my_detail = list(page)for i in teachers1:if i == None:teachers2.append('\n')else:teachers2.append(i.string)for i in weeks1:if i == None:weeks2.append('\n')else:weeks2.append('\n' + i.string)for i in classrooms1:if i == None:classrooms2.append('\n')else:classrooms2.append('\n' + i.string)all_data = []pitch_number = ['(上午)\n第1,2节\n(08:00-08:45)\n(08:55-09:40)', '(上午)\n第3,4节\n(10:00-10:45)\n(10:55-11:40)','(下午)\n第5,6节\n(14:30-15:15)\n(15:25-16:10)', '(下午)\n第7,8节\n(16:20-16:05)\n(17:15-18:00)','(晚上)\n第9,10节\n(19:30-20:15)\n(20:25-21:10)', '第11,12节', '第13,14节']temp = []temp.append(pitch_number[0])num = 0pnum = 0for i in range(len(my_detail)):if my_detail[i].text == '\xa0':temp.append('\n\n\n')else:temp.append(my_detail[i].text.split(teachers2[i])[0] + '\n' + teachers2[i] + weeks2[i] + classrooms2[i])num = num + 1if num == 7:all_data.append(temp)temp = []pnum = pnum + 1temp.append(pitch_number[pnum])num = 0page2 = soup.find('td', attrs={'colspan': "7"})BZ = ['备注:' + page2.text, '\n', '\n', '\n', '\n', '\n', '\n', '\n']all_data.append(BZ)

④生成csv文件(可用excel打开)

     f = open(self.csv_file_path, 'w', newline='')csv_write = csv.writer(f)csv_write.writerow(['课程时间', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六', '星期日'])for i in range(len(all_data)):csv_write.writerow(all_data[i])f.close()

最后附上所有代码

工程代码如下

import csv
import requests
import execjs
from bs4 import BeautifulSoupclass SpiderOfTimetable:login_url = 'http://jwgln.zsc.edu.cn/jsxsd/xk/LoginToXk'score_url = 'http://jwgln.zsc.edu.cn/jsxsd/xskb/xskb_list.do'header = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) ''Chrome/75.0.3770.100 Safari/537.36','Host': 'jwgln.zsc.edu.cn','Referer': 'http://jwgln.zsc.edu.cn/jsxsd/'}user = '账号'pwd = '密码'csv_file_path = r'C://个人学期课程表.csv' #生成文件的位置def get_js(self, msg):  # python 调用JS加密 返回 加密后的结果with open('conwork.js', encoding='utf-8') as f:js = execjs.compile(f.read())return js.call('encodeInp', msg)def login_requests(self):encode = str(self.get_js(self.user)) + "%%%" + str(self.get_js(self.pwd)) + "="  # 获得加密后的东西form_data = {'encoded': encode}r_session = requests.session()r_session.post(self.login_url, headers=self.header, data=form_data)return r_sessiondef parse_page(self,r_session):post_data = {'zc': '0',  # 周次选择全部'xnxq01id': '2019-2020-2',  # 学期'sfFd': '1'  # 放大}response = r_session.get(self.score_url, headers=self.header,data=post_data)soup = BeautifulSoup(response.text, 'lxml')page = soup.find_all('div', attrs={'class': "kbcontent"})teachers1, teachers2 = [], []weeks1, weeks2 = [], []classrooms1, classrooms2 = [], []for i in page:teachers1.append(i.find('font', attrs={'title': '老师'}))weeks1.append(i.find('font', attrs={'title': '周次(节次)'}))classrooms1.append(i.find('font', attrs={'title': '教室'}))my_detail = list(page)for i in teachers1:if i == None:teachers2.append('\n')else:teachers2.append(i.string)for i in weeks1:if i == None:weeks2.append('\n')else:weeks2.append('\n' + i.string)for i in classrooms1:if i == None:classrooms2.append('\n')else:classrooms2.append('\n' + i.string)all_data = []pitch_number = ['(上午)\n第1,2节\n(08:00-08:45)\n(08:55-09:40)', '(上午)\n第3,4节\n(10:00-10:45)\n(10:55-11:40)','(下午)\n第5,6节\n(14:30-15:15)\n(15:25-16:10)', '(下午)\n第7,8节\n(16:20-16:05)\n(17:15-18:00)','(晚上)\n第9,10节\n(19:30-20:15)\n(20:25-21:10)', '第11,12节', '第13,14节']temp = []temp.append(pitch_number[0])num = 0pnum = 0for i in range(len(my_detail)):if my_detail[i].text == '\xa0':temp.append('\n\n\n')else:temp.append(my_detail[i].text.split(teachers2[i])[0] + '\n' + teachers2[i] + weeks2[i] + classrooms2[i])num = num + 1if num == 7:all_data.append(temp)temp = []pnum = pnum + 1temp.append(pitch_number[pnum])num = 0page2 = soup.find('td', attrs={'colspan': "7"})BZ = ['备注:' + page2.text, '\n', '\n', '\n', '\n', '\n', '\n', '\n']all_data.append(BZ)f = open(self.csv_file_path, 'w', newline='')csv_write = csv.writer(f)csv_write.writerow(['课程时间', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六', '星期日'])for i in range(len(all_data)):csv_write.writerow(all_data[i])f.close()if __name__ == '__main__':spider = SpiderOfTimetable()session = spider.login_requests()spider.parse_page(session)

conwork.js文件代码

eval(function(p,a,c,k,e,d){e=function(c){return(c<a?"":e(parseInt(c/a)))+((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--)d[e(c)]=k[c]||e(c);k=[function(e){return d[e]}];e=function(){return'\\w+'};c=1;};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p;}('b 9="o+/=";p q(a){b e="";b 8,5,7="";b f,g,c,1="";b i=0;m{8=a.h(i++);5=a.h(i++);7=a.h(i++);f=8>>2;g=((8&3)<<4)|(5>>4);c=((5&s)<<2)|(7>>6);1=7&t;k(j(5)){c=1=l}v k(j(7)){1=l}e=e+9.d(f)+9.d(g)+9.d(c)+9.d(1);8=5=7="";f=g=c=1=""}u(i<a.n);r e}',32,32,'|enc4||||chr2||chr3|chr1|keyStr|input|var|enc3|charAt|output|enc1|enc2|charCodeAt||isNaN|if|64|do|length|ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789|function|encodeInp|return|15|63|while|else'.split('|'),0,{}))

工程目录格式

python3强智教务系统个人课表爬虫相关推荐

  1. 强智教务系统——获取课表

    两个接口: 获取个人信息以及登录成功后header中的token: http://jwxt.xxx.edu.cn/app.do?method=authUser&xh={$学号}&pwd ...

  2. 强智教务系统API学习进度条--(以完结)

    前言 想写一个基于微信公众号的课表及成绩查询系统,记录学习过程与实现. 开发环境 IDEA JDK1.8 强智教务系统API文档 API目录 登录 (以实现) 时间信息 (以实现) 课程信息 成绩信息 ...

  3. 每日获取强智教务系统课表,并发送短信到学生手机!爬虫真牛逼!

    自从学校换了强智的教务系统后,学校的app的查课表功能基本就报废了,记不住课表的我无奈自己动手. 功能实现:如果当天有课,在当天早上6点30以短信的形式自动发送课表至手机 首先我想的是利用模拟登陆然后 ...

  4. python3 + selenium 进行强智教务成绩的刷新以及通知成绩(华东理工大学 某ecust)

    强智教务自动刷新教务处成绩,更新后发邮件通知,以某ECUST华理为例子.此处的ECUST华理教务系统是18年9月后的新系统 Windows端或者挂在阿里云上都可以,下文示例是在Ubuntu上运行的. ...

  5. Java--使用httpClient模拟登陆正方教务系统获取课表

    最近形如课程格子与超表课程表应用如雨后春笋般涌现,他们自动获取课程表是怎么实现的呢.于是我用Java实现了一下模拟登陆正方教务系统获取课表的过程. 首先,我们先了解一下网站登录的原理:当我们输入学号, ...

  6. 中南大学python考试_中南大学教务系统学生成绩爬虫【图】

    中南大学教务系统学生成绩爬虫[图] 08-20栏目:技术 TAG:中南大学教务管理 中南大学教务管理系统 写本博客的原因 其实这个项目很早前我就做完了,当时由于·时间仓促,仅在csdn上传了打包后的程 ...

  7. python3爬取教务系统的个人学期课程表(无头谷歌浏览模拟登录)

    前言 今天带来的是与上次爬取教务系统获取成绩单的姐妹版--爬取教务个人的学期课程表. 工具 使用pycharm编辑器,安装selenium库,beautifulsoup库,csv库,当然需要下载对应的 ...

  8. 中南大学python程序设计实践_「中南大学教务管理系统」中南大学教务系统学生成绩爬虫 - seo实验室...

    中南大学教务管理系统 写本博客的原因 其实这个项目很早前我就做完了,当时由于·时间仓促,仅在csdn上传了打包后的程序:点击下载,没想到陆陆续续有校友找到了我,这让我受宠若惊,恰巧暑假放假在家,我觉得 ...

  9. python3爬取教务系统_python requests模拟登陆正方教务管理系统,并爬取成绩

    最近模拟带账号登陆,查看了一些他人的博客,发现正方教务已经更新了,所以只能自己探索了. 登陆: 通过抓包,发现需要提交的值 需要值lt,这是个啥,其实他在访问登陆页面时就产生了 session=req ...

  10. python3 + selenium 强智教务 抢课脚本 #当然是捡漏(是真的劳火(华东理工大学 某ecust(暂时只能抢跨专业、跨年级、公选))

    需提前装好chrome浏览器,python3,selenium等库,以及chromedriver,详细教程请自行百度!! 代码 # -*- coding: utf-8 -*-from selenium ...

最新文章

  1. PAT甲级1017 Queueing at Bank:[C++题解]字符串、结构体、最小堆
  2. c语言函数的三种调用方式是什么?
  3. 在PLSQL中编译复杂的java(转)
  4. Oracle11g最佳培训高清下载版(王二暖Oracle11g教室\10年经验毫无保留)
  5. Python练习5-正则表达式
  6. 天天生鲜项目页面——商品列表页
  7. cenos回到linux桌面快捷键,CentOS 常用命令及快捷键整理
  8. win10卸载程序灾难性故障_win10新建文件夹出现0X8000FFFF:灾难性故障的错误提示解决方法...
  9. 学校开展计算机培训活动,我校举办学生高级领导力专题培训活动
  10. 知识点:vs2017 git 操作重置、还原、挑拣对比
  11. 用批处理调用Rundll32添加打印机命令说明文件
  12. ANS.1的基础总结
  13. CF1428 G1,G2 . Lucky Numbers题解
  14. 标定学习笔记(二)-- 张正友论文学习笔记
  15. JPA、Hibernate和Spring Data JPA区别
  16. SAR舰船数据集----SSDD
  17. win7+VS2008 System.Runtime.InteropServices.COMException
  18. android热补丁原理完bb霜,answered
  19. 数云荣登乌镇互联网大会2016中国大数据创新企业50强
  20. pptp-client连接设置

热门文章

  1. 计算性和复杂度理论2
  2. linux堆栈有什么作用,嵌入式世界里,堆栈的作用和意义
  3. 从头到尾彻底解析Hash 表算法
  4. 云函数隐匿C2服务器
  5. 【18】微信小程序:05-WePY简介、WePY的安装与运行、WePY文件介绍、WePY框架开发规范与使用
  6. linux c 获取文件大小
  7. bootstrap登录模板
  8. 软件工程第三章节结构化方法
  9. STM32F7--->FMC(可变存储控制器) Flexible Memory Controller
  10. aardio - 时钟例程