我鄙視一切商業性質的搶票工具。這些公司取代了火車站門口兜售的個體,成為了新時代的壟斷黃牛。
技術
一道面試題:讓你實現一套自動搶票系統,你會怎麼設計?
大體來說,有這樣幾個功能需要實現:
1. 模擬網路請求。12306沒有提供過API,所以要能通過程式自動購票,只能去模擬(偽造)請求。請求的來源可以是12306網頁版,也可以從12306的APP裡抓包分析。
只是拿到請求地址,最多可以查詢餘票,並不能成功購票,必須以賬號登入才能獲得購票許可權。如果一次登入就可以,那解決途徑有很多,直接在手動登入後把cookie取出給程式使用都行。
僅僅這種程度,幾乎所有會寫一些爬蟲的人都能解決。我們爬蟲課程裡的例項都比這個要複雜。
但12306在高峰時經常會退出登入狀態,需要不定時地重新登入。這就遇到了自動購票最大的阻礙:
2. 驗證碼。12306的驗證碼相信大家都體會過,正常人類都能被攔住,簡單的程式顯然是無法搞定的。給三種解決思路:
a. 人工干預。程式遇到驗證碼後,由人去點選正確的驗證碼,保證程式順利進行。這裡可以用 selenium 實現,也可以通過程式將驗證碼單獨取出供點選。
b. 打碼平臺。打碼平臺是一種神奇的存在,它會將你需要識別的驗證碼分配到一個個打碼人員的客戶端裡,他們幫你選擇正確的結果。當然這是要付費的,不過由於高度規模化,這個成本被降到很低。
這是上一種方法的加強版,只是不用你自己盯著程式執行,而是由其他人幫你解決。
c. 影像識別。12306的圖片驗證碼儘管奇葩,但也不是無法識別,甚至一些機器學習的通用識別服務都可以達到一定的識別率。知乎上就有不少人給出過識別的參考方法和效果:
而一些搶票工具更是把驗證碼識別功能作為VIP功能來收費。
3. 定時重新整理。解決了前兩個問題,購票的流程已經打通。只要在程式里加上定時功能就可以自動購票了。這裡可以選擇一直執行程式,定時傳送請求,也可以通過 Linux 的 cronjob、Windows 的計劃任務等實現定時執行。
不過到這一步為止,只能說你實現了一個自動“購”票的指令碼,離“搶”票還有很遠的距離。即使你把請求間隔調整得很低,在春運出票高峰也很難有效果。如果想要進一步提升效果,還得考慮:
4. 多賬號、分散式請求。在你自己的電腦上用自己的賬號不停刷票,一來是速度是有瓶頸的,再快大約也需要幾秒鐘才能完成一次購票嘗試,二來這很可能導致你的賬號、IP被封禁。所以,你必須有足夠多的賬號和機器,可以在極短時間內發起大量的購票請求,才能把購票成功率提高到一個有競爭力的水平。從技術角度來說,這不算困難,各種隨開隨用的雲服務彈性計算就是滿足你此類需求的。
以上幾點,基本就是一個搶票系統需要考慮的主要問題,接下來就是要在實踐中優化你的程式,提升效能和穩定性,考慮諸如時間間隔、伺服器的選擇,以及購票條件的設定、通知傳送等細節。
看到這裡也許有人要說了:
程式碼在哪裡下載?怎麼用?
整這麼複雜幹嘛,XXX軟體早就實現實現了。
對此我要說的是,以上僅僅是對一個技術問題的分析討論,我沒有也無意開發一款實用的搶票軟體。所以今天這裡不會有任何程式碼下載,也不會推薦任何軟體。
我鄙視一切商業性質的搶票工具。
我們談論的技術本身不存在善惡。但使用技術的人/公司卻有立場,作為大企業更應該承擔相應的社會責任。
當我在此文開頭設定那道“面試題”的時候,我想除了黃牛黨,真的會有公司這麼問嗎?一般正常公司也是問“如果你設計12306網站,如何防刷票?”吧。
可現如今,有多少體面的大公司,推出搶票工具或在自己的APP裡增加搶票功能,以此推廣或牟利。
在這裡,我個人建議不要使用這些工具。這並不是僅僅是為了立場而反對,而是這裡本身就有很多不安全因素。
套路
1. 很多工具打著免費刷票的旗號,但等你真的用了就發現,不付費幾乎是買不到票的。甚至有時候你沒發現,就已經付了費,買了VIP/加速包。
2. 你以為花了錢,就真的可以買到票嗎?並不是。即使按照他們明面上的說法,也只是給你分配更多的資源,提高你搶到的概率。但實際上怎樣,不得而知。反正搶不到最多退款唄。聽過“包生男孩”的偏方嗎:收你一萬,包生男孩,不靈退款。這些軟體即使什麼額外功能都不提供,僅僅是替你轉發購票請求,也可以賺到錢。
已經有網友驗證過,某些工具裡顯示的“已搶票XXXX次”,其實只是前端頁面寫的程式碼,並不是後臺的真實資料,斷了網也會自動增加。當然我們不能以此推斷說他一定沒有去刷,但客觀事實就是,他刷沒刷,刷的頻率如何,你並不知道。
就算真的沒有忽悠你,確實付了錢增加為你搶票的資源,但你可以想象一下:原本大家都是各自去搶,拼網速手速和運氣。後來有人付了錢,通過更好的渠道搶到了票。於是大家都開始付錢。付費渠道雖然更快,但資源也不是無限的,如果使用者增加到一定程度,必然要有個優先順序。如果你是刷票公司,你會讓誰先買?想象一下銀行裡,大家都成了VIP客戶,VIP視窗和普通視窗,哪個辦業務更快?你覺得刷票公司是會單純增加VIP資源,還是會關掉絕大多數普通視窗,然後再開闢新的SVIP視窗、SSVIP……。
3. 使用搶票軟體,你必須提供賬號、密碼、身份證資訊用於登入和購票,有些還會要求你支付預付款。對於這些置社會公平於不顧的公司,你卻很信任他們的隱私保護?想想我剛剛技術分析中提到的,提高搶票成功率需要大量的賬號,你覺得他們的賬號是從哪裡來的呢?
4. 一些更沒節操的黑產從業者也在這場搶票混戰中虎視眈眈,一不小心下載了帶木馬的搶票軟體,或者是被人用軟體合成的火車票騙了錢,這也都不是什麼新鮮事。
在現有鐵路運力無法充分應對春運客流的客觀條件限制下,為了能保證絕大多數人都有相對公平的機會,火車票價並不會像飛機票一樣隨市場需求水漲船高。可這些公司倒好,把這個空間作為自己大撈一票的機會,很有商業頭腦是吧。說到底,你們無非是取代上個時代的黃牛罷了。而且比起各地零散的黃牛,掌握著技術、渠道和大量使用者資料的大公司更強勢。長此以往地惡性迴圈,或許再過兩年的春節,不通過這些APP加價購票,就沒法正常買到車票了。
好在12306也並沒有像大家以為的那麼爛,這幾年的穩定性已經提升不少,今年據說增加了應對刷票的“慢速排隊機制”:購票的時候,如果有使用者疑似使用機器或外掛搶票,將會被列入慢速排隊佇列,讓符合規定的使用者在正常速度中排隊。希望真的能有效果。
技巧
其實大家都很無奈,搶不到票回不了家,不然誰願意去給刷票軟體奉上金錢和隱私。這也是沒辦法的辦法。
一些前人總結的購票技巧,希望能增加買到票的概率:
1. 算好預售期,從出票就開始搶。
這個是最基本的了。不過今年的時間點已經過去。如果你沒趕上,或者搶了但沒搶到,也別放棄,還有機會。
2. 把握撿漏的時間點。火車票一般都不會在開票的時候全部放出,再加上不斷有人退票,所以即使現在顯示無票了,也還是可能會有新票放出。幾個重要的時間點:
- 開票後的45分鐘,沒支付的車票超時而釋放(現在退票釋放時間有延遲,只能說隨緣了)
- 開車前15天,此時退票免手續費,有不少人退票
- 開車前的48小時直到開車前,這個時間點會放出一些之前鎖定的保留票,以及有的人最後行程取消的退票
- 另外就是晚上10點之後,早上7點,以及整點、半點,相對出票的概率會大一些
3. 曲線乘車。比如嘗試買到目的地的下一站/上一站(需補票),或者分段成兩個不同車次購買。
4. 電話購票,這個渠道常被人遺忘。當大家都在網際網路搶票的時候,也可以嘗試下,或許有驚喜。購票電話:95105105。而且一個小技巧是,這個電話是區分鐵路局的,可以加撥區號,去特定的鐵路局進行購票。
然而,這些也只能多增加一些買到票的可能性而已。黃牛、刷票軟體的存在,本質上是特定時間內的供求不平衡帶來的矛盾。如果這一點不能解決,即使防範了所有黃牛和刷票,也沒法讓所有人都買到票。這場道高一尺魔高一丈的比拼還會不斷持續下去。
但願情況在不久之後可以逐步改善。此刻我也只能祝大家都能順利買到票,開開心心回家過個年。
PS:如果覺得路程太長,可以看看我們的教程,在微信裡也可以直接寫Python哦 ?
════
其他文章及回答: