今天想作一個微博爬我的頁面的工具,知足一些不可告人的祕密。那麼首先就要作那件必作之事!模擬登錄……php
代碼是參考了:https://www.douban.com/note/2...python
我對代碼進行了優化,重構成了Python 3.6 版本,而且加入了大量註釋方便你們學習。ajax
PC 登陸新浪微博時, 在客戶端用js預先對用戶名、密碼都進行了加密, 並且在POST以前會GET 一組參數,這也將做爲POST_DATA 的一部分。 這樣, 就不能用一般的那種簡單方法來模擬POST 登陸( 好比 人人網 )。json
在提交POST請求以前, 須要GET 獲取兩個參數。
地址是:數組
http://login.sina.com.cn/sso/...緩存
獲得的數據中有 servertime 和 nonce 的值, 是隨機的,其餘值貌似沒什麼用。python爬蟲
def get_servertime(): url = 'http://login.sina.com.cn/sso/prelogin.php?entry=weibo&callback=sinaSSOController.preloginCallBack&su=dW5kZWZpbmVk&client=ssologin.js(v1.3.18)&_=1329806375939' # 返回出來的是一個Response對象,沒法直接獲取,text後,能夠經過正則匹配到 # 大概長這樣子的:sinaSSOController.preloginCallBack({"retcode":0,"servertime":1545606770, ...}) data = requests.request('GET', url).text p = re.compile('\((.*)\)') try: json_data = p.search(data).group(1) data = json.loads(json_data) servertime = str(data['servertime']) nonce = data['nonce'] return servertime, nonce except: print('獲取 severtime 失敗!') return None
經過httpfox 觀察POST 的數據, 參數較複雜,其中 「su" 是加密後的username, sp 是加密後的password。servertime 和 nonce 是上一步獲得的。其餘參數是不變的。工具
username 通過了BASE64 計算:學習
username = base64.encodestring( urllib.quote(username) )[:-1]
password 通過了三次SHA1 加密, 且其中加入了 servertime 和 nonce 的值來干擾。
即: 兩次SHA1加密後, 將結果加上 servertime 和 nonce 的值, 再SHA1 算一次。優化
def get_pwd(pwd, servertime, nonce): # 第一次計算,注意Python3 的加密須要encode,使用bytes pwd1 = hashlib.sha1(pwd.encode()).hexdigest() # 使用pwd1的結果在計算第二次 pwd2 = hashlib.sha1(pwd1.encode()).hexdigest() # 使用第二次的結果再加上以前計算好的servertime和nonce值,hash一次 pwd3_ = pwd2 + servertime + nonce pwd3 = hashlib.sha1(pwd3_.encode()).hexdigest() return pwd3 def get_user(username): # 將@符號轉換成url中可以識別的字符 _username = urllib.request.quote(username) # Python3中的base64計算也是要字節 # base64出來後,最後有一個換行符,因此用了切片去了最後一個字符 username = base64.encodebytes(_username.encode())[:-1] return username
將參數組織好, POST請求。 這以後尚未登陸成功。
POST後獲得的內容中包含一句:
location.replace("http://weibo.com/ajaxlogin.php?framelogin=1&callback=parent.sinaSSOController.feedBackUrlCallBack&retcode=101&reason=%B5%C7%C2%BC%C3%FB%BB%F2%C3%DC%C2%EB%B4%ED%CE%F3")
這是登陸失敗時的結果, 登陸成功後結果與之相似, 不過retcode 的值是0 。
接下來再請求這個URL,這樣就成功登陸到微博了。
記得要提早build 緩存。
關注公衆號「Python專欄」,後臺回覆「模擬微博登錄」,獲取全套微博自動登錄代碼。