python模擬登錄練習(二)

花了4個晚上終于把模擬登錄新浪微博學習完了,相對于知乎迷你登錄仲智,微博登錄的過程確實難度大了很多莱衩,好多知識點都不懂烈钞,所以雖然把代碼都碼了一遍贫堰,但很多都是照貓畫虎,其實還有很多地方不是十分清楚考传。代碼中寫了很多注解(對向我一樣的初學者來說應該很有必要),所以看以來不是很簡潔证鸥,其實源碼查不到150行僚楞。

希望本文能對向我一樣的初學者能起到一點借鑒作用

寫以下我這幾天自學的過程:
一、第一天直接看xchaoinfo的源碼枉层,完全看不懂泉褐,好不好∧窭看了15分鐘直接放棄膜赃,轉(zhuǎn)百度看圖文教程,還好網(wǎng)上的教程不算少(其實方法都一樣矩欠,代碼也基本沒多少差別财剖,應該起初都出自同一作者)悠夯,
網(wǎng)上從抓包介紹,好吧又不會躺坟,那就學吧~~~
這樣一天就過去了沦补,感覺什么都沒學到
二、第二天繼續(xù)抓包咪橙,還是沒什么進展夕膀,期間換了各種抓包工具,都不太會用美侦,感覺網(wǎng)上介紹的看方法用這些抓包工具都沒發(fā)抓到产舞,這樣一天快要過去的時候,想想還是用瀏覽器的F12吧菠剩,這樣就用了火狐瀏覽器(因為之前一致用chrome的F12看源碼易猫,也抓不到js文件),下載了firebug具壮,用起來還是一頭霧水准颓,晚上想想還是睡覺吧,睡覺前又百度了firebug的用法棺妓,本來也沒抱希望有什么用攘已,可是突然奇跡發(fā)生了,多次嘗試了之后找到了教程中的js文件怜跑,太晚了样勃,睡覺!P苑摇峡眶!
自學真的很痛苦,可能很簡單的問題會難住好幾天批旺。
三幌陕、第三天,繼續(xù)看js文件汽煮,抓post的各種屬性搏熄,看著教程試著理解密碼加密的方法,差不多的時候繼續(xù)回去啃源碼暇赤,中間碰到不會的模塊google和自己用idle一點點測試心例,理解個大概繼續(xù)往下啃,啃到一般就睡覺了鞋囊。
四止后、第四天的繼續(xù)下面的代碼,后面的表單登錄相對簡單,因為之前有相關(guān)的學習經(jīng)驗译株,進過兩個小時瓜喇,終于測試成功了。
下面把源碼貼出來給自己留個紀念歉糜,也給需要的書友提供一點思路乘寒。

"""
新浪微博模擬登錄練習,本教程參考了很多網(wǎng)上的教程匪补,很多教程的源碼都差不多伞辛,本文的代碼主要修改自author : "xchaoinfo" github的源碼
新浪微博的模擬登錄對新手來說比較困難(我就是初學者,以前沒有任何編程基礎夯缺,因為對現(xiàn)在的工作狀態(tài)不滿意蚤氏,2017年開始自學python)


author : xcaojianhong
qq:1254798548
date:2017.02.21
"""

import time
import base64   #加密模塊
import rsa  #加密模塊
import binascii #二進制模塊
import requests #是的,本次練習還是用的requests庫踊兜,本意是學習scrapy爬蟲竿滨,可是找不到模擬登錄的詳細的教程,只能先擱置了
import re   #正則模塊捏境,不太會用
import random   #我不是太理解為甚要rondom模塊
import http.cookiejar
from PIL import Image #這個只用到簡單的方法姐呐,高級的本人也不會
from urllib.parse import quote_plus #涉及編碼問題,需要用到該模塊


'''
如果沒有開啟登錄保護典蝌,不用輸入驗證碼就可以登錄
如果開啟登錄保護,需要輸入驗證碼头谜,PIL庫就是用了打開驗證碼的圖片用的骏掀,就只是打開,還是需要手動輸入的柱告,不是完成自動驗證
'''


# 構(gòu)造 Request headers截驮,這個不解釋了,很多基礎教程中都會有的际度,一般網(wǎng)站都有反爬蟲的機制葵袭,最常見的就是識別是不是瀏覽器訪問的,這個就是用來模擬瀏覽器的
user_agent = 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36'
headers = {
    'User-Agent': user_agent
}

session = requests.session()    #實例化一個session類乖菱,session類能夠自動處理cookies
session.cookies = http.cookiejar.LWPCookieJar(filename = 'cookies') #用于保存cookies坡锡,對爬取后需爬去有用
index_url = "http://weibo.com/login.php" #這個是微博登錄的原始的url

# 訪問初始頁面帶上 cookies
try:
    session.get(index_url,headers=headers,timeout=2)        #為什么用延時參數(shù)不太清楚,我自己寫的話就只寫excpet后面的一句
except:
    session.get(index_url,headers=headers)

try:
    input = raw_input #這個自行百度兩個input的差異窒所,因為我也不太清楚
except:
    pass


# 下面開始困難了鹉勒,我光抓包就花了兩個晚上才看懂網(wǎng)上講的方法是怎么回事,期間換了很多抓包的工具吵取,最后還是覺得firebug好用
def get_su(username):
    """
    1.輸入賬號禽额,會先在js中通過encodeURIComponent進行編碼,對應python的urllib.parse.quote_plus方法,問我怎么知道的脯倒,是因為源碼中的注釋說的
    密碼的加密方法在ssologin.js文件中实辑,為我為什么知道,網(wǎng)上教程說的藻丢,自己分析的話我估計2天都不一定能找到剪撬。
    在js里面有這樣的代碼:
    username = sinaSSOEncoder.base64.encode(urlencode(username))
    urlencode函數(shù)中用了encodeURIComponent編碼,具體代碼就不貼了郁岩,自己仔細看能找到婿奔。這里能看到用戶名用了base64進行加密

    2.其實我也不知道怎么解釋,為什么要先對username_quote進行utf-8編碼问慎,然后才base64加密萍摊,照著寫就行了,我在python中測試不編碼加密會報錯如叼,具體原因不清楚
    """
    username_quote = quote_plus(username)   #詳細解釋看1
    username_base64 = base64.b64encode(username_quote.encode('utf-8'))  #詳細解釋看2
    # print(username_base64.decode('utf-8')) 測試用
    return username_base64.decode('utf-8') #解碼成utf-8格式字符串


# 預登陸獲得 servertime, nonce, pubkey, rsakv 這些屬性在后面密碼加密過程中需要用到
def server_data(su):
    """
    3.通過抓包分析我們看到冰木,https://login.sina.com.cn/sso/prelogin.php?entry=weibo&callback=sinaSSOController.preloginCallBack
    &su=ODg4ODg4OA==&rsakt=mod&checkpin=1&client=ssologin.js(v1.4.18)&_=1487602221124這個url的response是一個json格式的文本,其中包含
    servertime, nonce, pubkey, rsakv這些屬性笼恰,這正是我們需要的踊沸,&su=ODg4ODg4OA==,這個su并不是get_su的返回值社证,但是相近逼龟,直接用get_su的返回值不影響
    另外這里用到了time模塊,用了生成時間戳追葡,1487602221124這個就是時間戳

    """

    #get_su()解釋了那么多腺律,就是為了獲得su,雖然在這里su不那么重要(因為實際預登錄url中su并不是完全正確的),但是最后的post表單中需要用到su
    pre_url = "http://login.sina.com.cn/sso/prelogin.php?entry=weibo&callback=sinaSSOController.preloginCallBack&su="\
    + su + "&rsakt=mod&checkpin=1&client=ssologin.js(v1.4.18)&_=" + str(int(time.time() * 1000))    #為什么是這個url宜肉,詳細請看3
    pre_data_res = session.get(pre_url, headers=headers)

    sever_data = eval(pre_data_res.content.decode("utf-8").replace("sinaSSOController.preloginCallBack", ''))   #這里用repalce替換
    # print(sever_data) 測試用
    return sever_data

# 這個是本次登錄中最難的地方匀钧,需要用到上面的參數(shù)
def get_password(password,servertime,nonce,pubkey):
    """
    具體為什么需要這些參數(shù),還是要仔細分析之前提到的js文件谬返,里面有密碼加密的過程
    request.servertime = me.servertime;
            request.nonce = me.nonce;
            request.pwencode = "rsa2";
            request.rsakv = me.rsakv;
            var RSAKey = new sinaSSOEncoder.RSAKey();
            RSAKey.setPublic(me.rsaPubkey, "10001");    #rsaPubkey就是pubkey之斯,js的代碼就不貼了
            password = RSAKey.encrypt([me.servertime, me.nonce].join("\t") + "\n" + password)
    """
    rsapublickey = int(pubkey,16)   #如果是16進制,則轉(zhuǎn)化為10進制
    key = rsa.PublicKey(rsapublickey,65537) # '10001'轉(zhuǎn)化為10進制就是65537
    message = str(servertime) + '\t' + str(nonce) + '\n' + str(password)  # 仔細對著js代碼慢慢看
    message = message.encode("utf-8")
    #print(message) 測試用
    passwd = rsa.encrypt(message, key)  # 加密遣铝,為什么要用rsa佑刷,我也不知道,源代碼就用的翰蠢,我也不懂這個方法的具體的用途项乒,反正看著和js的代碼相似的,當成是python版本的翻譯看
    #print(passwd) 測試用
    passwd = binascii.b2a_hex(passwd)  # 將加密信息轉(zhuǎn)換為16進制梁沧,post需要16進制ps檀何,猜測的,對編碼不太了解。
    # print(passwd) 測試用
    return passwd

# 獲得驗證碼频鉴,并下載后用PIL模塊自動打開栓辜,沒有安裝的話手動去爬蟲文件的目錄中手動打開圖片
def get_cha(pic):
    """

    我沒有詳細分析需要驗證碼的收獲,因為我登錄新浪微博基本沒有碰到需要驗證碼的時候
    下面用到了隨機數(shù)垛孔,我不是太理解藕甩,既然能用隨機數(shù),為什么不能用固定的數(shù)字周荐,反正都是我們自己構(gòu)造的一個數(shù)字
    """
    cha_url = "http://login.sina.com.cn/cgi/pin.php?r="
    cha_url = cha_url + str(int(random.random() * 100000000)) + "&s=0&p="
    cha_url = cha_url + pcid
    cha_page = session.get(cha_url, headers=headers)
    with open("cha.jpg", 'wb') as f:
        f.write(cha_page.content)
        f.close()
    try:
        im = Image.open("cha.jpg")
        im.show()
        im.close()
    except:
        print(u"請到當前目錄下狭莱,找到驗證碼后輸入")

def login(username,password):
    """
    激動人心的時候快要到了,上面作的一些準備工作就是為了獲得post的屬性
    """
    su = get_su(username)   #獲得加密的su
    sever_data = server_data(su)    #獲得server_data函數(shù)返回的字典
    servertime = sever_data['servertime']
    nonce = sever_data['nonce']
    rsakv = sever_data["rsakv"]
    pubkey = sever_data["pubkey"]
    showpin = sever_data["showpin"] #這個參數(shù)的值關(guān)系到是否需要輸入驗證碼概作,0表示不需要腋妙,1表示需要
    password_secret = get_password(password,servertime,nonce,pubkey) #獲得加密的sp
    # su,sp,servertime,nonce,rsakv,sp屬性是變化的,其他的都可以寫死
    postdata = {
        'entry':'weibo',
        'gateway':'1',
        'from':'',
        'savestate':'7',
        'useticket':'1',
        'pagerefer':"http://login.sina.com.cn/sso/logout.php?entry=miniblog&r=http%3A%2F%2Fweibo.com%2Flogout.php%3Fbackurl",
        'wsseretry':'servertime_error',
        'vsnf':'1',
        'su':su,
        'service':'miniblog',
        'servertime':servertime,
        'nonce':nonce,
        'pwencode':'rsa2',
        'rsakv':rsakv,
        'sp':password_secret,
        'sr':'1536*864',
        'encoding':'UTF-8',
        'prelt':'105',
        'url':'http://weibo.com/ajaxlogin.php?framelogin=1&callback=parent.sinaSSOController.feedBackUrlCallBack',
        'returntype':'META'
        }

    login_url = 'http://login.sina.com.cn/sso/login.php?client=ssologin.js(v1.4.18)'    #用于登錄的url讯榕,psot表單提交的url
    if showpin == 0:
        login_page = session.post(login_url, data=postdata, headers=headers)
    else:
        pcid = sever_data["pcid"]
        get_cha(pcid)
        postdata['door'] = input(u"請輸入驗證碼")
        login_page = session.post(login_url, data=postdata, headers=headers)
    login_loop = (login_page.content.decode("GBK")) #看網(wǎng)絡抓包骤素,知道是gbk編碼
    #print(login_loop)
    pa = r'location\.replace\([\'"](.*?)[\'"]\)' #這里的正則查相關(guān)的教程
    loop_url = re.findall(pa, login_loop)[0]
    #print(loop_url)
    # 正常訪問login_page就結(jié)束了,但是微博喪心病狂的還需要一部跳轉(zhuǎn)愚屁,請繼續(xù)往下看济竹,我自己寫的都累了,需要進一步訪問login_loop這個url

    login_index = session.get(loop_url, headers=headers)
    uuid = login_index.text
    print(login_index.status_code)  #測試登錄是否成功
    session.cookies.save() #保存cookies

    # ↑↑↑↑↑↑到上面其實已經(jīng)完成了登錄了

    response = session.get('http://weibo.com/',headers=headers)
    # print(response.text) #測試用霎槐,可以打印出來看看是否與正常登錄看到的微博首頁的源碼一樣了


    # 以下是原文作者用來登錄微博個人首頁獲得使用者微博賬號送浊,并打印出來的代碼,我沒有詳細解析
    uuid_pa = r'"uniqueid":"(.*?)"'
    uuid_res = re.findall(uuid_pa, uuid)[0]
    web_weibo_url = "http://weibo.com/%s/profile?topnav=1&wvr=6&is_all=1" % uuid_res
    weibo_page = session.get(web_weibo_url, headers=headers)
    weibo_pa = r'<title>(.*?)</title>'
    # print(weibo_page.content.decode("utf-8"))
    userID = re.findall(weibo_pa, weibo_page.content.decode("utf-8", 'ignore'), re.S)[0]    #不加re.S參數(shù)好像沒什么不同丘跌,上文我沒加
    print(u"歡迎你 %s, 你在正在使用 xcaojianhong 寫的爬蟲模擬登錄微博" % userID)
    print(input(u'輸入任何鍵繼續(xù)'))
    print(u'好吧其實大部分代碼都是參考xchaoinfo的文章')


if __name__ == "__main__":
    username = input(u'用戶名:')
    password = input(u'密碼:')
    login(username, password)


測試結(jié)果:

@P`MXHW5]5`%MP)~2LMWU50.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末罕袋,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子碍岔,更是在濱河造成了極大的恐慌,老刑警劉巖朵夏,帶你破解...
    沈念sama閱讀 222,807評論 6 518
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件蔼啦,死亡現(xiàn)場離奇詭異,居然都是意外死亡仰猖,警方通過查閱死者的電腦和手機捏肢,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,284評論 3 399
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來饥侵,“玉大人鸵赫,你說我怎么就攤上這事□锷” “怎么了辩棒?”我有些...
    開封第一講書人閱讀 169,589評論 0 363
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我一睁,道長钻弄,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 60,188評論 1 300
  • 正文 為了忘掉前任者吁,我火速辦了婚禮窘俺,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘复凳。我一直安慰自己瘤泪,他們只是感情好,可當我...
    茶點故事閱讀 69,185評論 6 398
  • 文/花漫 我一把揭開白布育八。 她就那樣靜靜地躺著对途,像睡著了一般。 火紅的嫁衣襯著肌膚如雪单鹿。 梳的紋絲不亂的頭發(fā)上掀宋,一...
    開封第一講書人閱讀 52,785評論 1 314
  • 那天,我揣著相機與錄音仲锄,去河邊找鬼劲妙。 笑死,一個胖子當著我的面吹牛儒喊,可吹牛的內(nèi)容都是我干的镣奋。 我是一名探鬼主播,決...
    沈念sama閱讀 41,220評論 3 423
  • 文/蒼蘭香墨 我猛地睜開眼怀愧,長吁一口氣:“原來是場噩夢啊……” “哼侨颈!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起芯义,我...
    開封第一講書人閱讀 40,167評論 0 277
  • 序言:老撾萬榮一對情侶失蹤哈垢,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后扛拨,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體耘分,經(jīng)...
    沈念sama閱讀 46,698評論 1 320
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,767評論 3 343
  • 正文 我和宋清朗相戀三年绑警,在試婚紗的時候發(fā)現(xiàn)自己被綠了求泰。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,912評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡计盒,死狀恐怖渴频,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情北启,我是刑警寧澤卜朗,帶...
    沈念sama閱讀 36,572評論 5 351
  • 正文 年R本政府宣布拔第,位于F島的核電站,受9級特大地震影響聊替,放射性物質(zhì)發(fā)生泄漏楼肪。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 42,254評論 3 336
  • 文/蒙蒙 一惹悄、第九天 我趴在偏房一處隱蔽的房頂上張望春叫。 院中可真熱鬧,春花似錦泣港、人聲如沸暂殖。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,746評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽呛每。三九已至,卻和暖如春坡氯,著一層夾襖步出監(jiān)牢的瞬間晨横,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,859評論 1 274
  • 我被黑心中介騙來泰國打工箫柳, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留手形,地道東北人。 一個月前我還...
    沈念sama閱讀 49,359評論 3 379
  • 正文 我出身青樓悯恍,卻偏偏與公主長得像库糠,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子涮毫,可洞房花燭夜當晚...
    茶點故事閱讀 45,922評論 2 361

推薦閱讀更多精彩內(nèi)容