用彪悍的Python寫了一個自動選課的指令碼

來源:互聯網
上載者:User

      高手請一笑而過。

      物理實驗課別人已經做過3、4個了,自己一個還沒做呢。不是咱不想做,而是咱不想起那麼早,並且僅有的一次起得早,但是哈工大的伺服器竟然超負荷,不停重新整理還是不行,不禁感慨這才是真正的“萬馬爭過獨木橋“啊!伺服器不給力啊……

       好了,廢話少說。其實,我的想法很簡單。寫一個三重迴圈,不停地提交,直到所有的資料都accepted。其中最關鍵的是提交最後一個頁面,因為提交使用者名稱和密碼後不需要再訪問其他的頁面,因此不需要用到cookis。

       這個只是Python最簡單的應用。核心代碼只有兩行:

       data = urllib.urlencode(each_people)<br />req = urllib2.Request(url , data)
      這裡用到了Python中Web編程中的比較重要的模組urllib和urllib2。其實你也可以用httplib來代替,兩者本質上是一樣的,因為urllib內部的一部分就是用httplib來實現的。

      現解釋一下上面的意思:each_people是一個字典,就相當於C++中的multimap、java中的hashMap,其含義是一個人的選課資訊。urllib.urlencode()函數將each_people的格式轉換一下,以便將其作為CGI請求的URL字串的一部分。關於CGI是什麼大家可以google一下。舉個例子:

      >>>import urllib

      >>>each_people = {'name' : 'Tom'  , 'password' : '12345' , 'class' : 'lab5'}

      >>>data = urllib.urlencode(each_people)

      >>>print data  

      結果是:name=Tom&password=12345&class=lab5

      第二行看字面意思就知道其實什麼意思了。參數url表示你要提交資料的網站。
   那麼怎麼查看其返回結果呢?很簡單:

   response = urllib2.urlopen(req)<br />the_page = response.read()<br />print the_page

 
看到有幾個人問,就把代碼貼出來吧,有注釋:

   #coding=gb2312<br />import urllib<br />import urllib2<br />import re<br />#要提交資料的網站<br />url = 'http://……'<br />#選課人的資訊<br />info_list = [<br /> {'week' : '9', 'expnumber' : '實驗10' , 'weekday' : '2' , 'exp_class' : '3-4' , 'number' : '10000000' , 'password' : '12345678' } ,<br /> {'week' : '9', 'expnumber' : '實驗10' , 'weekday' : '2' , 'exp_class' : '3-4' , 'number' : '20000000' , 'password' : 'abcdefgh' }<br /> ]<br />#對應的選課人的名字,可以不要,我加上這個的原因是做一個log,記住選課結果<br />name_list = [ '張三' , '李四']<br />#記錄對應的是否已經選上,可以用一個 位元代替<br />trace = [ 0 , 0]<br />#主程式,選課<br />def submit():<br /> while True:<br /> whether_over = 1<br /> for i , each_people in enumerate(info_list):<br /> if trace[i] == 0 :<br /> whether_over = 0<br /> for j in range(20):<br /> data = urllib.urlencode(each_people)<br /> req = urllib2.Request(url , data)<br /> try:<br /> response = urllib2.urlopen(req)<br /> except urllib2.URLError , e:<br /> continue<br /> else :<br /> the_page = response.read()<br /> #下面這個路徑可以更改,我用的是我的路徑<br /> #這三句是將返回的網頁寫到檔案中,以方便以後檢索<br /> my_file = open('/home/superior/Documents/WLlog.txt' , 'w+') ;<br /> my_file.write(the_page) ;<br /> my_file.close()</p><p> #將剛才的網頁讀到記憶體中<br /> my_file = open('/home/superior/Documents/WLlog.txt' , 'r') ;<br /> buffer = my_file.read()<br /> my_file.close()<br /> #下面用了Regex模組中的search()方法<br /> m = re.search('課程預約成功', buffer)<br /> #如果找到“課程預約成功”字串了<br /> if m is not None:<br /> result_file = open('/home/superior/Documents/result_log.txt' , 'a+')<br /> #將名字記錄到result_log.txt中<br /> result_file.write(name_list[i] + ' successful/n')<br /> result_file.close()<br /> #將此人從列表中划去<br /> trace[i] = 1<br /> break<br /> #所有人都選上了<br /> if whether_over == 1:<br /> break<br />#定義主函數<br />def main():<br /> submit()<br />#調用主函數<br />main() 

      我認為這個程式效率雖然還不錯,但是我認為還可以再提升一下。主要是開啟檔案,讀寫檔案,關閉檔案這幾個步驟耗時。但是goole擺弄了好久,沒找到更好地辦法。有誰找到更好地辦法,請吱一聲。

 

      另外需要說明的是:

            1.為了不失廣泛性,info_list這個列表中的資訊,是我舉例用的。具體使用的話,只需將info_list和url修改一下

            2.運行此程式需要預先裝上Python,如何安裝google一下就知道了

 

*************************************************************************************************************

      今天(Oct 17)協助15位同學選上了課,心裡很高興,娘的,“勝造七級浮屠”啊!

      看了看log,每秒選上5個同學,感覺效率很低啊!於是又想了一下改進的辦法。

第一點:

      正如前面分析的那樣,主要是開啟、讀取、關閉檔案費時。我看了一下the_page和buffer的類型:相同!

print 'buffer' , type( buffer )<br />print 'the_page' , type( the_page )

結果:

      buffer  <type 'str'>
      the_page  <type 'str'>

因此,果斷的把my_file這個中間檔案給去掉。

第二點:

      為每個人迴圈20遍,這個做法不明智。因為如果當前正在提交的人的資訊根本不可能被accepted,比如學號密碼打錯了,或者選的課程已經滿了(這是極有可能發生的),這時再為此人迴圈20遍,明顯的是在浪費時間,而且影響了後面人的提交。難道這就是傳說中的“佔著茅坑不拉屎”?因此果斷的把最後一個迴圈去掉。

      經過上面的兩點改進,相信效率一定會有極大的提升。

      做了一個final版本,暫且貼上吧。

#coding=gb2312<br />import urllib<br />import urllib2<br />import re<br />import os<br />url = 'http://……'<br />info_list = [<br /> {'week' : '9', 'expnumber' : '實驗10' , 'weekday' : '2' , 'exp_class' : '3-4' , 'number' : '10000000' , 'password' : '12345678' } ,<br /> {'week' : '9', 'expnumber' : '實驗10' , 'weekday' : '2' , 'exp_class' : '3-4' , 'number' : '20000000' , 'password' : 'abcdefgh' }<br /> ]<br />name_list = [ '張三' , '李四' ]<br />trace = [ 0 , 0 ]<br />def submit():<br /> while True:<br /> whether_over = 1<br /> for i , each_people in enumerate( info_list ):<br /> if trace[ i ] == 0 :<br /> whether_over = 0<br /> data = urllib.urlencode( each_people )<br /> req = urllib2.Request( url , data )<br /> try:<br /> response = urllib2.urlopen( req )<br /> except urllib2.URLError:<br /> continue<br /> else :<br /> the_page = response.read()<br /> m = re.search( '課程預約成功', the_page )<br /> if m is not None:<br /> result_file = open( '/home/superior/Documents/result_log.txt' , 'a+' )<br /> result_file.write( name_list[ i ] + ' successful ' + os.popen( 'date' ).read() + '/n' )<br /> result_file.close()<br /> trace[ i ] = 1<br /> if whether_over == 1:<br /> break<br />if __name__ == '__main__':<br /> submit() 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.