谈谈抢火车票的技术、技巧,以及暗藏其中的套路

谈谈抢火车票的技术、技巧,以及暗藏其中的套路

我鄙视一切商业性质的抢票工具。这些公司取代了火车站门口兜售的个体,成为了新时代的垄断黄牛。

技术

一道面试题:让你实现一套自动抢票系统,你会怎么设计?

大体来说,有这样几个功能需要实现:

1. 模拟网络请求。12306没有提供过API,所以要能通过程序自动购票,只能去模拟(伪造)请求。请求的来源可以是12306网页版,也可以从12306的APP里抓包分析。

只是拿到请求地址,最多可以查询余票,并不能成功购票,必须以账号登录才能获得购票权限。如果一次登录就可以,那解决途径有很多,直接在手动登录后把cookie取出给程序使用都行。

仅仅这种程度,几乎所有会写一些爬虫的人都能解决。我们爬虫课程里的实例都比这个要复杂。

但12306在高峰时经常会退出登录状态,需要不定时地重新登录。这就遇到了自动购票最大的阻碍:

2. 验证码。12306的验证码相信大家都体会过,正常人类都能被拦住,简单的程序显然是无法搞定的。给三种解决思路:

a. 人工干预。程序遇到验证码后,由人去点击正确的验证码,保证程序顺利进行。这里可以用 selenium 实现,也可以通过程序将验证码单独取出供点击。

b. 打码平台。打码平台是一种神奇的存在,它会将你需要识别的验证码分配到一个个打码人员的客户端里,他们帮你选择正确的结果。当然这是要付费的,不过由于高度规模化,这个成本被降到很低。

打码平台(图片转自网络)

这是上一种方法的加强版,只是不用你自己盯着程序运行,而是由其他人帮你解决。

c. 图像识别。12306的图片验证码尽管奇葩,但也不是无法识别,甚至一些机器学习的通用识别服务都可以达到一定的识别率。知乎上就有不少人给出过识别的参考方法和效果:

如何评价 12306 的图片型验证码?www.zhihu.com图标

而一些抢票工具更是把验证码识别功能作为VIP功能来收费。

12306验证码识别(出处见上方知乎链接)

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哦 :-)

Crossin的编程教室 - 在线练习crossincode.com


════

其他文章及回答:

双11 | 押韵工具 | 新手引导 | 学编程的弯路 | 自学Python

编辑于 2018-02-07

文章被以下专栏收录

    本专栏旨在为编程初学者提供浅显易懂的入门科普。微信公众号:Crossin的编程教室(crossincode),内有面向零基础学习者的 Python 入门教程。代码问题可上 bbs.crossincode.com 发帖提问。