项目已完成,文章更新完成(2016.06.04 1:52)
源码
OR
git@github.com:maoxs2/EcustAutoPJ.git
点击直接体验
【Success就是成功了orz,懒得写README】
设计缘由
- 华理评教太麻烦
- 经常忘了评。。。
- 师生和睦【大家好才是真的好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")
if pj_href.find("typg") > 0 :
pj_ty(pj_href)
elif pj_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为用户界面,方便发布用。
网友评论