国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

超詳細的Python實現百度云盤模擬登陸(模擬登陸進階)

CarterLi / 3407人閱讀

摘要:方法不僅適用于百度云,別的一些比較難以模擬登陸的網站都可以按照這種方式分析。本文要求讀者具有模擬登陸主要是抓包和閱讀代碼和密碼學的基本知識。和模擬登陸微博的分析流程一樣,我們首先要做的是以正常人的流程完整的登錄一遍百度網盤。

這是第二篇從簡書搬運過來的文章(大家別誤會,是我原創的)。因為前一篇文章,我看反響還挺好的,所以把這篇也搬運過來了,其實目的還是為宣傳自己的分布式微博爬蟲(該項目的內容和工作量都很飽滿啊,大家如果覺得有幫助,請多多支持啊)。大概從下一篇起,就會一步一步講解如何構建分布式爬蟲再到微博分布式爬蟲的方法了。因為關于初級爬蟲的文章太泛濫了,所以我就不會講比較基礎的東西。


今天我給大家講講如何模擬登陸百度云盤(該分析過程也適用于百度別的產品,比如模擬登陸百度搜索首頁,它們的加密流程完全一樣,只是提交參數有微小差別)。方法不僅適用于百度云,別的一些比較難以模擬登陸的網站都可以按照這種方式分析。

閱讀文章之前,有一些東西需要給大家闡述:

本文并沒有對驗證碼識別進行分析,因為我覺得寫爬蟲最主要的不是識別驗證碼,而是如何規避驗證碼,我自己寫的分布式微博爬蟲也是一直想著規避驗證碼,而不是去識別它,因為我覺得那并不是爬蟲該做的事情(至少不是中低階爬蟲的事,我覺得那是模式識別的事情了)。

本文要求讀者具有模擬登陸(主要是抓包和閱讀js代碼)和密碼學的基本知識。

和模擬登陸微博的分析流程一樣,我們首先要做的是以正常人的流程完整的登錄一遍百度網盤。在打開瀏覽器之前,先打開抓包工具,以前我在win平臺用的是fiddler,現在由于電腦是mac系統,所以選擇charles進行抓包。如果有同學沒有charles的使用經驗,那么需要先了解如何讓charles能抓取到本機的https數據包。由于使用charles抓包不是本文的重點,所以我就簡略說一下:

安裝charles證書。通過菜單"help"->"ssl proxying"->"install charles root certificate"進行安裝,安裝過后把證書設置為始終信任

修改charles的proxy settings。 選擇proxy->proxy settings,然后勾選“enable transparent HTTP proxying”

修改Charles的SSL proxy settings。選擇proxy->ssl proxy settings,在彈出的對話框中勾選"enable ssl proxying",并在location部分點擊add,添加需要捕獲的站點和443端口,如圖:

charles設置好了之后,我們再使用瀏覽器直接打開百度網盤首頁 。注意打開之前如果以前登錄過百度網盤,一定要先清除百度網盤的cookie,如果不清楚自己以前登錄過沒,那么最好把關于百度的cookie都清除了吧。如果清除得不徹底,很可能會錯過很關鍵的一步,我先按下不表。通過抓包,我們可以看到請求百度網盤的首頁,大概有這些請求:

這里other hosts是本機別的請求,所以直接被我忽略了(通過設置請求為“focus”或者“ignore”)。下圖給的是設置方法,主要是FocusDisable SSL Proxying

大家可以查看具體每個請求的內容和響應,由于篇幅限制,我就不啰嗦了。然后我們在登錄頁輸入登錄賬號(先別輸入密碼和點擊登錄,如果有想不明白的同學可以閱讀我的微博登陸分析),然后觀察charles的請求,會發現又多了一條請求:

我們看看它返回的內容:

可以看到有效信息大概有兩個: pubkeykey,它們的用途我們都還不知道,但是看命名可知大概pubkey是某種加密算法的公鑰。

然后我們輸入密碼,點擊登錄,可以看到charles的請求:

上圖圈出來的請求就是提交的密碼和登錄賬號等信息,這個只有大家自己挨著請求查看,才可以確定哪個是post的請求。我們查看post的參數:

現在終于Get到重點了,主要就是要把這些提交的參數的生成方式弄清楚。如果有過模擬登陸或者爬蟲編寫經驗的同學,都應該知道請求參數構造之前必須分析清楚哪些參數是變的,哪些參數是不變的,變的哪些參數比較有規律,哪些沒有規律。這個分析過程是通過反復登錄和抓包,對比post數據來完成的。我們通過反復登錄和對比post的數據,可以發現:

staticpage、charset、 tpl、 subpro、apiver、codestring、 safeflg、u、 isPhone、detect、quick_user、logintype、logLoginType、idc、loginmerge、foreignusername、username、mem_pass、crypttype、countrycode、dv

等參數不會變化。所以我們只需要分析變化的參數。

變化的參數當中,tt看樣子基本可以確定是請求時間戳(需要分析它是多少位,精確到毫秒還是秒),其它好像都沒什么規律。由于微博模擬登陸的經驗,我們基本可以判斷出password這個參數是最難分析的(從賬戶安全角度上來說也應該是加密最復雜的),我們放到后面分析。

那么我們先來分析token字段吧。參數不可能憑空產生,來源只有兩種可能:一種是通過服務端返回, 另外一種是通過請求回來的js構造。在分析token產生的時候,我們需要用到charles的查找功能(良心推薦,很強大),它可以查找到整個登錄流程中,包含某個查找字符串的所有請求和響應。下圖中的"望遠鏡"圖標就是查找功能。

通過查找,我們可以看到有14個地方包含了token的值,我們發現基本都是使用token作為請求參數的,不過有一個結果是返回token值的:

它的請求url是

https://passport.baidu.com/v2...

請求參數格式化一下,可能更方便查看:

根據上面介紹的分析變量與不變量的思路,這里我們可以看到要獲取到token,需要知道gidcallback的構造方法。然后用和分析token同樣的方式,我們來分析gid的產生。通過在charles中查找gid的值,我們發現找到的結果全是在請求中,并沒有在響應中找到該值,說明該值是通過js生成的而不是通過服務端返回的。既然是通過js生成的,我們需要找到該js文件。怎么找呢?我們在charles中輸入gid,再來看看查找的結果,注意這次我們重點關注哪個js文件中出現gid,否則查找的結果太多,看起來會比較費力。通過查找,可以看到名為login_tangram_c36ce25.js這個文件中頻繁出現了*gid這個參數,基本可以確定這個js文件很關鍵,這也是我先前說的在抓包分析之前需要把百度的cookie等歷史數據清除的原因,否則該js文件可能已經緩存了,charles中就查不到該js。我們把該js文件下載下來,通過webstorm將其中的代碼格式化,再查找gid,可以看到這段代碼

其中的this.guideRandom函數就是生成gid的函數,因為我們在webstorm中查找gid字符串的時候,可以發現很多如下圖所示的語句,只需要定位到guideRandom即可

我們現在找到了gid的生成方式了,如果讀不懂這段js也沒關系,可以直接使用pyv8或者pyexecjs等庫將運行后的js結果返回給python使用。然后我們再回到獲取token的請求參數那張圖,發現還有個callback參數需要分析。同gid分析過程一樣,我們先搜索callback的值bd__cbs__v2xmbc,發現只有請求中包含,基本可以確定它是通過js產生的,而加密js文件我們已經找到了。如果你害怕可能不是上面的那個js文件,我們也可以通過在charles中搜索callback這個字符串,可以發現就是該js文件。通過在webstorm中搜索callback關鍵詞(通過前面多次登錄抓包分析,可發現callback的bd__cbs_前綴不會改變,這個也可以是搜索依據),可以找到callback的生成方式


var i, r, o, a = this.url, s = document.createElement("SCRIPT"), u = "bd__cbs__", d = t || {},

l = d.charset, c = d.queryField || "callback", f = d.timeOut || 0,
p = new RegExp("(?|&)" + c + "=([^&]*)");

// 下面就是callback的生成邏輯
baidu.lang.isFunction(e) ? (i = u + Math.floor(2147483648 * Math.random()).toString(36)

截至目前,我們已經弄清楚了gidcallback的生成方式了,這樣我們就可以通過構造請求來獲取到token了。我們再返回post參數這張圖片,可以看到還有passwordrsakeyppui_logintime這三個字段還需要分析。而通過搜索rsakey的值,可以看到其實它就是 圖片輸入賬號后服務端返回的內容 中的key的值,我們可以通過

https://passport.baidu.com/v2...

這個請求獲取到。請求的參數如圖,都是我們前面分析過并且能夠得到的參數:

現在我們就只有ppui_logintimepassword兩個字段沒分析了。
老規矩,我們先在charles中搜索ppui_logintime的值,發現只有一個請求中出現了。那么它肯定是js生成的,它是如何生成的呢?我們又在我們獲取的login_tangram_c36ce25.js文件中搜索ppui_logintime這個字符串,可以發現這段代碼:


login: {

            memberPass: "mem_pass",
            safeFlag: "safeflg",
            isPhone: "isPhone",
            timeSpan: "ppui_logintime",
            logLoginType: "logLoginType"
        }


然后我們再看timeSpan是如何生成的。可以看到這段代碼

r.timeSpan = (new Date).getTime() - e.initTime

大概是一個時間差:當前時間-初始化時間。當前時間容易獲取,那么初始化時間到底是什么初始化呢?繼續追蹤initTime可以發現這段代碼


_initApi: function (e) {

        var t = this;
        t.initialized = !0, t.initTime = (new Date).getTime(), passport.data.getApiInfo({
            apiType: "login",
            gid: t.guideRandom || "",
            loginType: t.config && t.config.diaPassLogin ? "dialogLogin" : "basicLogin"
        })

.....


initApi中的initTime大概就是頁面請求完成的時間,所以ppui_time應該就是登錄頁面初始化完成到點擊登錄按鈕的時間差,為了方便,我們只需要取抓包獲取的值即可。

現在分析password參數,這個參數也是分析難度最大的參數了。這次我們直接在加密js文件中搜索password關鍵詞,可以搜索到很多地方有password這個字符串,那么如何做篩選呢?需要我們有一點js的基礎知識,在每個匹配到password的地方都讀讀源碼,大概知道它做什么的就行了。最后,我們可以定位到這段代碼:


var r = baidu.form.json(e.getElement("form"));
r.token = e.bdPsWtoken, passport.data.setContext(baidu.extend({}, e.config)), r.foreignusername && (r.foreignusername = e._SBCtoDBC(r.foreignusername)), r.userName = e._SBCtoDBC(r.userName), r.verifyCode = e._SBCtoDBC(r.verifyCode);
var o = e._SBCtoDBC(e.getElement("password").value);
if (e.RSA && e.rsakey) {

    var a = o;
    a.length < 128 && !e.config.safeFlag && (r.password = baidu.url.escapeSymbol(e.RSA.encrypt(a)), r.rsakey = e.rsakey, r.crypttype = 12)
                   }

var s, u = e.getElement("submit"), d = 15e3;

上述代碼既有rsakeyform又有password關鍵字,那么十有八九就是加密password的方法了。主要加密語句是:

e.RSA.encrypt(a)

我們查看encrypt()的實現


Jn.prototype.encrypt = function (e) {

try {
        return xn(this.getKey().encrypt(e))
    } catch (t) {
        return !1
    }

}

這里的過程大概就是先用this.getKey()返回的對象對e進行加密,然后再進行一次xn(),這里js的代碼十分復雜,如果想把對應的js轉化為python實現,需要很深的js和python功底,但是這個轉換已經有人幫我們做了。這里的encrypt()即是使用rsa非對稱加密算法對密碼進行加密。而xn()是base64編碼方法。判斷encrypt()是rsa加密算法的依據是該js文件中出現了多次rsakey,并且也有


fn.prototype.getPrivateKey = function () {

        var e = "-----BEGIN RSA PRIVATE KEY-----
";
        return e += this.wordwrap(this.getPrivateBaseKeyB64()) + "
", e += "-----END RSA PRIVATE KEY-----"
    }, fn.prototype.getPublicKey = function () {
        var e = "-----BEGIN PUBLIC KEY-----
";
        return e += this.wordwrap(this.getPublicBaseKeyB64()) + "
", e += "-----END PUBLIC KEY-----"
    }


這類代碼作為佐證。判斷后者是base64算法的依據是xn()函數中出現了

ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/

這類字符串,它是base64編碼的一個基礎部分。

所以說這里的分析需要大家有基本的密碼學知識,否則分析會比較困難。這里友情提示一句,目前主流的大中型網站都會使用rsa算法對密碼進行加密,所以大家需要有這個意識。但是不要求大家會實現rsa等加密算法,因為無論是python還是js還是java都有相關的實現了,我們只需要會分析會使用就行了。

到這里所有的參數分析就結束了,我們可以通過代碼進行驗證。


上面詳細介紹了百度整個登錄流程。我們來總結一下:

先通過加密js文件獲取到gid,callback參數

根據https://passport.baidu.com/v2/api/?getapi&...這個(get)請求獲取到token

根據https://passport.baidu.com/v2/getpublickey?token=...這個(get)請求獲取到rsakeypubkey

根據獲取到的pubkey對password進行加密,然后再進行base64編碼操作

將所有固定和構造的參數進行post請求,post請求的url為https://passport.baidu.com/v2/api/?login,如果該post返回err_no=0,那么模擬登陸就成功了,否則則失敗,會返回響應的err_no


前面費了這么大的力氣分析百度的登錄流程,如果實在是想走捷徑的,可以使用selenium自動化的方式登錄,這個我也給了相關實現。讀過我的新浪微博模擬登陸的同學大概對介于直接登錄和使用selenium自動化登錄之間的方法還有一些印象吧,這里我并沒有使用該方法,因為如果要使用該方法的話,需要改動一些js來使代碼跑通。有興趣的同學可以試試,應該比較有意思。

如果有同學感覺本文有一些難度,可以嘗試一些簡單的模擬登陸,比如知乎和CSDN等,我寫過一篇關于CSDN模擬登陸的文章,微博模擬登陸應該比本文的分析難度稍微要小一點,如果有興趣,也可以讀讀。

我把代碼放到我的開源項目smart_login上了,點擊這里可以查看百度模擬登陸流程的實現,如果有不清楚的同學,建議對照代碼再來讀本文,可能會更加清晰,如果實際動手按本文的分析流程
走一遍,那么可能會有一些收獲。

此外,打一個廣告,如果對如何構建分布式爬蟲或者大規模微博數據采集感興趣的話,可以專注一下我的開源分布式微博爬蟲項目,目前還在快速迭代,單從功能角度來講,抓取部分基本上快實現和測試完了。

如果大家覺得本文對大家有幫助,不妨點個推薦,如果代碼對大家有幫助,也不妨點個star,以表示對我的鼓勵吧。愛給別人點贊的孩子,運氣始終不會太差。

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/44387.html

相關文章

  • 詳細Python實現新浪微博模擬登陸(小白都能懂)

    摘要:可能有的老手覺得我寫得很啰嗦,但其實很多新手可能都不知道這些細節,所以我把我在分析新浪微博模擬登陸的過程全寫了出來。 這篇文章于去年4月發布在我的簡書,現在把它放到這里,主要是為了宣傳自己的分布式微博爬蟲。下面是主要內容,希望能幫到有這個需求的朋友 最近由于需要一直在研究微博的爬蟲,第一步便是模擬登陸,從開始摸索到走通模擬登陸這條路其實還是挺艱難的,需要一定的經驗,為了讓朋友們以后少...

    Aldous 評論0 收藏0
  • 首次公開,整理12年積累博客收藏夾,零距離展示《收藏夾吃灰》系列博客

    摘要:時間永遠都過得那么快,一晃從年注冊,到現在已經過去了年那些被我藏在收藏夾吃灰的文章,已經太多了,是時候把他們整理一下了。那是因為收藏夾太亂,橡皮擦給設置私密了,不收拾不好看呀。 ...

    Harriet666 評論0 收藏0
  • Python使用cookielib、urllib2和pyquery模擬登陸本科教學網并抓取數據

    摘要:原文鏈接使用和模擬登陸本科教學網并抓取數據剛才好無聊,突然想起來之前做一個課表的點子,于是百度了起來。使用現在,我們已經登錄了本科教學網,然后結合之前的解析就可以獲取網頁內的課表了。 原文鏈接:《Python使用cookielib、urllib2和pyquery模擬登陸本科教學網并抓取數據》 剛才好無聊,突然想起來之前做一個課表的點子,于是百度了起來。 PyQuery 剛...

    tuomao 評論0 收藏0
  • 知乎最新版模擬登陸詳解,小白也能懂

    摘要:模擬登陸知乎這個知乎的登陸也是坑滿滿,我也給踩了幾個,這個就直接說坑吧,其他的就不多說了。 以下內容僅交流學習,請勿用于非法用途 如果你現在想模擬登陸知乎,會發現 fromdata 是一串加密的字符串 showImg(https://segmentfault.com/img/remote/1460000018245629); 看了之后是不是很痛苦?你是不是就想使用 selenium 來...

    buildupchao 評論0 收藏0
  • 知乎最新版模擬登陸詳解,小白也能懂

    摘要:模擬登陸知乎這個知乎的登陸也是坑滿滿,我也給踩了幾個,這個就直接說坑吧,其他的就不多說了。 以下內容僅交流學習,請勿用于非法用途 如果你現在想模擬登陸知乎,會發現 fromdata 是一串加密的字符串 showImg(https://segmentfault.com/img/remote/1460000018245629); 看了之后是不是很痛苦?你是不是就想使用 selenium 來...

    xuxueli 評論0 收藏0

發表評論

0條評論

最新活動
閱讀需要支付1元查看
<