1. 程式人生 > >python刷課指令碼(正方教務系統)

python刷課指令碼(正方教務系統)

#!/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)