EcustAutoPJ|EcustAutoPJ 华理自动评教设计

项目已完成,文章更新完成(2016.06.04 1:52)
源码 OR
git@github.com:maoxs2/EcustAutoPJ.git
【EcustAutoPJ|EcustAutoPJ 华理自动评教设计】点击直接体验
【Success就是成功了orz,懒得写README】
设计缘由

  1. 华理评教太麻烦
  2. 经常忘了评。。。
  3. 师生和睦【大家好才是真的好hhh】
产品构思 自动完成自己的期末评教,且所有浏览器操作都由后台完成
技术分析 Python 的自动处理库够多就它了
步骤一 首先,实现评教需要实现登录,需要用户输入密码,这里就直接用到了Python的sys。
user_info = sys.argv[1].split("x") user_id = user_info[0] user_pw = user_info[1]

这样就实现了用户输入学号和密码【方式不喜勿喷,个人不喜欢“--version”这样的信息录入方式】
然后,我们通过requests来实现用户登录教务处评教网站。
login_url = "http://pjb.ecust.edu.cn/pingce/login.php" p = s.post(login_url, {'action':"login", 'sno':user_id,'password':user_pw}) o = s.get("http://pjb.ecust.edu.cn/pingce/list.php") if o.url != "http://pjb.ecust.edu.cn/pingce/list.php" : print 'Failed' exit() o.encoding = "gbk" txt = o.text.encode("gbk")

其中通过检测是否跳转来判断了是否登录成功。
顺带一提的是教务处GBK编码有点坑……
另:其实此处完全可用后文引入的mechanize来实现。只不过这里的表单提交很简单也目测不会有任何的大变化,所以用requests个人感觉更轻巧舒适。
最后将cookie取出。
步骤二 自动登陆后网站给出一个需要填写各个老师评价表单的网址清单。
这里我们先要把这些网址URL从网页的源代码里解析出来,然后再一一进行访问和模拟提交。
html = etree.HTML(txt) hrefs = html.xpath("//tr[@class='row']/td[@class='subject']/a")

这里就是运用了lxml的xpath【因为个人不太会正则= =,xpath在Chrome和FF都有插件一下就能取到真的很方便】
步骤三 获取所有网址(hrefs)后我们对他们进行一一访问,在访问的同时进行表单提交。
首先分析网址可以发现一共有三种评教:班导师评教、体育评教和普通的任课老师评教。
针对这三种评教的表单设计是不同的。
for href in hrefs: pj_href = "http://pjb.ecust.edu.cn/pingce/" + href.attrib['href'] print pj_href print pj_href.find("typg")ifpj_href.find("typg") > 0 : pj_ty(pj_href) elifpj_href.find("bdspg.php") > 0: pj_bds(pj_href) else: pj_normal(pj_href)

首先我看到的是体育评教(很幸运立即看见最简单的),它表单中各个评价(yp*)都是等价的25分,再加上最后的100,在引入了mechanize后就非常简单了。
引入mechanize:
br = mechanize.Browser() #options br.set_handle_equiv(True) br.set_handle_redirect(True) br.set_handle_referer(True) br.set_handle_robots(False)

体育评教:
def pj_ty(href): response = br.open(href) br.select_form(name="Form1") i=1 for i in xrange(1,5): br["yq" + str(i)] = ["25"] br["yq17"] = ["100"] br.submit() print "OK"

但是在普通评教时却遇到了阻碍——每个分值不同。
为了省力,懒得一个个看到底几分,这里我选择了取出每个选项的value值,然后value自动为最大值。由于这一方法普适,故班导师的也就照搬。
response = br.open(href) br.select_form(name="Form1") html = response.read() HTML_filter = etree.HTML(html) i =1 for i in xrange(1,20): values = HTML_filter.xpath("//input[@name='yq"+str(i)+"']") z = 1 for value in values: if z == 1 : br.form["yq" + str(i)] = [values[0].attrib['value']] else: break br.submit() print "OK"

到这里主程序的结构就完成了。
其他,php为接口,html为用户界面,方便发布用。

    推荐阅读