pylogin系列之搞定百度統計

概述

這次分析的百度統計登錄接口,算是這幾個中最簡單的了。

但是學到了一個新東西,叫做js模板,搞web的同學應該知道,我這種web半吊子第一次見,非常有意思。

工具:

1. chrome/firefox
2. f12,network
3. python:requests、re

登錄接口

打開百度統計首頁https://tongji.baidu.com/web/welcome/login,點開登錄框,f12。嘗試輸入之後,查看發送的數據。

Request URL:https://cas.baidu.com/?action=login
Request Method:POST
Status Code:200 OK

appscope[]:6
appscope[]:7
appscope[]:12
appid:12
entered_login:anhkgg //名字
entered_password:1111111111111111 //密碼
entered_imagecode:9mxm //驗證碼
charset:utf-8
fromu:https://tongji.baidu.com/web/welcome/loginback
selfu:https://tongji.baidu.com/web/welcome/login
senderr:1

除了上面註釋的需要輸入的三個字段,其他字段意義都不明確,偷點懶,多次嘗試後發現其他字段不會變化,那麼就用固定值了。

點擊驗證碼,看到網絡,拿到獲取驗證碼的請求,key使用10位時間戳。

GET https://cas.baidu.com/?action=image&key=1503151305

所以登錄接口就出來了,vcode需要人工輸入。

url = 'https://cas.baidu.com/?action=image&key=' + time_stamp(10)
r = self.s.get(url)

payload = {
    'appscope[]':6,
    'appscope[]':7,
    'appscope[]':12,
    'appid':12,
    'entered_login':name,
    'entered_password':pwd,
    'entered_imagecode':vcode,
    'charset':'utf-8',
    'fromu':'https://tongji.baidu.com/web/welcome/loginback',
    'selfu':'https://tongji.baidu.com/web/welcome/login',
    'senderr':1,
    }        
url = 'https://cas.baidu.com/?action=login'
r = self.s.post(url, data = payload)

接着看看登錄返回狀態,如果失敗了,返回數據中包含如下數據:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta http-equiv="ReFresh" content="0; url=https://tongji.baidu.com/web/welcome/login?fromu=https%3A%2F%2Ftongji.baidu.com%2Fweb%2Fwelcome%2Floginback&e=%E7%94%A8%E6%88%B7%E5%90%8D%E5%AF%86%E7%A0%81%E9%94%99%E8%AF%AF&un=anhkgg&aid=12&errno=132" />
<title>正在處理...</title>
</head>
<body>
    <script>                
    var url="https://tongji.baidu.com/web/welcome/login?fromu=https%3A%2F%2Ftongji.baidu.com%2Fweb%2Fwelcome%2Floginback&e=%E7%94%A8%E6%88%B7%E5%90%8D%E5%AF%86%E7%A0%81%E9%94%99%E8%AF%AF&un=anhkgg&aid=12&errno=132";
    location.href=url;
    </script>

</body>
</html>

然後瀏覽器加載該url,顯示錯誤提示信息

Request URL:https://tongji.baidu.com/web/welcome/login?fromu=https%3A%2F%2Ftongji.baidu.com%2Fweb%2Fwelcome%2Floginback&e=%E7%94%A8%E6%88%B7%E5%90%8D%E5%AF%86%E7%A0%81%E9%94%99%E8%AF%AF&un=anhkgg&aid=12&errno=132
Request Method:GET

fromu:https://tongji.baidu.com/web/welcome/loginback
e:用戶名密碼錯誤
un:anhkgg
aid:12
errno:132

其中e是錯誤提示信息,errno是錯誤號。

登錄成功返回數據如下,沒有e錯誤信息。

<script>                
var url="http://cas.baidu.com/?action=check&appid=12&u=https%3A%2F%2Ftongji.baidu.com%2Fweb%2Fwelcome%2Floginback%3Fcastk%3Dc4086gh7e82166251d451&fromLogin=1";
location.href=url;
</script>

那麼就可以先通過正則拿到url,通過搜索url是否有e判斷是否登錄成功,並且拿到提示信息。成功則繼續訪問該url跳轉到成功頁面,獲取其他需要的信息。

pattern = re.compile(r'var url="(.*?)";')
cont = re.search(pattern, r.content)
url = cont.group(1)
pattern = re.compile(r'e=(.*?)&un=')
cont = re.search(pattern, url)
if cont != None:
    r = urllib.unquote(cont.group(1)) #失敗
    return utf2gbk(r)        

r = self.s.get(url) # 成功

js模板

這裏比較意思的是使用的js模板來生成登錄表單。

具體js模板使用看這裏

<script id="LoginTemplate" type="text/template">

    <div id="LoginContainer" class="login-dialog">
        <div id="TopTmp">&nbsp;</div>

        if (this.isIco == 1) {
        <div id="LoginMain" class="ico-login clearfix">
            <div class="visitor-login-tab" id="LoginTab">請輸入查看密碼</div>
            <div id="LoginInput" class="login-input">
                if (this.errMsg) {
                <div id="ErrorTip" class="error">#{this.errMsg}</div>
                }
                ...
            </div>
        </div>
        }
        else {
        <div id="LoginMain" class="login-main">

                <form method="post" action="#{this.loginAction}">
                    <input type="hidden" value="12" id="Appid" name="appid">
                    ...
                    <input type="hidden" value="#{this.selfUrl}" name="selfu" />
                    <input type="hidden" value="1" name="senderr" />
                </form>
            </div>
        </div>
        }
    </div>
    <div class="dialog-bottom-bg"></div>
</script>

從上面代碼中可以看到,某些標籤的值使用了#{this.xxx}這樣的語法,不是直接填入的具體內容,更加靈活,擴展更容易。

然後在點擊登錄按鈕之後,通過函數格式化一個全局定義的變量來生成的登錄表單。具體如下:

//全局數據,用於替換表單中的this.xxx
<script type="text/javascript">
VAR = {
    webMasterRegister: "https://tongji.baidu.com/web/register",
    customRegister: "https://u.baidu.com/ucweb/?module=Reguser&controller=reg&action=index&appid=3",
    union_forget: "http://union.baidu.com/findPassword!input.action",
    shifen_forget: "https://aq.baidu.com/new/#/findpwd",
    uc_forget: "https://aq.baidu.com/new/#/findpwd",
    waiting_img_src: "/web/img/loadingImage.gif",
    app_id: "0",
    errMsg: "",
    loginUrl: "/web/welcome/login",
    loginAction: "https://cas.baidu.com/?action=login",
    userName: "",
    authCode: "https://cas.baidu.com/?action=image&key=1503151305",
    registerUrl: "/web/register",
    fromUrl: "https://tongji.baidu.com/web/welcome/loginback",
    selfUrl: "https://tongji.baidu.com/web/welcome/login",
    isIco: "0",
    webmasterUserNum: "2097176",
    customerUserNum: "2270927",
    mtjUserNum: "2262130"
};
</script>

然後在login.js中,通過下面的函數來初始化表單,並且顯示。

其中n.format("LoginTemplate", VAR)用於格式化VAR定義的數據到表單的數據中。

, h = function() {
    var e = t(".login-trigger").eq(0);
    e.on("click", function() {
        s || (s = new i({
            width: 345,
            isModal: !0,
            titleText: "",
            isSingle: !0,
            content: n.format("LoginTemplate", VAR) //初始化登錄表單數據
        }),
        loginController.init()),
        s.show()
    });

而在format具體如何替換的,就隨意實現了,這裏就不在具體分析,有興趣跟着分析的同學可以去看看common.js中的代碼。

總結

百度統計接口非常簡單,密碼未做變換,使用https。

登錄之後具體做什麼也不在分析。

預告下次做百度主站的登錄分析,簡單看了下,非常…複雜!

安利一下公衆號:漢客兒

這裏寫圖片描述

轉載請註明出處,博客原文:https://anhkgg.github.io/pylogin-baidutongji-login-analyze/

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章