python刷課指令碼(正方教務系統)
阿新 • • 發佈:2018-12-30
#!/usr/bin/env python # coding=utf-8 __metaclass__=type import urllib2 import urllib import time import sys import re reload(sys) sys.setdefaultencoding('utf-8') class Spider: def __init__(self): self.baseUrl='http://222.201.132.117/' self.CheckCodeUrl='CheckCode.aspx' self.PostUrl='default2.aspx' self.Agent='Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/40.0.2214.111 Chrome/40.0.2214.111 Safari/537.36' #開啟debug httpHandler = urllib2.HTTPHandler(debuglevel=0) self.opener = urllib2.build_opener(httpHandler) self.attempt=0 self.setRealUrl() def setRealUrl(self): '獲取真實網站,包含cookie' request = urllib2.Request(self.baseUrl) request.add_header('User-Agent', self.Agent) urlList=self.opener.open(request).geturl().split('/') urlList.pop() self.baseUrl='/'.join(urlList)+'/' def getCheckCode(self): '獲取驗證碼' #設定agent request = urllib2.Request(self.baseUrl+self.CheckCodeUrl) request.add_header('User-Agent', self.Agent) #下載驗證碼 file=self.opener.open(request) pic=file.read() path='code.gif' CheckCode=open(path,'wb') CheckCode.write(pic) CheckCode.close() def setInfo(self): '設定身份資訊' #學號 self.uid=raw_input('輸入學號:') #密碼 self.pwd=raw_input('輸入密碼:') #驗證碼 #self.getCheckCode() #self.code=raw_input('輸入驗證碼:(驗證碼在本軟體所在資料夾)') self.code='' def getPage(self): '登入教務系統,並且獲取網頁' postdata=urllib.urlencode({ '__VIEWSTATE':'dDwyODE2NTM0OTg7Oz5VGnjXV87Z19Dm3QbgRgvcptEYyA==', 'txtUserName':self.uid, 'TextBox2': self.pwd, 'txtSecretCode':self.code, 'RadioButtonList1':self.encodeGBK('學生'),#用gbk編碼 'Button1':'', 'lbLanguage':'', 'hidPdrs':'', 'hidsc':'' }) headers={ 'User-Agent':self.Agent, 'Referer':self.baseUrl } req = urllib2.Request( url = self.baseUrl+self.PostUrl, data = postdata, headers = headers ) try: response = urllib2.urlopen(req) page=response.read().decode('gbk').encode('utf-8')#對gbk編碼的資料進行轉碼 return page except urllib2.URLError, e: self.run() if hasattr(e, 'code'): print 'The server couldn\'t fulfill the request.' print 'Error code: ', e.code elif hasattr(e, 'reason'): print 'We failed to reach a server.' print 'Reason: ', e.reason else: print 'No exception was raised.' # everything is fine def encodeGBK(self,str): '對字串用gbk進行編碼' return str.decode('utf-8').encode('gbk') def getSelect(self): '獲取選課的網址' href=re.findall(r'xf_xsqxxxk.+?N121103',self.getPage()) chinese=self.getChinese(href[0].decode('utf8')) url=re.sub(u"[\u4e00-\u9fa5]+",urllib2.quote(self.encodeGBK(chinese)),href[0].decode('utf8')) return url def getChinese(self,str): '從字串獲取中文' word=re.findall(u"[\u4e00-\u9fa5]+",str) return word[0] def getViewState(self,page): '從網頁中獲取viewstate' return re.search('<input type="hidden" name="__VIEWSTATE" value="(.+?)" />',page).group(1) def getList(self): '獲取全部課程列表' url=self.baseUrl+self.getSelect() request=urllib2.Request(url) request.add_header('User-Agent', self.Agent) request.add_header('Referer', self.baseUrl+'/xs_main.aspx?xh='+self.uid) response = self.opener.open(request) page=response.read().decode('gbk').encode('utf-8')#對gbk編碼的資料進行轉碼 postdata=urllib.urlencode({ '__EVENTTARGET':'dpkcmcGrid:txtPageSize', '__EVENTARGUMENT':'', 'ddl_ywyl':'', '__VIEWSTATE':self.getViewState(page), 'ddl_kcxz':'', 'ddl_kcgs':'', 'ddl_xqbs':'2', 'ddl_sksj':'', 'TextBox1':'', 'dpkcmcGrid:txtChoosePage':'1', 'dpkcmcGrid:txtPageSize':'120' }) headers={ 'User-Agent':self.Agent, 'Referer':url } request = urllib2.Request( url = url, data = postdata, headers = headers ) try: response = self.opener.open(request) page=response.read().decode('gbk').encode('utf-8')#對gbk編碼的資料進行轉碼 return page,url except urllib2.URLError: self.run() def postCourse(self,course,teacher,date): '獲取課程資訊,並且提交' data=self.getList() url=data[1] page=data[0] pat='<tr.+?</tr>' pat_code='<input id=".+?" type="checkbox" name="(.+?)" />' pattern=re.compile(pat,re.S)#開啟dotall模式 codes=re.findall(pattern,page)#找出課程程式碼 code='' flag=1 for c in codes: if course in c and teacher in c and date in c: l=re.findall(pat_code,c) code=l[0] flag=0 break if(flag): print '未找到相應課程,請重新輸入' exit() print code self.submit(code,url,page,date) if(self.checkSelect(course,page,code,url,date)): return True else: return False <span style="white-space:pre"> </span> def submit(self,code,url,page,date): '提交選課表單' postdata=urllib.urlencode({ '__EVENTTARGET':'', '__EVENTARGUMENT':'', 'ddl_ywyl':'', '__VIEWSTATE':self.getViewState(page), 'ddl_kcxz':'', 'ddl_kcgs':'', 'ddl_xqbs':'2', 'ddl_sksj':'', 'TextBox1':'', 'dpkcmcGrid:txtChoosePage':'1', 'dpkcmcGrid:txtPageSize':'120', code:'on', 'Button1':self.encodeGBK(' 提交 '), 'dpDataGrid2:txtChoosePage':'1', 'dpDataGrid2:txtPageSize':'120' }) headers={ 'User-Agent':self.Agent, 'Referer':url } request = urllib2.Request( url = url, data = postdata, headers = headers ) try: response = self.opener.open(request) page=response.read().decode('gbk').encode('utf-8')#對gbk編碼的資料進行轉碼 except urllib2.URLError: self.run(course,teacher,date) def checkSelect(self,course,page,code,url,date): '判斷選課是否成功' pat='<legend>已選課程</legend><table.+?'+course+'.+?</table>' pattern=re.compile(pat,re.S) lenth=len(re.findall(pattern,page)) if(lenth==1): print '選課成功' return False else: time.sleep(1)#等待一秒 self.attempt += 1 print '嘗試選課'+str(self.attempt) self.submit(code,url,page,date) return True def run(self,course,teacher,date): self.setInfo() while(self.postCourse(course,teacher,date)): pass spider=Spider() course=raw_input("輸入課程:") teacher=raw_input("輸入教師:") date=raw_input("輸入週一~週五") spider.run(course,teacher,date)