關於搶火車票的那些事兒(二)
阿新 • • 發佈:2018-11-08
關於搶火車票的那些事兒(二)
在 上一節 裡面我們已經準備好了Cookie,這一節該準備正式登陸12306了~
有一點要注意
我用的是
抓登陸過程的時候我們會發現瀏覽器會先給 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固定,但是每訪問一次獲取到的驗證碼圖片其實是不一樣的,這也應該是服務端可以不跟客戶端JS隨機演算法產生的值一一對應的原因吧~
如果我們post的驗證碼點選座標是對的話就會收到這樣的回覆內容 {"result_message":"驗證碼校驗成功","result_code":"4"}
驗證碼這一部分可以通過打碼兔來實現自動識別,但是需要自己註冊付費,可以細節可以參考damatu.py
接下來我們就可以傳送使用者名稱密碼來登陸了~
就是給 https://kyfw.12306.cn/passport/web/login post : username=*********.com&password=********&appid=otn 這樣的資料就行了 回覆的同樣是Json格式的資料 {'result_message': '登入成功', 'result_code': 0, 'uamtk': 'g-lT6rQ5XVZsZUTOKyohI46jpJR38fma2_IBxdAfyX8-bS6ldq4140'}
歐耶~~
在 上一節 裡面我們已經準備好了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生成的網址,
但是實踐證明瀏覽器的隨機並沒有跟伺服器發生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'}
歐耶~~