爬取教务管理系统成绩

由于在学校期间没有重视学习,回家补了一段时间,想着用爬取本学校的教务管理系统自己的成绩来测试下成果。

完成步骤

  1. 分析网站获取信息

  2. 模拟浏览器进行登录

  3. 筛选数据获取成绩

所用到的库有selenium,time和re

1.分析网站获取信息

        打开我们的教务管理系统:

 然后打开谷歌浏览器的F12开发者模式进行network抓包,随便填入账号密码来查看结果,我们的教务管理系统输入账号密码后是不需要输入验证码的,所以不用进行验证码处理。

在这里我们能够发现,输入了账号和密码之后,会发送出一个名为loginExt.action的post请求,在这个请求中可以查看到我们输入的账号密码,准备使用selenium自动化的方法。

2.模拟浏览器进行登录并分析

使用selenium之前需要先导入整个代码所需要的包:

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
import time
import re

通过selenium来获取Cookie:首先定位表单元素,我们对学号输入框进行右键元素检查获取,得到他们的Xpath路径:

右键再对右边方框中的Xpath进行复制,自动键入预定的数值就是我们的账号密码“username1”和“password1”,使用Keys.ENTER自动按回车登陆成功,附上代码:

web = webdriver.Chrome()
web.get(url)
web.find_element(By.XPATH, '//*[@id="username"]').send_keys('username1')
web.find_element(By.XPATH, '//*[@id="pwd"]').send_keys('password1', Keys.ENTER)

 登陆成功后分析登陆页面:

 不难发现,我的成绩在 "首页" -> "我的" -> 点击"我的成绩"方可得到成绩,于是我们按步骤点进"我的成绩":

web.find_element(By.XPATH, '//*[@id="main-nav"]/ul/li[2]/a').click()
web.find_element(By.XPATH, '//*[@id="main-nav"]/ul/li[2]/ul/li[8]/a').click()

 经过分析页面得到了我们的具体成绩在页面的iframe里面,在这里我首先的想法是切换到嵌套的iframe里面再进行成绩的提取:

web.switch_to.window(web.window_handles[-1])    # 首先将当前页面作为主页面
iframe = web.find_element(By.XPATH, '//*[@id="iframeMain"]')
web.switch_to.frame(iframe)

 但是切换到iframe页面后发现我们又回到了登录后的首页,在登陆后的首页无法找到具体成绩的元素,回过头再对上一步进入"我的成绩"页面进行分析,发现"我的成绩"里面有个href链接,于是点进去发现是一个单独的"我的成绩"页面,这个页面和之前的页面不同的是这个新"我的成绩"页面中使用F12查看具体成绩元素,元素不在嵌套的iframe界面中,那就可以直接提取了,狂喜!上面的切换到iframe也就无用了,在首页"我的成绩"节点下,拿到href链接,接着就是访问该链接,抓取该页面的源代码:

result = a.get_attribute('href')  # 这个链接是成绩的链接 但必须要保持登录状态
web.get(result)
web.switch_to.window(web.window_handles[-1])
# 在新窗口'我的成绩'页面提取内容
time.sleep(3)
S = web.page_source

3.筛选数据获取成绩

解析提取数据的时候也想着使用Xpath来,但失败了,发现这个页面的div属性值是每一次都不断变化的,基于自己的能力只能使用re对内容进行解析提取

obj = re.compile(r'<td class="gridselect">.*?<td>(?P<term>.*?)</td>'
                 r'.*?<td>(?P<course_code>.*?)</td>'
                 r'.*?<td>(?P<course_num>.*?)</td>'
                 r'.*?<td>(?P<course_name>.*?)</td>'
                 r'.*?<td>(?P<course_type>.*?)</td>'
                 r'.*?<td>(?P<course_nature>.*?)</td>'
                 r'.*?<td>(?P<credit>.*?)</td>'
                 r'.*?<td style="">(?P<score>.*?)</td>'
                 r'.*?<td style="">(?P<total_score>.*?)</td>', re.S)
obj2 = obj.finditer(S)
for it in obj2:
    print(it.group("course_name").strip())
    print(it.group("total_score").strip())

得到想要的结果没有截全:

总结:没有进行相应的存储,代码也没有模块化,没有考虑异常情况,不过也算是成功了,这个检验还有些许不完善。后续会进行相应的优化。

  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值