前言
之前写过一篇用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={