1. 程式人生 > >超詳細的Python實現微博模擬登陸,小白都能懂

超詳細的Python實現微博模擬登陸,小白都能懂

原文來自:公眾號"速學Python"

前言

最近由於需要一直在研究微博的爬蟲,第一步便是模擬登陸,從開始摸索到走通模擬登陸這條路其實還是挺艱難的,需要一定的經驗,為了讓朋友們以後少走點彎路,這裡我把我的分析過程和程式碼都附上來。

首先,我們先用正常的賬號登陸,具體看會有些什麼請求。這裡我用的是Http Analyzer抓包(Filders也是一個不錯的選擇)。下面是正常登陸流程的截圖:

接下來我會詳細說明各個過程。

第一步:預登陸。

現在微博、空間等大型網站在輸入使用者名稱後基本都會做編碼或者加密處理,這裡在使用者名稱輸入框輸入我的賬號,通過抓包工具可以看到伺服器會返回一段字串:

這一步就是預登陸過程,同學們可以自己試試。登陸的時候我們需要用到其中的servertime、nonce、pubkey等欄位。當然這個不是我自己猜想的,後面的步驟會做說明。

還有一點,就是預登陸的url:

這裡su的值是自己使用者名稱經過base64編碼的值。但可能你們會問我是如何知道的呢,待會兒我會講到。經過實測,如果我們這裡不給su傳引數,其實也是可以的。為了最真實的模擬使用者登入,我們最好還是帶上它的值。

學習從來不是一個人的事情,要有個相互監督的夥伴,工作需要學習python或者有興趣學習python的夥伴可以私信回覆小編“學習” 獲取資料,一起學習

請看圖一的第一條js請求http://i.sso.sina.com.cn/js/ssologin.js,同學們可以點進去看,這個就是前面提到的加密使用者名稱和密碼等一系列的加密檔案了,如果有同學非要問我是怎麼找到這個加密檔案的,我也只有說:反覆抓包,從在瀏覽器輸入weibo.com過後就找js檔案請求路徑,然後再用程式碼格式化工具開啟,挨著一個一個看,在程式碼中搜關鍵字,比如這裡我們可以搜"nonce"、“servertime”等,就能找到加密檔案了。

開啟加密檔案我們可以看到加密使用者名稱的程式碼,在加密js檔案中搜索'username',可以看到有一行程式碼為:

現在我們可以直接查詢encode方法(程式碼太多就不貼上來了),即可查詢到對應方法了,為了驗證我們的猜想,我們可以在webstorm中copy這個encode函式帶上自己的使用者名稱執行,返回的結果就是su的值,這個值在之後進行post提交的時候也會用到。如果對加密有一定經驗的同學可能一眼就會看出這個是base64編碼,python中有個base64模組可以幹這個事情。我們再回到圖一,http://login.sina.com.cn/sso/login.php?client=ssologin.js(v1.4.18)這個地址就是進行post提交資料的地址,下面是我自己提交的資料:

這裡我們需要自己構造su(加密後的使用者名稱),sp(加密後的密碼),servertime,nonce,rsakv等資料,其它資料都不用變。有同學問我為哈其它資料不用變?你自己可以多登陸幾次,看變化的值,那麼那些值就是需要構造的值,其它值就直接拿過來用就行了。

這裡的su,servertime,nonce,rsakv都已經拿到了,所以當前需要的就只是sp的值了。我們還是按照原來的方法在js檔案中查詢“sp”,可以找到requests.sp=password這段程式碼,所以我們就只需要看password怎麼構造的了。通過查詢可以看到關鍵加密程式碼:

這一段程式碼便是加密密碼的程式碼,有經驗的同學一看就知道是用的RSA加密,python中也有相應的rsa加密庫可用。但是我們假設大家都沒看出來或者不知道python中有rsa這個第三方庫。這時候就要給大家介紹一些我的經驗了,我現在已經知道的有三種模擬登陸方案:

最簡單暴力,效率也是最高的,直接把js原始碼轉化為相應的python程式碼,模擬加密流程進行加密

使用selenium+phantomjs/firefox的方案直接模擬人的操作填寫表單提交資料進行模擬登陸,這種方式最為簡單,效率稍微低一些。如果有同學對這種簡單暴力的方式感興趣,可以到我的github上檢視一下原始碼

比較折中的方案,通過pyv8/pyexecjs等渲染js程式碼進行執行,本文主要就是講的這種方式。

第一種方式如果是遇到微博調整了登陸加密演算法,就必須改加密程式碼,第二種方式和第三種方式不存在這個問題。

由於我用的是Python3,並不支援PyV8,所以我選了和它類似的PyexecJS(https://github.com/doloopwhile/PyExecJS),這個也可以直接執行js程式碼。我也不是很熟悉Javascript程式碼,所以我直接定義了一個函式處理加密密碼,並沒對其加密原始碼修改太多:

這個函式中的東西其實就是copy的加密檔案的加密過程程式碼。為了試驗,我直接使用之前自己登陸抓到的nonce、servertime、rsakey等資料,在webstorm中呼叫這個函式,但是報錯了,提示"navigator is undefined",webstorm 使用的nodejs的執行時環境,而navigator為瀏覽器的某個屬性,所以執行會出問題。

於是我就是用phantomjs來作為執行時環境.考慮到有同學不知道phantomjs怎麼使用,這裡我簡要說一下吧。使用windows的同學先要去 phantomjs官網 下載它的可執行檔案,然後設定環境變數。在命令列輸入"phantomjs some.js"即可執行some.js檔案,其實就和在命令列執行python或者java檔案一樣,如果不清楚的可以百度執行命令列執行python的方法,仿照著來就可以了,再不清楚就在後臺問我。

使用ubuntu的同學可以直接用sudo apt-get install phantomjs,就可以安裝使用了。我直接把加密的js檔案使用phantomjs執行,果然好著呢。

原因是因為phantomjs其實就是一款無ui的瀏覽器,自然支援navigator、window等屬性。而pyexecjs支援使用phantomjs作為執行時環境,具體用法pyexecjs的git主頁有,我也在程式碼中有所體現。

這段程式碼就可以得到加密過後的密碼了。

之後,便可以進行post提交,提交地址可以從抓包工具看到:http://login.sina.com.cn/sso/login.php?client=ssologin.js(v1.4.18)。

根據經驗,到這裡過程基本就完了。但是微博有點坑啊,這裡還需要有一步,就是圖一所示的類似

,這一步會將請求重定向,返回當前賬號的登陸資訊,如下圖:

那麼問題來了,怎麼獲取上面的請求地址呢。分析上面地址,有ticket欄位,這個應該是讓你登陸的憑據,所以這個地址應該是服務端返回的,如果不是,起碼ticket是服務端返回的,於是我們又使用抓包工具檢視在請求這段url之前返回的資訊,發現有和上述url吻合的資訊:

這段程式碼是使用post後回覆的內容,所以可以直接從中提取出我們需要的url。然後再使用get方式請求上述的url,它會經歷一次重定向,直接返回登陸資訊。這個時候,就代表成功登陸了。

PS:授人以魚不如授人以漁,這是我一直秉承的信念。可能有的老手覺得我寫得很囉嗦,但其實很多新手可能都不知道這些細節,所以我把我在分析新浪微博模擬登陸的過程全寫了出來。

另外,除了這種方式,本文提到的另外兩種方式也有實現。最暴力的方式需要使用rsa這個第三方庫,具體我在程式碼上有詳細註釋,還有一種是使用selenium+phantomjs這種方式,我也在程式碼中關鍵地方有註釋.

Talk is cheap,show me the code!

最後奉上本文的所有方式的模擬登陸程式碼(如果覺得喜歡或者看了對你有幫助,不妨在github上給個star,也歡迎fork)

star(https://github.com/SpiderClub/smart_login/tree