关于使用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