1. 程式人生 > >關於搶火車票的那些事兒(二)

關於搶火車票的那些事兒(二)

關於搶火車票的那些事兒(二)
上一節 裡面我們已經準備好了Cookie,這一節該準備正式登陸12306了~

有一點要注意
User-Agent
這個內容的設定需要跟之前獲取Cookie的瀏覽器控制元件所使用的一致,不然容易被伺服器發現~
我用的是 
'User-Agent' : 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.2; WOW64; Trident/7.0; .NET4.0C; .NET4.0E)',
來來來,還是開啟Fiddler,然後開啟瀏覽器登陸,抓包~



抓登陸過程的時候我們會發現瀏覽器會先給 https://kyfw.12306.cn/passport/captcha/captcha-check 這個看名字就知道是先驗證驗證碼內容的 Post資料資料內容是 answer=30%2C48%2C256%2C130&login_site=E&rand=sjrand
30%2C48%2C256%2C130 被轉碼了,UTF8 轉中文後 內容是 30,48,256,130
其實這個就是你點選驗證碼的時候點選的座標,伺服器會校驗這些個座標究竟落入了哪個具體的圖片,6不6?
那我們如何獲取驗證碼呢?
我們檢視瀏覽器會發現是個JS生成的網址,
具有隨機性 :https://kyfw.12306.cn/passport/captcha/captcha-image?login_site=E&module=login&rand=sjrand& 0.7533216669081391
但是實踐證明瀏覽器的隨機並沒有跟伺服器發生11對應的關係,所以只要寫死這個URL即可~
#驗證碼URL
verificationCodeUrl = 'https://kyfw.12306.cn/passport/captcha/captcha-image?login_site=E&module=login&rand=sjrand&0.46630622142659206'

    def captchaCheck(self):

        captchaErrorCount = 0
        print('正在識別驗證碼...')
        while True:
            if captchaErrorCount > 5:
                print('驗證碼失敗次數超過限制,登入失敗,退出程式')
                sys.exit()
            # 獲取驗證碼
            captchaRes = self.session.get(message.verificationCodeUrl)
            captcha = captchaRes.content
            with open(message.captchaDownloadName, 'wb') as f:
                f.write(captcha)
            #呼叫打碼兔去自動識別驗證碼
            #captchaStr = damatu.DamatuApi(message.damaUserName,message.damaPassword).decode(message.captchaDownloadName, 287)
            captchaStr = self.getCoordinate()
            print(captchaStr)
            captchaStr = captchaStr.replace('|', ',')
            captchaStr = requests.utils.requote_uri(captchaStr)
            data = {
                'answer': captchaStr,
                'login_site' :'E',
                'rand': 'sjrand'
            }
            #驗證驗證碼
            response = self.session.post(message.verificationCodeCheckUrl, data = data)
            print(response.text)
            result = response.json()
            if result['result_code'] == '4':
                print('識別驗證碼成功')
                break
            else:
                #print('識別驗證碼失敗')
                captchaErrorCount += 1

雖然url固定,但是每訪問一次獲取到的驗證碼圖片其實是不一樣的,這也應該是服務端可以不跟客戶端JS隨機演算法產生的值一一對應的原因吧~
如果我們post的驗證碼點選座標是對的話就會收到這樣的回覆內容 {"result_message":"驗證碼校驗成功","result_code":"4"}
驗證碼這一部分可以通過打碼兔來實現自動識別,但是需要自己註冊付費,可以細節可以參考damatu.py
#呼叫打碼兔去自動識別驗證碼
            captchaStr = damatu.DamatuApi(message.damaUserName,message.damaPassword).decode(message.captchaDownloadName, 287)


接下來我們就可以傳送使用者名稱密碼來登陸了~
就是給 https://kyfw.12306.cn/passport/web/login  post :  username=*********.com&password=********&appid=otn 這樣的資料就行了 回覆的同樣是Json格式的資料 {'result_message': '登入成功', 'result_code': 0, 'uamtk': 'g-lT6rQ5XVZsZUTOKyohI46jpJR38fma2_IBxdAfyX8-bS6ldq4140'}
歐耶~~