python 自动化——获取学生提交的作业
python 自动化——获取学生提交的作业
我这学期担任本科的操作系统助教。课程要求所有学生的作业都提交到“网络教学平台上”给助教批改,但学生数量众多,一个一个点击下载压缩包十分麻烦,还容易遗漏。我注意到网站没有批量下载解压的功能,为提高工作效率,想试着使用python来一键完成下载解压。
关于 selenium.webdriver
Selenium 通过使用 webdriver 支持市场上所有主流浏览器的自动化。 Webdriver 是一个 API 和协议,它支持多种语言,有python、java、C#、Ruby、JavaScript等。Webdriver 用于控制 web 浏览器的行为,且每个主流的浏览器都有一个特定的 WebDriver 实现,称为驱动程序。 驱动程序是负责委派给浏览器的组件,并处理与 Selenium 和浏览器之间的通信。
Selenium 框架通过一个面向用户的界面将所有这些部分连接在一起, 该界面支持不同的浏览器后端, 从而实现跨浏览器和跨平台自动化。
安装
可以使用 miniconda :
1 |
|
或者 pip :
1 |
|
然后,根据你使用的浏览器,安装特定于浏览器的 WebDriver 二进制文件:
浏览器 | 维护者 | 支持的版本 |
---|---|---|
Chrome | Chromium | 所有版本 |
Firefox | Mozilla | 54及以上版本 |
Edge | Microsoft | 84及以上版本 |
Internet Explorer | Selenium | 6及以上版本 |
Opera | Opera Chromium / Presto | 10.5及以上版本 |
Safari | Apple | 10及以上版本 |
在模拟用户在浏览器上的选择、点击等操作方面,webdriver包提供了非常多的便利!使用方面,网上有非常多详实的手册,如果你使用python,推荐 selenium-Python 网站。
使用
不详细讨论技术细节,总的来说,有五个步骤:
- webdriver 初始化,获取驱动。Chrome 用
webdriver.Chrome()
- 打开网页链接。
driver.get("http://www.python.org")
- 找到需要的元素。
elem = driver.find_element_by_name("q")
- 对该元素进行操作,例如点击、提交信息等。
elem.send_keys("pycon")
- 等待网页的响应。
driver.implicitly_wait(10)
或者WebDriverWait(driver, 10).until()
整个过程重点是要确定交互的元素,需要在编程前仔细研究网页的 HTML 源码。
自动化
获取作业
首先,获取驱动,打开网站:
1 |
|
因为刚刚打开浏览器会比较慢,因此使用显式等待比较好。下面的代码,对应的操作就是点击“统一身份认证登录”。
1 |
|
随后就会进入科大的统一身份认证系统。同样地,先找到账号密码对应的 input 框的id,然后用 find_element_by_id
查找,将你的账号密码填入即可。
1 |
|
登录后,网站就跳入到了bb页面。要下载所有学生的作业,首先需要点击对应课程“操作系统原理与设计”,进入课程页面后,找到“评分中心”,下拉框中有“需要评分”一栏,点击后会出现已经提交作业的学生名单。
整体步骤依然不变,但为了更快找到对应元素,需要熟练地使用 webdriver 的 API 。不过我觉得,能用 id 或者 text 找,就尽量用 id 或 text 找。没有定义 id 和 text 的,才需要从 class 等入手。
1 |
|
程序进行到这里后,我已经可以看到提交同学的名单了。但需要更进一步,让python能帮我自动下载这些作业,才是我的目的。
先从该页面中,抠出所有提交作业的学生名。注意,find_elements*
的 API ,都是返回一个列表。以下面代码为例,返回了所有 class 为 gradeAttempt
的元素。
1 |
|
然后,点击链接(表格中同学名字的链接背后就是每个人的作业界面)。需要注意的是,下载完一个同学的作业后,还需要点击返回,即 driver.back()
,才能回到上面的页面。循环才能继续,否则会出现程序找不到元素的情况。
1 |
|
解压操作
如此,我十分顺利地拿到了所有同学的作业,程序自动帮我下载到了 ~/下载
目录中。不过,我还想一步到位,除了自动下载,干脆解压的工作也让程序帮我完成了吧 :smile:。下面的代码使用了 python 中最好用也是最常用的包 os 和 re。
一般来说,作业的提交格式都是统一的,这里是“学号_姓名.zip or .rar”,那么相关的正则表达式需要如何描述呢?
1 |
|
大功告成!:happy: