当前位置: 代码迷 >> 综合 >> 【Python网络爬虫实战篇】关于在青果教务网络管理系统爬取学生成绩的分析及代码展示——以郑州轻工业大学(zzuli)教务网络管理系统为例
  详细解决方案

【Python网络爬虫实战篇】关于在青果教务网络管理系统爬取学生成绩的分析及代码展示——以郑州轻工业大学(zzuli)教务网络管理系统为例

热度:18   发布时间:2024-02-02 16:58:23.0

        关于使用Python爬虫爬取教务网络管理系统的学生成绩,实际上博主在几个月前上课期间就已经写好了。记得当时是因为嫌查成绩麻烦懒得登录网页、恰好又学习了Python爬虫所以萌发了运行代码一键爬成绩的想法(我真是个小机灵鬼x懒是人类进步的根源)。接下来我先记录、分析一下当时爬取教务网络管理系统所遇到的问题,然后展示我所编写的代码。

思路分析

        由于时间间隔较长,我就不再进行详细的爬取分析了。总体上来说,郑州轻工业大学教务网络管理系统使用的是青果教务网络管理系统的模板,只要了解了青果教务网络管理系统的源代码构造后,完成网络爬虫的爬取简直是轻而易举。同样的,不管是哪所高校,只要使用了青果教务网络管理系统,依葫芦画瓢就能进行爬虫的编写。
        因为青果教务网络管理系统作为一家普遍应用于全国各大高校的教务网络管理系统,自然具备着一定的反爬虫能力。所以一般的requests模块爬取还是有一定问题的。因此,这里我们主要使用的是Selenium自动化测试,及在网络爬虫被称之为“可见即可爬”的强大模块。由于时间问题(其实是懒),我就不进行函数封装了(博主在简单的代码编写中习惯先写好代码然后再封装为函数)。接下来,我们来说说分析的主要步骤:

        1.我们想要进入教务网络管理系统页面,自首当其冲的目标是解决登录问题。那么我们打开郑州轻工业大学的教务网络管理系统官网的“开发者工具”进行分析。观察登录模块的整体源代码,可以发现我们要解决的第一个问题:Frame子页面问题。因为账号登录的整个模块是囊括在Frame子页面中,所以直接获取输入框和按钮是获取不到的。这时,我们可以通过以下代码解决:

browser.switch_to.frame('frm_login')   # 进入教务网的子Frame页面

在这里插入图片描述
        2.进入到教务网络管理系统的Frame子页面后,我们就可以直接获取到输入框和按钮了。关于账号和密码的输入,可以通过三种方式:① 直接写死到send_keys里面输入;② input()方法手动输入;③ 通过读取文件输入。这三种方式我都试过,最后是通过读入文件输入的(下列代码演示是通过input()方法输入)。

login = input("请输入账号: ")
password = input("请输入密码: ")
browser.find_element_by_id('txt_asmcdefsddsd').send_keys(login)
browser.find_element_by_id('txt_asmcdefsddsd').send_keys(Keys.TAB)   # TAB键是制表符,输入完账号后按下TAB跳至下一行密码输入框
browser.find_element_by_id('txt_pewerwedsdfsdff').send_keys(password)
browser.find_element_by_id('txt_sdertfgsadscxcadsads').click()   # 点击验证码框使验证码显示出来

        如果需要读入文件输入,这里我使用的是txt文本。文本名称为“账号密码.txt”,文本内格式为账号和密码分别单独占一行。读取账号密码txt文本的代码如下所示:

with open('账号密码.txt', 'r') as file:   # 账号和密码分别为一行user = file.readlines()   # 读取账号密码到列表中login = user[0].strip()   # 账号password = user[1].strip()   # 密码

        3.验证码问题。关于验证码的问题,我使用过python的OCR库进行了灰度化和二值化,但是识别效果很不理想(毕竟验证码的目的就是为了限制爬虫,属于反爬虫的手段之一)。所以,这里我使用Python的PIL库进行页面的整体截图+精细裁剪获取验证码

# 验证码截图获取
image_file = "验证码.png"
screenshot = browser.save_screenshot(image_file)   # 获取屏幕截图,保存成验证码.png
wait = WebDriverWait(browser, 20)   # 显式等待最长20秒
img = wait.until(EC.presence_of_element_located((By.ID, 'txt_sdertfgsadscxcadsads')))   # 定位图片位置
time.sleep(1)
location = img.location
size = img.size
top, bottom, left, right = location['y'], location['y'] + size['height'], location['x'], location['x'] + size['width']
# print("验证码位置:", top, bottom, left, right) # 366 463 236 432
im = Image.open(image_file)
im = im.crop((left+210, top+275, right+206, bottom+280))   # 有头模式验证码位置
# im = im.crop((left+130, top+125, right+90, bottom+130)) # 无头模式验证码位置
im.save(image_file)   # 保存截取后的图片
im.show(image_file)   # 显示图片code = input("请输入识别后的验证码: ")
browser.find_element_by_id('txt_sdertfgsadscxcadsads').send_keys(code)
browser.find_element_by_id('btn_login').click()

        4.输入验证码登录成功后,这里有些细节需要注意了!因为在多次尝试后,我发现在教务网络管理系统登录时如果之前登录的cookies生命周期还未消亡,此时登录会弹出“上次登录已下线”的弹窗。这里,我们通过一个if语句判断、捕获一下可能出现的弹窗问题

# 判断是否出现弹窗,如果出现则进行捕获并点击确认
if browser.switch_to.alert:get_window = browser.switch_to.alert   # 捕获弹窗“您在别处的登录已下线”time.sleep(1)get_window.accept()   # 点击确认按钮
print("登录成功,现在您已到达郑州轻工业大学教务网络页面!")

        5.打开开发者工具中的Network,点击“学生成绩”下的“查看成绩”选项,观察到新增加了Stu_MyScore.aspx,这里我们点击找到Request URL。这样,我们登录后只需请求该url就能够获取网页源代码并进行成绩的爬取。
在这里插入图片描述