使用Selenium自动化选课

学校换了新的选课系统,听网络中心那边的老师说,新的选课系统花了100w RMB。这钱花的还挺值。

  • 新的选课策略 1. 第一轮选课:任意选,后台随机分配
  1. 第二轮第三轮:抢课
  • 性能的优化
  • 界面还算简约美观

吐槽一下:第一轮系统随机分配的思路挺好的,问题在于算法还是有待优化。有的同学才中了一两门,有的同学必修都没中。

回到正题

由于采用了新的选课策略,第一轮抢课的行为就不存在了,抢课只能在第二轮进行,并且对于热门的课程,只能等别人退了捡漏。
思路就是利用软件提交request自动化选课。

利用request库?

首先我想到的是利用request库重复发送选课操作request请求。但是发现选课操作并没有发送form表单,选课系统采用的是json通信来完成操作。

利用chrome浏览器的控制台拦截选课操作的xhr:add-request,返回一个hash值,这个hash值是下一个add-drop-response的参数
如下:

<code class="json">{id: "53350de8-ef74-11e7-bd8f-005056830e1c", requestId: "53397aa9-ef74-11e7-8365-0050568331e4",…}
errorMessage
:
{textZh: "教学班人数已满", textEn: "Lesson is full", text: "教学班人数已满"}
exception
:
null
id
:
"53350de8-ef74-11e7-bd8f-005056830e1c"
requestId
:
"53397aa9-ef74-11e7-8365-0050568331e4"
success
:
false

其中id应该表示我的账户id,requestId表示目标课程id
发现id是变化的。
查看js执行记录,存在make dirty函数改变id

<code class="shell">[Cache]Make dirty: cs-selectedLessons-78282-163
[Cache]Hit: cs-suitableAddableLessons-78282-163

这时候突然想到了,可以使用selenium模拟浏览器应该更简单。

selenium

第一次接触selenium,基本是边查边写的代码。不过还算简单。

Selenium automates browsers. That’s it! What you do with that power is entirely up to you. Primarily, it is for automating web applications for testing purposes, but is certainly not limited to just that. Boring web-based administration tasks can (and should!) be automated as well.

先贴代码git

https://bitbucket.org/peacefullion/choose_lesson

为了便于debug,这里使用的ChromeDriver。
这次selenium使用的大致流程如下:

  • 载入WebDriver(常用的有Chrome、PhantomJs,PhantomJs无界面)
  • 打开网页
  • 使用find_element方法查询页面组件 - xpath
  • css select
  • 使用click方法点击页面

有几个坑单独列一下:

  1. 打开新的页面,或者当前页面有frame需要使用switch_to.window方法来切换焦点,才能找到焦点内的element
  2. 由于提示框采用的是div show hidden的方式来控制显示,所以可以execute_script(‘$(arguments[0]).click()’, select)直接执行对应按钮的js脚本