1. 程式人生 > >Python 模擬微博登陸,親測有效!

Python 模擬微博登陸,親測有效!

640?wx_fmt=gif

640?wx_fmt=jpeg


今天想做一個微博爬個人頁面的工具,滿足一些不可告人的祕密。那麼首先就要做那件必做之事!模擬登陸……


程式碼是參考了:https://www.douban.com/note/201767245/,我對程式碼進行了優化,重構成了Python 3.6 版本,並且加入了大量註釋方便大家學習。


PC 登入新浪微博時, 在客戶端用JS預先對使用者名稱、密碼都進行了加密,而且在POST之前會GET 一組引數,這也將作為POST_DATA 的一部分。這樣,就不能用通常的那種簡單方法來模擬POST 登入( 比如人人網 )。



640?wx_fmt=png



在提交POST請求之前,需要GET 獲取兩個引數。

地址是:http://login.sina.com.cn/sso/login.php?client=ssologin.js(v1.3.18)。


得到的資料中有 servertime 和 nonce 的值, 是隨機的,其他值貌似沒什麼用。


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



640?wx_fmt=png



通過 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



640?wx_fmt=png



將引數組織好,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 快取。


640?wx_fmt=png


作者簡介:上海小胖,四大諮詢的Tech Lead,MongoDB Professional獲得者。「Python專欄」專注Python領域的各種技術:爬蟲、DevOps、人工智慧、Web開發等。還有「大航海計劃」,各種內推活動。

宣告:本文為作者投稿,版權歸其個人所有。



 熱 文 推 薦  

☞ 「傻瓜」才能寫出好程式碼!

☞ 漫畫 | 從搬家到容器技術 Docker 應用場景解析

☞ Hacker News 12 月招聘趨勢:React 已連續霸榜 19 個月

☞ 從傾家蕩產到身價百億,這個85後只用了8年

☞ 難逃寒冬裁員的“大追殺”,30 歲女碼農該何去何從?

☞ OpenStack 2018 年終盤點

☞ 拼多多黃崢給陸奇“兼職”,欲挖掘這類AI人才

☞ 老程式設計師肺腑忠告:千萬別一輩子靠技術生存!


  

print_r('點個好看吧!');
var_dump('點個好看吧!');
NSLog(@"點個好看吧!");
System.out.println("點個好看吧!");
console.log("點個好看吧!");
print("點個好看吧!");
printf("點個好看吧!\n");
cout << "點個好看吧!" << endl;
Console.WriteLine("點個好看吧!");
fmt.Println("點個好看吧!");
Response.Write("點個好看吧!");
alert("點個好看吧!")
echo "點個好看吧!"

640?wx_fmt=gif點選“閱讀原文”,開啟 CSDN App 閱讀更貼心!

640?wx_fmt=png 喜歡就點選“好看”吧!