12306搶票的關鍵拼的就是整點出票的速度,快的幾秒鐘,慢的幾分鐘,本文提供終極搶票攻略,經過多線程掃描上萬個CDN,來大幅度提高出票速度。
準備一:須要瞭解CDN和切站的機制,請參考:
準備二:須要熟悉12306最重要的查詢接口和下單接口及傳入的參數規範
- /otn/leftTicket/queryX 和 /otn/leftTicket/submitOrderRequest
- 具體流程請參考:解析12306訂票流程
12306 CDN研究機制一
- 12306對kyfw.12306.cn用到了全站CDN緩存,至少上萬的CDN IP
- 對於90%的子頁面使用了CDN緩存
- 部分動態內容如我的中心,CDN將充當代理去12306實際服務器讀寫數據,請百度「cdn回源」
12306 CDN研究機制二
- 官方網站的自動查詢,每次都會命中同一臺CDN
- 拿到的都是CDN緩存數據,緩存時間2分鐘
- 因此運氣好的話,整點放票較快就能刷出票,通常狀況下要等幾十秒才能看到出票
- 參考下圖:
12306 CDN研究機制三
- 360搶票王每次查詢使用不一樣的CDN,經過內置dll插件實現,每次查詢映射不一樣的IP
- 參考下圖:
12306 頻繁刷票容易被踢的猜想
- 每次查詢,都會AJAX Log一下,請參考上面截圖
- 若是登陸狀態下,cookie的token就被記錄上傳了
- 因此登陸狀態下刷票容易被踢
- 因此查詢時動態修改hosts,切CDN,切站點,也容易被踢
12306 關於secretStr
- 查詢返回的每一個車次結果,都會有個secretStr
- 加密了此車次的全部相關信息,後續用於提交訂單用
- 此secretStr幾分鐘後會過時
- 因此關鍵就是放票整點後能快速刷出這個secretStr
- 參考下圖:
-
12306 查詢設計思路
- 啓用匿名查詢,查詢結果後返回的secretStr,交給登陸的賬號作訂單提交
- 目前市面上的搶票神器或收費軟件,都是採用了此機制:
- 啓用多個線程,主線程賬號登陸;
- 其餘線程併發匿名做業:輪詢請求不一樣的CDN查詢票源;
- 查到有票的secretStr,塞給主線程進行訂單提交;
- 集成收費打碼API,自動化點觸驗證碼,實現多開無人值守搶票
終極設計思路:
- 作Winform及界面工做量太大,這裏提供簡單的定製方案和一些設計思路
- 服務端:本身建個本地的IIS Web站點,去匿名輪詢請求不一樣的CDN查詢票源,返回secretStr
- 客戶端:瀏覽器登陸狀態,12306任何一個頁面,控制檯或插件植入js腳本,AJAX長輪詢去請求服務端,請求到secretStr作訂單提交
終極設計思路之服務端:
- 本身建個本地的IIS Web站點或在公網上建,或商業化作雲服務器分佈式的查詢
- 此網站提供接口如:http://127.0.0.1/GetSecretStr...
- 此接口的實現:啓動多線程去上萬個CDN去查詢指定車第二天期的票源
- 查到secretStr,立刻返回給客戶端
幫助:獲取kyfw.12306.cn的CDN ip,能夠去chinaz上去獲取,大概有上千個html
幫助:實在不夠,我能提供fishlee的一個IP列表,有上萬個git
終極設計思路之服務端的關鍵技術:
- http://www.cnblogs.com/dudu/archive/2012/07/18/webrequest_dns.html
- 這個技術,不用修改hosts,使用WebRequest能映射不一樣的IP
- 參考下圖:
-
終極設計思路之客戶端:
- 瀏覽器登陸狀態,控制檯或插件植入js腳本
- AJAX長輪詢去請求服務端,請求到secretStr作訂單提交
- 到最後的訂單提交頁,用插件自動勾選人,座位,本身手動輸入驗證碼提交
- 參考下圖:
-
測試結果:整點出票秒數,根據本身之前的N次經驗
- 3-10秒:此文思路,多線程在10秒內對1萬個CDN進行查詢
- 5-20秒:某收費軟件,採用了後臺多線程查詢CDN
- 10-30秒:fishlee的NET訂票助手,單線程,每隔1秒嘗試不一樣CDN
- 15-60秒:360搶票王,也是單線程,但CDN數量不夠
- 20-120秒:官方網站,CDN通常1分鐘內不會變,緩存嚴重
最新更新!
- 驗證碼問題 參考:http://bbs.fishlee.net/thread-10058-1-1.html
- 如今沒時間研究 工具 加入驗證碼輸入功能,
- 工具源代碼在:https://github.com/guozili/12306
- 基本思路能夠實現下: console工具 要輸入驗證碼時,發送驗證碼圖片二進制(socket)到 verifycodeWPFInput.exe(實現一個WPF程序彈出來)去點擊,而後返回驗證碼座標給console