亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

Python3爬蟲模擬新浪微博登錄(2019-8-3)最新

系統 2053 0

目錄

  • Python3爬蟲模擬新浪微博登錄
    • 過程分析
    • 遇到的坑
    • 關于第一步,賬號和密碼加密
    • 登錄請求post數據包裝
    • 關于登錄后如跳轉到主頁面
    • 其他模塊
    • 執行結果

Python3爬蟲模擬新浪微博登錄

初學Python3小白一枚,若有錯誤請不吝賜教

過程分析

Python3爬蟲模擬新浪微博登錄(2019-8-3)最新_第1張圖片

整個過程 從填寫數據到跳轉到主頁一共經歷了七個步驟:
1.在登陸前,輸入賬號結束,失去輸入框焦點,瀏覽器會發送兩個請求,分別請求了登陸前加密密碼所需的servertime、nonce、pubkey(圖中對應3)
2.第二個ajax請求的是關于驗證碼的(圖中對應4、5)
3.這個是點擊登錄按鈕后,將加密后的數據post到服務器(圖中對應6)
4.服務器會返回一系列數據,(對應圖中的8),它包含了重定向的地址
5.多次頁面加載后,會接收到來自服務器的json數據包(對應圖中的19)在這
個數據包中包含了每個微博用戶特定的uniqueid
6.這是一個攜帶有相關用戶信息的script腳本(對應圖中的22)
7.經過一系列的跳轉后,最終跳轉到個人主頁面

遇到的坑

遇到的最嚴重的坑,就是驗證碼的啦
驗證碼的請求分析,著實耗費了大半天 。這是驗證碼請求的服務器地址:
https://login.sina.com.cn/cgi/pin.php?r=18674039&s=0&p=yf-c92f2edb50c21d4bcbfdc3fccfdb94c4c23f
其中分析后發現:
固定服務器url:https://login.sina.com.cn/cgi/pin.php?
攜帶的參數:r = 18674039,p = yf-c92f2edb50c21d4bcbfdc3fccfdb94c4c23f,s = 0
其中s和p是固定值,r是一串不固定變化的數字,在分析的過程中,我試圖尋找關于r的規律,最后實在沒辦法,我打算在Fiddler中測試一下,看看不加參數r是否能獲得,結果是可喜可賀的,確實獲得了。
事實上,在保證cookie一致的情況下,去請求驗證碼,也就是說和你本次的登錄保持在一個cookie中,可以主動的抓取驗證碼。

            
              
                # 獲取驗證碼
              
              
                def
              
              
                get_verificationcode
              
              
                (
              
              
                )
              
              
                :
              
              
                print
              
              
                (
              
              
                "開始請求獲取驗證碼..."
              
              
                )
              
              
    url 
              
                =
              
              
                "https://login.sina.com.cn/cgi/pin.php?s=0&p=yf-9f5e31626347e127bc21874aa9d6f4d745ca"
              
              
    request
              
                .
              
              urlretrieve
              
                (
              
              url
              
                =
              
              url
              
                ,
              
               filename
              
                =
              
              
                "./img/code.jpg"
              
              
                )
              
              
                print
              
              
                (
              
              
                "驗證碼獲取成功!"
              
              
                )
              
              
                return
              
              
                input
              
              
                (
              
              
                "請輸入驗證碼:"
              
              
                )
              
            
          

在應對驗證碼問題上,我這里采用的是半人工半自動的,將每次獲得的驗證碼存到當前目錄下的img文件中,人工查看和輸入驗證碼。

關于第一步,賬號和密碼加密

經分析在第二步發送登錄的post請求之前,瀏覽器會實現發一個請求,請求的響應信息如下:
Python3爬蟲模擬新浪微博登錄(2019-8-3)最新_第2張圖片
里邊攜帶的servertime、pubkey、nonce、rsakv等關鍵信息在后邊加密密碼和包裝post請求數據非常關鍵。關于如何得到這個分析以及整個爬蟲的結構也,參考了這篇博文:https://www.cnblogs.com/houkai/p/3488468.html.
以下是加密模塊encrypt.py的代碼

            
              
                import
              
               base64

              
                import
              
               binascii

              
                import
              
               rsa


              
                # 對用戶名加密
              
              
                def
              
              
                encryUsername
              
              
                (
              
              username
              
                )
              
              
                :
              
              
                print
              
              
                (
              
              
                "開始加密用戶名..."
              
              
                )
              
              
    text 
              
                =
              
              
                (
              
              base64
              
                .
              
              b64encode
              
                (
              
              username
              
                .
              
              encode
              
                (
              
              encoding
              
                =
              
              
                "utf-8"
              
              
                )
              
              
                )
              
              
                )
              
              
    text 
              
                =
              
               text
              
                .
              
              decode
              
                (
              
              
                )
              
              
                return
              
              
                str
              
              
                (
              
              text
              
                )
              
              
                .
              
              replace
              
                (
              
              
                "="
              
              
                ,
              
              
                ""
              
              
                )
              
              
                # 對密碼加密
              
              
                def
              
              
                encryPassword
              
              
                (
              
              password
              
                ,
              
              servertime
              
                ,
              
              nonce
              
                ,
              
              pubkey
              
                )
              
              
                :
              
              
                print
              
              
                (
              
              
                "開始加密密碼..."
              
              
                )
              
              
    rsaPublickey 
              
                =
              
              
                int
              
              
                (
              
              pubkey
              
                ,
              
              
                16
              
              
                )
              
              
    key 
              
                =
              
               rsa
              
                .
              
              PublicKey
              
                (
              
              rsaPublickey
              
                ,
              
              
                65537
              
              
                )
              
              
                # 創建公鑰
              
              
    message 
              
                =
              
              
                str
              
              
                (
              
              servertime
              
                )
              
              
                +
              
              
                '\t'
              
              
                +
              
              
                str
              
              
                (
              
              nonce
              
                )
              
              
                +
              
              
                '\n'
              
              
                +
              
              
                str
              
              
                (
              
              password
              
                )
              
              
                # 拼接明文js加密文件中得到
              
              
    message 
              
                =
              
              
                bytes
              
              
                (
              
              message
              
                ,
              
               encoding
              
                =
              
              
                "utf-8"
              
              
                )
              
              
    passwd 
              
                =
              
               rsa
              
                .
              
              encrypt
              
                (
              
              message
              
                ,
              
               key
              
                )
              
              
                # 加密
              
              
    passwd 
              
                =
              
               binascii
              
                .
              
              b2a_hex
              
                (
              
              passwd
              
                )
              
              
                # 將加密信息轉換為16進制。
              
              
                return
              
               passwd

            
          

登錄請求post數據包裝

在Chrome的開發者模式下,可以抓取相關參數信息

            
              
                # 組織post數據
              
              
                def
              
              
                get_postData
              
              
                (
              
              su
              
                ,
              
              password
              
                ,
              
              servertime
              
                ,
              
              nonce
              
                ,
              
              pubkey
              
                ,
              
              rsakv
              
                )
              
              
                :
              
              
                print
              
              
                (
              
              
                "開始組織post數據..."
              
              
                )
              
              
                # 密碼加密
              
              
    sp 
              
                =
              
               encrypt
              
                .
              
              encryPassword
              
                (
              
              password
              
                ,
              
               servertime
              
                ,
              
               nonce
              
                ,
              
               pubkey
              
                )
              
              
                # 驗證碼請求
              
              
    door 
              
                =
              
               get_verificationcode
              
                (
              
              
                )
              
              
                # 構造post請求參數
              
              
    data 
              
                =
              
              
                {
              
              
                "door"
              
              
                :
              
               door
              
                ,
              
              
                "entry"
              
              
                :
              
              
                "weibo"
              
              
                ,
              
              
                "gateway"
              
              
                :
              
              
                1
              
              
                ,
              
              
                "from"
              
              
                :
              
              
                ""
              
              
                ,
              
              
                "savestate"
              
              
                :
              
              
                7
              
              
                ,
              
              
                "su"
              
              
                :
              
               su
              
                ,
              
              
                "sp"
              
              
                :
              
               sp
              
                ,
              
              
                "servertime"
              
              
                :
              
               servertime
              
                ,
              
              
                "service"
              
              
                :
              
              
                "miniblog"
              
              
                ,
              
              
                "nonce"
              
              
                :
              
               nonce
              
                ,
              
              
                "rsakv"
              
              
                :
              
               rsakv
              
                ,
              
              
                "encoding"
              
              
                :
              
              
                "UTF-8"
              
              
                ,
              
              
                "domain"
              
              
                :
              
              
                "sina.com.cn"
              
              
                ,
              
              
                "returntype"
              
              
                :
              
              
                "META"
              
              
                ,
              
              
                "vsnf"
              
              
                :
              
              
                1
              
              
                ,
              
              
                "useticket"
              
              
                :
              
              
                1
              
              
                ,
              
              
                "pwencode"
              
              
                :
              
              
                "rsa2"
              
              
                ,
              
              
                "prelt"
              
              
                :
              
              
                372
              
              
                ,
              
              
                "qrcode_flag"
              
              
                :
              
              
                "false"
              
              
                ,
              
              
                "url"
              
              
                :
              
              
                "https://weibo.com/ajaxlogin.php?framelogin=1&callback=parent.sinaSSOController.feedBackUrlCallBack"
              
              
                }
              
              
    data 
              
                =
              
               parse
              
                .
              
              urlencode
              
                (
              
              data
              
                )
              
              
                .
              
              encode
              
                (
              
              
                "utf-8"
              
              
                )
              
              
                return
              
               data

            
          

關于登錄后如跳轉到主頁面

這個過程參考了:https://www.cnblogs.com/woaixuexi9999/p/9404745.html
在模塊login.py中定義了一個類Login,其中的登錄方法代碼:

            
              
                def
              
              
                login
              
              
                (
              
              self
              
                )
              
              
                :
              
              
                # 第一步 獲得時間戳、公鑰、nonce等數據
              
              
        req 
              
                =
              
               request
              
                .
              
              Request
              
                (
              
              url
              
                =
              
              self
              
                .
              
              __preloginUrl
              
                ,
              
              headers
              
                =
              
              self
              
                .
              
              headers1
              
                ,
              
              method
              
                =
              
              
                "get"
              
              
                )
              
              
        response 
              
                =
              
               request
              
                .
              
              urlopen
              
                (
              
              req
              
                )
              
              
        text 
              
                =
              
               response
              
                .
              
              read
              
                (
              
              
                )
              
              
        servertime
              
                ,
              
               nonce
              
                ,
              
               pubkey
              
                ,
              
               rsakv 
              
                =
              
               dealdata
              
                .
              
              get_prelogin
              
                (
              
              text
              
                =
              
              text
              
                )
              
              
                # 第二步 向服務器發送post請求 登錄信息
              
              
        postdata 
              
                =
              
               dealdata
              
                .
              
              get_postData
              
                (
              
              self
              
                .
              
              __su
              
                ,
              
              self
              
                .
              
              __password
              
                ,
              
              servertime
              
                ,
              
              nonce
              
                ,
              
              pubkey
              
                ,
              
              rsakv
              
                )
              
              
        req 
              
                =
              
               request
              
                .
              
              Request
              
                (
              
              url
              
                =
              
              self
              
                .
              
              __loginUrl
              
                ,
              
               headers
              
                =
              
              self
              
                .
              
              __postheaders
              
                ,
              
               data
              
                =
              
              postdata
              
                ,
              
              method
              
                =
              
              
                "post"
              
              
                )
              
              
        response 
              
                =
              
               request
              
                .
              
              urlopen
              
                (
              
              req
              
                )
              
              
        text 
              
                =
              
               response
              
                .
              
              read
              
                (
              
              
                )
              
              
                # 第三步 解析登錄響應數據 獲取中間鏈接
              
              
        replaceUrl 
              
                =
              
               dealdata
              
                .
              
              get_replaceUrl
              
                (
              
              text
              
                =
              
              text
              
                )
              
              
                # 分析登錄結果
              
              
        result
              
                ,
              
              retcode
              
                ,
              
              reason 
              
                =
              
               dealdata
              
                .
              
              get_reason
              
                (
              
              replaceUrl
              
                )
              
              
                if
              
               result
              
                ==
              
              
                False
              
              
                :
              
              
                print
              
              
                (
              
              
                "登錄失敗!"
              
              
                )
              
              
                print
              
              
                (
              
              
                "原因"
              
              
                ,
              
              reason
              
                )
              
              
                return
              
              
                else
              
              
                :
              
              
                print
              
              
                (
              
              
                "登錄成功!"
              
              
                )
              
              
                print
              
              
                (
              
              
                "正在向個人主頁跳轉..."
              
              
                )
              
              
                # 第四步 加載中間鏈接 提取ticket
              
              
        response 
              
                =
              
               request
              
                .
              
              urlopen
              
                (
              
              replaceUrl
              
                )
              
              
        text 
              
                =
              
               response
              
                .
              
              read
              
                (
              
              
                )
              
              
        ticket 
              
                =
              
               dealdata
              
                .
              
              get_ticket
              
                (
              
              text
              
                =
              
              text
              
                )
              
              
                # 第五步 利用ticket組合關鍵部分構造網址 獲得攜帶uniqueid的json數據
              
              
        uniqueidUrl 
              
                =
              
               ticket 
              
                +
              
              
                "&callback=sinaSSOController.doCrossDomainCallBack&scriptId=ssoscript0&client=ssologin.js(v1.4.19)&_=1564805281285"
              
              
        response 
              
                =
              
               request
              
                .
              
              urlopen
              
                (
              
              uniqueidUrl
              
                )
              
              
        text 
              
                =
              
               response
              
                .
              
              read
              
                (
              
              
                )
              
              
        uniqueid 
              
                =
              
               dealdata
              
                .
              
              get_uniqueid
              
                (
              
              text
              
                )
              
              
                # 第六步 跳轉到主頁
              
              
                print
              
              
                (
              
              
                "進入個人主頁..."
              
              
                )
              
              
        homeUrl 
              
                =
              
              
                "https://weibo.com/u/"
              
              
                +
              
               uniqueid 
              
                +
              
              
                "/home"
              
              
        request
              
                .
              
              urlretrieve
              
                (
              
              homeUrl
              
                ,
              
              
                "./html/home.html"
              
              
                )
              
            
          

其他模塊

處理數據的dealdata.py模塊

Python3爬蟲模擬新浪微博登錄(2019-8-3)最新_第3張圖片
工程文件列表
Python3爬蟲模擬新浪微博登錄(2019-8-3)最新_第4張圖片
code.jpg是驗證碼
home.html是加載的主頁

執行結果

Python3爬蟲模擬新浪微博登錄(2019-8-3)最新_第5張圖片

初學Python,深感Python的強大。人生苦短,我用Python。
此程序僅供嘗試使用,不可商用。
轉載請注明出處:https://blog.csdn.net/Blz624613442/article/details/98368815


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 好吊妞欧美视频免费 | 中文字幕三级久久久久久 | 天天爽天天狼久久久综合 | 久久国产精品视频一区 | 久久a视频| 亚洲欧美在线看 | 久久综合久久精品 | 草久影院 | 欧洲色网站| 99视频全部看免费观 | 亚洲在线h | 日本久久久久中文字幕 | 久久天天 | 久久99热这里只有精品 | 亚欧精品一区二区三区四区 | 中文字幕在线最新在线不卡 | 九草伊人 | 亚洲天天做日日做天天欢毛片 | 欧美精品18xxxhd4k| 91国在线 | 一本久草 | 午夜在线成人 | 中文字幕一二区 | 四虎成人精品在永久在线观看 | 久久亚洲欧美成人精品 | 日韩在线视频不卡 | 精品国产一区二区三区在线观看 | 奇米色吧 | 欧美性猛交ⅹxxx乱大交按摩 | www.av天天| 欧美日韩小视频 | 亚洲国产精品日韩在线 | 婷婷在线成人免费观看搜索 | 9191精品国产费久久 | 日本不卡中文字幕一区二区 | 国产成人精品在线观看 | 亚洲精品中文字幕第一区 | 老司机观看精品一区二区 | 欧美在线观看第一页 | 中文字幕亚洲视频 | 久久久精品免费视频 |